一、所用工具
1、芯片: STM32F103C8T6
2、STM32CubeMx软件
3、IDE: MDK-Keil软件
4、烧录软件:FlyMcu
5、串口接收软件:firetools野火多功能调试助手
6、STM32F1xx/STM32F4xxHAL库
7、led小灯泡及导线若干和面包板
二、STM32CubeMX新建工程、基础配置
1、打开外部时钟,点击“System Core”,选择RCC,在右侧弹出的菜单栏中选择“Crystal/Ceramic Resonator”
2、选择调试接口,点击“System Core”,选择RCC。,在右侧弹出的菜单栏中选择“Serial Wire”。
3、配置IO。配置A5,B9, PC14,并命名为D1,D2,D3。
4、配置定时器2。这里我们使用定时器2来实现定时的功能。如图所示,依次点击位置1,选中定时器2;位置2,配置定时器2的时钟源为内部时钟;位置3,分频系数为71,向上计数模式,计数周期为5000,使能自动重载模式。
分频系数那里虽然写的是71,但系统处理的时候会自动加上1,所以实际进行的是72分频。由于时钟我们一般会配置为72MHZ,所以72分频后得到1MHZ的时钟。1MHZ的时钟,计数5000次,得到时间5000/1000000=0.005秒。也就是每隔0.005秒定时器2会产生一次定时中断。
5、配置中断。如下图所示,开启定时器2的中断。
如下图所示,生成定时器2中断优先级配置代码。
6、时钟配置
7、生成工程文件,用keil软件打开文件
三、keil修改代码
1、启动定时器
生成工程后,打开,添加中断响应之后所需的一些代码。在main.c文件中添加如下内容,位置:
HAL_TIM_Base_Start_IT(&htim2);
该函数表示启动相应的定时器,“h”表示HAL库,“tim2”表示定时器2。所以这行代码的意思就是启动定时器2。
2、定时器的中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint32_t time_cnt1 =0;
static uint32_t time_cnt2 =0;
if(htim->Instance == TIM2)
{
if(++time_cnt1 >= 400)
{
time_cnt1 =0;
HAL_GPIO_TogglePin(D1_GPIO_Port,D1_Pin);
HAL_GPIO_TogglePin(D2_GPIO_Port,D2_Pin);
HAL_GPIO_TogglePin(D3_GPIO_Port,D3_Pin);
}
if(++time_cnt2>=1000)
{
time_cnt2=0;
char data[]="hello windows!\n";
HAL_UART_Transmit(&huart1, (uint8_t *)data, 15, 0xffff);
}
}
}
当产生定时中断的时候,会自动调用这个函数。在函数内部定义了一个静态变量:time_cnt1,time_cnt2。
当time_cnt1>=400时,执行控制LED灯泡亮灭。也就是说需要发生400次中断,才会让LED的状态翻转。
当time_cnt2>=1000时,执行控制串口输出“hello windows!”。也就是需要发送1000此中断,才会发送"hello windows!“。
一次定时中断的时间是0.005秒,所以400次中断的时间是0.005*100=2秒,1000此中断是5秒。所以LED灯泡亮灭的周期是2秒,亮2秒,熄灭2秒,每隔5秒输出一次"hello windows!”。
接下来编译成功,生成.hex文件,烧录,上电查看完成情况。
四、实验效果及总结
这次实验总的来说比较简单,使用定时器来控制同时串口输出"hello windows!",和控制LED灯泡亮。可以通过设置频率来控制中断发送的时间,设置在多少次中断时调用函数就可以以时间周期来控制LED和串口输出。
参考资料:
http://www.mcublog.cn/stm32/2021_01/stm32cubemx-dingshiqi-led/