实训1:定时器与串口综合训练
要求
- 开机后,LED1与LED2依次点亮,然后熄灭,进行灯光检测。LED1接到STM32的PF9, LED2接到STM32的PF10,高电平点亮。
- 系统通过串口 1向上位机发送一个字符串“STM32欢迎你! ”。
- LED1作为一个秒闪灯,系统向上位机发送完字符串后,开始亮0.5 秒,灭0.5秒…循环闪烁,并开始启动系统运行时间的记录,其 时分秒格式为“XX: XX: XX”。
- 上位机通过一个由3个字节组成的命令帧控制LED2灯的开关。该命 令帧的格式为“OxBF控制字OxFB"
OxBF为帧头,OxFB为帧尾,控制字的定义如下:
0xA1:打开LED2,返回信息 “XX:XX:XX LED2打开。"
0xA2:关闭LED2,返回信息 "XX:XX:XX LED2关闭。”
其他:返回信息“XX:XX:XX这个一个错误指令! ”
-
sprinft()
函数的用法:-
sprintf()
,指的是字符串格式化函数,把格式化的数据写入某个字符串中
int sprintf(char *string,char *format[,argument,...]);
-
引入头文件
include "stdio.h"
-
例:有一个表示温度的整形变量
tmp
,现在要将其格式化为字符串“温度是:XX摄氏度”,并将其通过串口1发送出去。1
2
3uint8_t Str_buff[64];
sprintf((char*)Str_buff,"温度是:%d摄氏度",tmp);
HAL_UART_Transmit(&huart1,Str_buff,sizeof(Str_buff),0xFFFF);
-
1. 使用STM32CubeMX进行初始配置
-
配置仿真器接口
-
配置时钟为外部时钟
-
配置时钟树
-
配置TIM2作为1秒计时并打开中断
注意:不同时钟与主频的关系不一定是1:1,TIM2的时钟频率是主频的二分之一
-
配置串口1为异步并打开中断
生成代码
2. 编写代码
-
宏定义,简化部分代码
1
2
3
4
5
6
7//宏定义
-
定义相关全局变量
1
2
3
4
5//全局变量定义
uint8_t str1[] = "STM32欢迎你!\r\n";
uint8_t hh =0,mm=0,ss=0,ss05=0; //存储时间
uint8_t str_buff[64]; //字符串缓冲数组
uint8_t Rx_dat[16]; //串口接收 -
功能1的实现
1
2
3
4
5
6
7
8
9
10
11
12
13//自定义函数
void Check_LED() //放到main()函数中的对应位置
{
LED1_ON();
HAL_Delay(500);
LED2_ON();
HAL_Delay(500);
LED1_OFF();
HAL_Delay(500);
LED2_OFF();
HAL_Delay(500);
} -
功能2的实现
-
打开定时器
1
HAL_TIM_Base_Start_IT(&htim2);
-
重写回调函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//计时以及灯光闪烁
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //时钟走完一次后执行
{
LED1_TOG();
ss05++;
if(ss05==1)
{
ss05=0;
ss++;
if(ss==60)
{
ss=0;
mm++;
if(mm==60)
{
mm=0;
hh++;
}
}
}
}
-
-
功能3的实现
-
引用头文件
1
-
非阻塞性接收
1
HAL_UART_Receive_IT(&huart1,Rx_dat,3); //放在while(1)外
-
重定义虚函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //接收完后执行
{
if(huart->Instance == USART1)
{
if(Rx_dat[0]==0xBF && Rx_dat[2] == 0xFB)
{
switch(Rx_dat[1])
{
case 0xa1:LED2_ON();sprintf((char*)str_buff,"%d:%d:%d LED2打开!\r\n",hh,mm,ss);break;
case 0xa2:LED2_OFF();sprintf((char*)str_buff,"%d:%d:%d LED2关闭!\r\n",hh,mm,ss);break;
default: sprintf((char*)str_buff,"%d:%d:%d 这是一个错误指令!\r\n",hh,mm,ss);break;
}
HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);
HAL_UART_Receive_IT(&huart1,Rx_dat,3); //如果这句话不在while(1)函数内则在回调函数内添加,不然执行一次后就不再接收
}
}
}
-
3. 实验结果
附件
这是跟随B站小蜜蜂老师的干货铺的【小蜜蜂笔记】基于STM32CubeMX的嵌入式开发基础教程所写的学习笔记。
此教程以应用为主,辅以简单的原理讲解,能够快速的上手STM32的开发。