本文主要是介绍P7 STM32的定时器与串口综合训练,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一,实训:定时器与串口综合训练
【1】开机后,LED1 与LED2依次点亮,然后熄灭,进行灯光检测。
LED1 接到STM32的PB3,LED2接到STM32的PB4,低电平点亮。
【2】系统通过串口1向上位机发送一个字符串"XMF07欢迎你!”。
【3】LED1 作为一个秒闪灯,系统向上位机发送完字符串后,开始亮0.5秒,灭0.5秒…循环闪烁,并开始启动系统运行时间的记录,其时分秒格式为“XX:XX:XX”。
【4】上位机通过一个由3个字节组成的命令帧控制LED2灯的开关。该命令帧的格式为“0xBF 控制字 0xFB”。
0xBF为帧头,0xFB为帧尾,控制字的定义如下:
0xA1:打开LED2,返回信息“XX:XX:XX LED2打开。”
0xA2:关闭LED2,返回信息“XX:XX:XX LED2关闭。”
其他:返回信息“XX:XX:XX 这个一个错误指令!”。
二,STM32CubeMX中的配置
1.新建工程,根据自己的开发板选择芯片
2.配置参数
①配置RCC和SYS
②配置定时器
i)将时钟频率设置为32MHZ
ii)根据题目,需要实现亮0.5秒,然后灭0.5秒…。在时钟频率为32MHz的前题下,可以设Prescaler为32000-1,Counter Period为500-1
使用定时器中断
③根据题目需求,配置串口
打开串口中断
④配置LED
将PB3和PB4设置为GPIO_Output
3.配置工程,并创建工程
生成代码
三,在MDK上编写代码,实现需求
1.需求一:开机后,LED1 与LED2依次点亮,然后熄灭,进行灯光检测。
在main.c的CODE BEGIN 2 处写如下代码可实现
/* USER CODE BEGIN 2 */HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET);HAL_Delay(500);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);HAL_Delay(500);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);/* USER CODE END 2 */
2.需求二:系统通过串口1向上位机发送一个字符串"XMFO7欢迎你!”。
接在需求一的代码最后处可以实现该任务
HAL_UART_Transmit(&huart1,"XMF07欢迎你!",sizeof("XMF07欢迎你!"),10000);
3.需求三:LED1作为一个秒闪灯,系统向上位机发送完字符串后,开始亮0.5秒,灭0.5秒…循环闪烁,并开始启动系统运行时间的记录,其时分秒格式为“XX:XX:XX”。
①重写定时器相关的虚函数
②在需求二的最末尾处接上定时器的启动代码
HAL_TIM_Base_Start_IT(&htim2);
③在CODE BEGIN 0处写需求三的相关代码
/* USER CODE BEGIN 0 */
unsigned char hour = 0;
unsigned char minute = 0;
unsigned char second = 0;
unsigned char halfSecond = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_3);
halfSecond++;
}
if(halfSecond == 2)
{
halfSecond = 0;
second++;
}
if(second == 60)
{
second = 0;
minute++;
}
if(minute == 60)
{
minute = 0;
hour++;
}
}/* USER CODE END 0 */
4.需求四:上位机通过一个由3个字节组成的命令帧控制LED2灯的开关。该命令帧的格式为“0xBF 控制字 0xFB”。
0xBF为帧头,0xFB为帧尾,控制字的定义如下:
0xA1:打开LED2,返回信息“XX:XX:XX LED2打开。”
0xA2:关闭LED2,返回信息“XX:XX:XX LED2关闭。”
其他:返回信息“XX:XX:XX 这个一个错误指令!”。
①在HAL_TIM_Base_Start_IT(&htim2);代码后接上串口接收的相关代码
HAL_UART_Receive_IT(&huart1,&Rxd_Date,3);
②在CODE BEGIN 0需求三的相关代码后面写如下代码
unsigned char Rxd_Date[3];
unsigned char Txd_Data1[]="00: 00: 00 LED2打开";
unsigned char Txd_Data2[]="00: 00: 00 LED2关闭";
unsigned char Txd_Data3[]="00: 00: 00 这是一个错误指令!";
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
Txd_Data1[0] = Txd_Data2[0] = Txd_Data3[0] = hour / 10 +0x30;
Txd_Data1[1] = Txd_Data2[1] = Txd_Data3[1] = hour % 10 +0x30;
Txd_Data1[4] = Txd_Data2[4] = Txd_Data3[4] = minute / 10 +0x30;
Txd_Data1[5] = Txd_Data2[5] = Txd_Data3[5] = minute % 10 +0x30;
Txd_Data1[8] = Txd_Data2[8] = Txd_Data3[8] = second / 10 +0x30;
Txd_Data1[9] = Txd_Data2[9] = Txd_Data3[9] = second % 10 +0x30;
if(huart->Instance == USART1)
{
if(Rxd_Date[0] == 0xBF && Rxd_Date[2] == 0xFB)
{
if(Rxd_Date[1] == 0xA1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_UART_Transmit(&huart1,Txd_Data1,sizeof(Txd_Data1),10000);
}
else if(Rxd_Date[1] == 0xA2)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);
HAL_UART_Transmit(&huart1,Txd_Data2,sizeof(Txd_Data2),10000);
}
else
{
HAL_UART_Transmit(&huart1,Txd_Data3,sizeof(Txd_Data3),10000);
}
}else{HAL_UART_Transmit(&huart1,Txd_Data3,sizeof(Txd_Data3),10000);}
}
HAL_UART_Receive_IT(&huart1,Rxd_Date,3);
}
四,使用sprintf()函数
1.指的是字符串格式化函数,把格式化的数据写入某个字符串中。
int sprintf(char *string,char *format [,argument,.]);
引入头文件 #include “stdio.h”
例:有一个表示温度的整型变量tmp,现在要将其格式化为字符串“温度是:XX摄氏度”,并将其通过串口1发送出去。
uint8_t Str_buff[64];
sprintf((char*)Str_buff,"温度是:%d摄氏度",tmp);
2.使用sprintf()函数更改训练代码
1)在main.c文件中加上头文件"stdio.h"
2)更改main.c文件中USER CODE BEGIN 0处的代码
/* USER CODE BEGIN 0 */
unsigned char hour = 0;
unsigned char minute = 0;
unsigned char second = 0;
unsigned char halfSecond = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_3);
halfSecond++;
}
if(halfSecond == 2)
{
halfSecond = 0;
second++;
}
if(second == 60)
{
second = 0;
minute++;
}
if(minute == 60)
{
minute = 0;
hour++;
}
}unsigned char Rxd_Date[3];
unsigned char Str_buff[64];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
if(Rxd_Date[0] == 0xBF && Rxd_Date[2] == 0xFB)
{
if(Rxd_Date[1] == 0xA1)
{
sprintf((char*)Str_buff,"%d: %d: %d LED2打开", hour, minute, second);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_UART_Transmit(&huart1,Str_buff,sizeof(Str_buff),10000);
}
else if(Rxd_Date[1] == 0xA2)
{
sprintf((char*)Str_buff,"%d: %d: %d LED关闭", hour, minute, second);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);
HAL_UART_Transmit(&huart1,Str_buff,sizeof(Str_buff),10000);
}
else
{
sprintf((char*)Str_buff,"%d: %d: %d 这是一个错误指令", hour, minute, second);
HAL_UART_Transmit(&huart1,Str_buff,sizeof(Str_buff),10000);
}
}
else
{
sprintf((char*)Str_buff,"%d: %d: %d 这是一个错误指令", hour, minute, second);
HAL_UART_Transmit(&huart1,Str_buff,sizeof(Str_buff),10000);
}}
HAL_UART_Receive_IT(&huart1,Rxd_Date,3);
}/* USER CODE END 0 */
这篇关于P7 STM32的定时器与串口综合训练的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!