STM32的温室大棚系统实现
一、实验目的
利用STM32F103C8T6来模拟蔬菜大棚的采集设备通过温湿度传感器DHT11和光敏电阻来获取大棚内的光照,温度,湿度信息来实时分析蔬菜的生长状况
二、实验内容
1.串行总线的使用方法
2.stm32串口1的复习
3.DHT11温湿度传感器介绍
4.ADC数模转换采集光照信息
三、实验原理及说明
1.串行总线的使用方法
DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输为40bit,高位先出。数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和。数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。用户MCU发送一次开始信号后, DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后, DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号, DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
2. stm32串口1复习
stm32串口1使用PA10作为RX端接收数据,使用PA9作为TX端发送数据。
3. DHT11温湿度传感器
DHT11是一个温湿度传感器,有三个需要连接的外设引脚,除了VSS和GND,传输数据的data引脚需要和stm32单片机的PB2引脚进行串行单向数据传输。详细信息如下图所示。

4. ADC采集光敏电阻信息

四、实验设备
一套STM32实验设备、头歌实践教学平台。
五、实验步骤
1.1 双击打开软件 stm32cubemx。
1.2 开始创建工程,本次实训采用的开发板MCU型号为STM32F103C8T6,所以直接根据MCU配置工程,打开软件后选择 access to mcu selector。
1.3 搜索芯片STM32F103C8T6,并选择芯片型号 STM32F103C8T6 ,并点击“start project”创建工程。
1.4 芯片选择完成后,进入配置界面,配置分为如下几类:
SystemCore 用于配置MCU核心功能,如时钟,中断,调试接口等;nalog 用于配置MCU的ADC功能;
Timers 用于配置MCU的定时器;Connectivity 用于配置MCU外设接口,如SPI,USART,CAN等;Computing 用于配置MCU的CRC校验
Middleware 用于配置MCU的中间件,如文件系统,实时操作系统等; 学院可以根据实际需要,选择相应的功能配置,过程如下: 展开“system core”标签,找到“SYS"选项,在右边选择如图所示配置调试接口为JTAG 5脚接口,如果是其他接口,按照需要选择,配置完成后,右边的MCU预览图相应管脚会显示为绿色。

1.5 切换到”RCC“标签,配置系统时钟,本实验用到的开发板主时钟使用8MHz晶振,备份域时钟使用32.768kHz时钟,分别接在MCU的相应引脚上,所以在配置的时候HSE(高速外部时钟)选择使用外部晶振(crystal),LSE(低速外部时钟)选择使用外部晶振(crystal),具体如图所示。

1.6 选择GPIO,在PB2上选择GPIO_Out输出,因为是单向传输,而它的数据传输方向根据需求而实时改变,这里暂时设置为输出模式。设置初始初始状态为高电平,传输速率为高速,引脚简称DHT11_DA.具体如图所示。

1.7 选择Analog->ADC2->IN5并且在PA5选择ADC2_IN5,其它配置都为默认配置。

1.8 切换到“Connectivity”标签,在实验过程中需要使用串口打印信息,所以需要配置串口功能,此处选择USART1,配置为异步通信,其他参数(奇偶校验,波特率等)使用默认即可,按照如图所示配置“USART1”
1.9 切换到"TIME"标签,选择RTC,然后在Activate Clock Source打勾,按照如下图配置

1.10 配置系统时钟为72M,将ADC预分频系数调成除以8,设置ADC工作频率为9M,点击电脑确认键并编译环境。

1.11 配置工程命名为TEST并生成代码,具体如图所示。
1.12 为项目建立一个inode节点,用来放置节点驱动代码
1.13 在inode文件里面新建一个adc文件夹,在inode->adc里面新建一个源文件命名为adc.c和一个头文件命名为adc.h并将下面代码移植分别移植到对应文件夹中

adc.c如下面所示:
/*
* adc.c
*
* Created on: Oct 21, 2021
* Author: Administrator
*/
#include "adc.h"
uint16_t ADC_IN_1(void) //ADC采集程序
{
HAL_ADC_Start(&hadc1);//开始ADC采集
HAL_ADC_PollForConversion(&hadc1,500);//等待采集结束
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))//读取ADC完成标志位
{
return HAL_ADC_GetValue(&hadc1);//读出ADC数值
}
return 0;
}
uint16_t ADC_IN_2(void) //ADC采集程序
{
HAL_ADC_Start(&hadc2);//开始ADC采集
HAL_ADC_PollForConversion(&hadc2,500);//等待采集结束
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc2), HAL_ADC_STATE_REG_EOC))//读取ADC完成标志位
{
return HAL_ADC_GetValue(&hadc2);//读出ADC数值
}
return 0;
}
adc.h如下面所示
/*
* adc.h
*
* Created on: Oct 21, 2021
* Author: Administrator
*/
#ifndef ADC_ADC_H_
#define ADC_ADC_H_
#include "stm32f1xx_hal.h" //HAL库文件声明
extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc2;
uint16_t ADC_IN_1(void);
uint16_t ADC_IN_2(void);
#endif /* ADC_ADC_H_ */
1.14 在inode文件里面新建一个dht11文件夹,在inode->dht11里面新建一个源文件命名为dht11.c和一个头文件命名为dht11.h并将下面代码移植分别移植到对应文件夹中
dht11.c如下面所示:
/*
* dht11.c
*
* Created on: Oct 21, 2021
* Author: Administrator
*/
#include "dht11.h"
#include "main.h"
void DHT11_IO_OUT (void){ //端口变为输出
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_DA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void DHT11_IO_IN (void){ //端口变为输入
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_DA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)
DHT11_IO_OUT();
HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_RESET);
HAL_Delay(20); //拉低至少18ms
HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_SET);
delay_us(30); //主机拉高20~40us
}
uint8_t Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)
uint8_t retry=0;
DHT11_IO_IN();//IO到输入状态
while (HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11会拉低40~80us
retry++;
delay_us(1);
}
if(retry>=100)return 1; else retry=0;
while (!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11拉低后会再次拉高40~80us
retry++;
delay_us(1);
}
if(retry>=100)return 1;
return 0;
}
uint8_t Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
uint8_t retry=0;
while(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变为低电平
retry++;
delay_us(1);
}
retry=0;
while(!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变高电平
retry++;
delay_us(1);
}
delay_us(40);//等待40us //用于判断高低电平,即数据1或0
if(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin))return 1; else return 0;
}
uint8_t Dht11_ReadByte(void){ //从DHT11读取一个字节 返回值:读到的数据
uint8_t i,dat;
dat=0;
for (i=0;i<8;i++){
dat<<=1;
dat|=Dht11_ReadBit();
}
return dat;
}
uint8_t DHT11_Init (void){ //DHT11初始化
DHT11_RST();//DHT11端口复位,发出起始信号
return Dht11_Check(); //等待DHT11回应
}
uint8_t DHT11_ReadData(uint8_t *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
uint8_t buf[5];
uint8_t i;
DHT11_RST();//DHT11端口复位,发出起始信号
if(Dht11_Check()==0){ //等待DHT11回应
for(i=0;i<5;i++){//读取5位数据
buf[i]=Dht11_ReadByte(); //读出数据
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){ //数据校验
*h=buf[0]; //将湿度值放入指针1
h++;
*h=buf[2]; //将温度值放入指针2
}
}else return 1;
return 0;
}
}
dht11.h如下面所示:
/*
* dht11.h
*
* Created on: Oct 21, 2021
* Author: Administrator
*/
#ifndef DHT11_DHT11_H_
#define DHT11_DHT11_H_
#include "stm32f1xx_hal.h"
#include "../delay/delay.h"
void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
uint8_t Dht11_Check(void);
uint8_t Dht11_ReadBit(void);
uint8_t Dht11_ReadByte(void);
uint8_t DHT11_Init (void);
uint8_t DHT11_ReadData(uint8_t *h);
#endif /* DHT11_DHT11_H_ */
1.15 在inode文件里面新建一个usart文件夹,在inode->usart里面新建一个源文件命名为usart.c和一个头文件命名为usart.h并将下面代码移植分别移植到对应文件夹中

usart.c如下面所示:
/*
* usart1.c
*
* Created on: Oct 20, 2021
* Author: Administrator
*/
#include "usart.h"
uint8_t USART1_RX_BUF[USART1_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
uint16_t USART1_RX_STA=0;//接收状态标记//bit15:接收完成标志,bit14:接收到0x0d,bit13~0:接收到的有效字节数目
uint8_t USART1_NewData;//当前串口中断接收的1个字节数据的缓存
uint8_t USART2_RX_BUF[USART2_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
uint16_t USART2_RX_STA=0;//接收状态标记//bit15:接收完成标志,bit14:接收到0x0d,bit13~0:接收到的有效字节数目
uint8_t USART2_NewData;//当前串口中断接收的1个字节数据的缓存
uint8_t RS485orBT;//当RS485orBT标志位为1时是RS485模式,为0时是蓝牙模式
uint8_t USART3_RX_BUF[USART3_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
uint16_t USART3_RX_STA=0;//接收状态标记//bit15:接收完成标志,bit14:接收到0x0d,bit13~0:接收到的有效字节数目
uint8_t USART3_NewData;//当前串口中断接收的1个字节数据的缓存
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口中断回调函数
{
if(huart ==&huart1)//判断中断来源(串口1:USB转串口)
{
printf("%c",USART1_NewData); //把收到的数据以 a符号变量 发送回电脑
if((USART1_RX_STA&0x8000)==0){//接收未完成
if(USART1_RX_STA&0x4000){//接收到了0x0d
if(USART1_NewData!=0x0a)USART1_RX_STA=0;//接收错误,重新开始
else USART1_RX_STA|=0x8000; //接收完成了
}else{ //还没收到0X0D
if(USART1_NewData==0x0d)USART1_RX_STA|=0x4000;
else{
USART1_RX_BUF[USART1_RX_STA&0X3FFF]=USART1_NewData; //将收到的数据放入数组
USART1_RX_STA++; //数据长度计数加1
if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1); //再开启接收中断
}
// if(huart ==&huart2)//判断中断来源(RS485/蓝牙模块)
// {
// if(RS485orBT){//当RS485orBT标志位为1时是RS485模式,为0时是蓝牙模式
// USART2_RX_BUF[0]=USART2_NewData;//将接收到的数据放入缓存数组(因只用到1个数据,所以只存放在数据[0]位置)
// USART2_RX_STA++;//数据接收标志位加1
// }else{
// printf("%c",USART2_NewData); //把收到的数据以 a符号变量 发送回电脑
// }
// HAL_UART_Receive_IT(&huart2,(uint8_t *)&USART2_NewData, 1); //再开启接收中断
// }
// if(huart ==&huart3)//判断中断来源(串口3:WIFI模块)
// {
// printf("%c",USART3_NewData); //把收到的数据以 a符号变量 发送回电脑
// HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_NewData,1); //再开启接收中断
// }
}
usart1.h如下面所示:
/*
* usart1.h
*
* Created on: Oct 20, 2021
* Author: Administrator
*/
#ifndef INC_USART_H_
#define INC_USART_H_
#include "stm32f1xx_hal.h" //HAL库文件声明
#include <string.h>//用于字符串处理的库
#include "../inc/retarget.h"//用于printf函数串口重映射
extern UART_HandleTypeDef huart1;//声明USART1的HAL库结构体
extern UART_HandleTypeDef huart2;//声明USART2的HAL库结构体
extern UART_HandleTypeDef huart3;//声明USART2的HAL库结构体
#define USART1_REC_LEN 200//定义USART1最大接收字节数
#define USART2_REC_LEN 200//定义USART1最大接收字节数
#define USART3_REC_LEN 200//定义USART1最大接收字节数
extern uint8_t USART1_RX_BUF[USART1_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern uint16_t USART1_RX_STA;//接收状态标记
extern uint8_t USART1_NewData;//当前串口中断接收的1个字节数据的缓存
extern uint8_t USART2_RX_BUF[USART2_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern uint16_t USART2_RX_STA;//接收状态标记
extern uint8_t USART2_NewData;//当前串口中断接收的1个字节数据的缓存
extern uint8_t RS485orBT;//当RS485orBT标志位为1时是RS485模式,为0时是蓝牙模式
extern uint8_t USART3_RX_BUF[USART3_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern uint16_t USART3_RX_STA;//接收状态标记
extern uint8_t USART3_NewData;//当前串口中断接收的1个字节数据的缓存
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);//串口中断回调函数声明
#endif /* INC_USART_H_ */
1.16 在inode文件里面新建一个delay文件夹,在inode->delay里面新建一个源文件命名为delay.c和一个头文件命名为delay.h并将下面代码移植分别移植到对应文件夹中

delay.c如下面所示:
/*
* delay.c
*
* Created on: Oct 21, 2021
* Author: Administrator
*/
#include "delay.h"
void delay_us(uint32_t us)
{
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 8000000 * us);
while (delay--);
}
delay.h如下面所示:
/*
* delay.h
*
* Created on: Oct 21, 2021
* Author: Administrator
*/
#ifndef DELAY_DELAY_H_
#define DELAY_DELAY_H_
#include "stm32f1xx_hal.h"
void delay_us(uint32_t us);
#endif /* DELAY_DELAY_H_ */
1.17 在Core文件里的src文件中添加一个retarget.c源文件如下图所示,在inc文件添加一个retarget.h头文件如下图所示

retarget.c如下面所示:
/*
* retarget.c
*
* Created on: 2021��10��20��
* Author: Administrator
*/
#include <_ansi.h>
#include <_syslist.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/times.h>
#include <limits.h>
#include <signal.h>
#include <../Inc/retarget.h>
#include <stdint.h>
#include <stdio.h>
#if !defined(OS_USE_SEMIHOSTING)
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
UART_HandleTypeDef *gHuart;
void RetargetInit(UART_HandleTypeDef *huart) {
gHuart = huart;
/* Disable I/O buffering for STDOUT stream, so that
* chars are sent out as soon as they are printed. */
setvbuf(stdout, NULL, _IONBF, 0);
}
int _isatty(int fd) {
if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
return 1;
errno = EBADF;
return 0;
}
int _write(int fd, char* ptr, int len) {
HAL_StatusTypeDef hstatus;
if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
hstatus = HAL_UART_Transmit(gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);
if (hstatus == HAL_OK)
return len;
else
return EIO;
}
errno = EBADF;
return -1;
}
int _close(int fd) {
if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
return 0;
errno = EBADF;
return -1;
}
int _lseek(int fd, int ptr, int dir) {
(void) fd;
(void) ptr;
(void) dir;
errno = EBADF;
return -1;
}
int _read(int fd, char* ptr, int len) {
HAL_StatusTypeDef hstatus;
if (fd == STDIN_FILENO) {
hstatus = HAL_UART_Receive(gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);
if (hstatus == HAL_OK)
return 1;
else
return EIO;
}
errno = EBADF;
return -1;
}
int _fstat(int fd, struct stat* st) {
if (fd >= STDIN_FILENO && fd <= STDERR_FILENO) {
st->st_mode = S_IFCHR;
return 0;
}
errno = EBADF;
return 0;
}
#endif //#if !defined(OS_USE_SEMIHOSTING)
retarget.h如下面所示:
/*
* retarget.h
*
* Created on: 2021��10��20��
* Author: Administrator
*/
#ifndef INC_RETARGET_H_
#define INC_RETARGET_H_
#include "stm32f1xx_hal.h"
#include "stdio.h"
#include <sys/stat.h>
void RetargetInit(UART_HandleTypeDef *huart);
int _isatty(int fd);
int _write(int fd, char* ptr, int len);
int _close(int fd);
int _lseek(int fd, int ptr, int dir);
int _read(int fd, char* ptr, int len);
int _fstat(int fd, struct stat* st);
#endif /* INC_RETARGET_H_ */
1.18在Core->src->main函数添加以下代码所示。
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "rtc.h"
#include "usart.h"
#include "gpio.h"
#include "../../inode/led/led.h"
#include "../Inc/retarget.h"
#include "../../inode/usart/usart.h"
#include "../../inode/dht11/dht11.h"
#include "../../inode/adc/adc.h"
#include "../../inode/wifi/wifi.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t DHT11_BUF[2]={0};
uint16_t a;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RTC_Init();
MX_ADC2_Init();
MX_USART1_UART_Init();
RetargetInit(&huart1);
HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1);
HAL_ADCEx_Calibration_Start(&hadc2);
HAL_Delay(500);
DHT11_Init();
HAL_Delay(1500);
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/*每隔一秒钟打印出温度、湿度、光照值,请补充获取温湿度值和光照值的代码,并通过串口1打印出来*/
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
2.1配置编译生成HEX文件



烧录hex文件:


六、实验结果:
hex 文件成功生成烧录