STM32F103使用定时器控制led周期闪烁及串口发送信息

一、所用工具

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”
Alt
2、选择调试接口,点击“System Core”,选择RCC。,在右侧弹出的菜单栏中选择“Serial Wire”。
Alt
3、配置IO。配置A5,B9, PC14,并命名为D1,D2,D3。
Alt
Alt
4、配置定时器2。这里我们使用定时器2来实现定时的功能。如图所示,依次点击位置1,选中定时器2;位置2,配置定时器2的时钟源为内部时钟;位置3,分频系数为71,向上计数模式,计数周期为5000,使能自动重载模式。
Alt
分频系数那里虽然写的是71,但系统处理的时候会自动加上1,所以实际进行的是72分频。由于时钟我们一般会配置为72MHZ,所以72分频后得到1MHZ的时钟。1MHZ的时钟,计数5000次,得到时间5000/1000000=0.005秒。也就是每隔0.005秒定时器2会产生一次定时中断。
5、配置中断。如下图所示,开启定时器2的中断。
Alt
如下图所示,生成定时器2中断优先级配置代码。
Alt
6、时钟配置
Alt
7、生成工程文件,用keil软件打开文件

三、keil修改代码

1、启动定时器

生成工程后,打开,添加中断响应之后所需的一些代码。在main.c文件中添加如下内容,位置:

HAL_TIM_Base_Start_IT(&htim2);

Alt
该函数表示启动相应的定时器,“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!”。
Alt
接下来编译成功,生成.hex文件,烧录,上电查看完成情况。

四、实验效果及总结

Alt
这次实验总的来说比较简单,使用定时器来控制同时串口输出"hello windows!",和控制LED灯泡亮。可以通过设置频率来控制中断发送的时间,设置在多少次中断时调用函数就可以以时间周期来控制LED和串口输出。

参考资料:
http://www.mcublog.cn/stm32/2021_01/stm32cubemx-dingshiqi-led/

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!针对您的问题,我可以给您一些思路和代码示例来帮助您实现所需的功能。 首先,您需要配置定时器2和串口1。以下是一个简单的示例代码,您可以根据自己的需要进行修改: ```c #include "stm32f10x.h" void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { //发送数据到串口1 USART_SendData(USART1, 'H'); USART_SendData(USART1, 'e'); USART_SendData(USART1, 'l'); USART_SendData(USART1, 'l'); USART_SendData(USART1, 'o'); USART_SendData(USART1, '\n'); TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } void TIM2_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 36000 - 1; //定时器周期为0.5秒 TIM_TimeBaseStructure.TIM_Prescaler = 7200 - 1; //定时器时钟为72MHz,分频7200,计数器时钟为10kHz TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_Cmd(TIM2, ENABLE); } void USART1_Configuration(void) { USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } int main(void) { TIM2_Configuration(); USART1_Configuration(); while(1); } ``` 在上述代码中,我们通过定时器2的中断实现了每0.5秒向串口1发送一次数据。您只需要在`TIM2_IRQHandler`函数中修改发送的数据即可。 需要注意的是,如果您的串口1接收端是PC,那么您需要在PC端打开串口调试助手或其他串口调试工具,并且设置相应的波特率、数据位、校验位和停止位等参数,才能接收到发送的数据。 希望以上内容能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值