【STM32+cubemx】0003 HAL库开发:定时器基础应用,中断和回调函数

本节我们来学习STM32最基础的定时器应用,并利用hal库生成的代码,添加用户自己的功能到回调函数中。

程序实现的功能是:以10ms的定时器中断为周期,循环检测一个按键的状态,如果按下,则点亮LED灯;没有按下则熄灭LED灯。

1)cubemx生成代码

首先还是在cubemx中生成代码,选择器件、设置SYS(调试接口)、设置RCC(外部晶振时钟源)这几个步骤和前一节一样。

然后设置用户IO口,我们需要一个引脚输出驱动LED灯,一个引脚输入作为按键。这里我们的硬件上LED仍然使用开发板上的PC13按键的一端连接到PA0另一端接地

所以GPIO如下设置,把PC13设置为输出,PA0设置为输入:

设置完成后引脚会变成绿色。

然后,将PA0设置为上拉,因为我们的按键另一端连到了地,那么不按按键的时候,硬件上需要给PA0引脚一个高电平才能被识别,正好STM32的引脚可以设置内部上拉电阻:

然后设置定时器:

这里我们选择定时器3,使用内部时钟(72M主频),由于我们希望每10ms产生一个中断,所以分频系数和计数周期如下图设置,最终的中断周期为:

(分频数+1)*(计数周期+1)/72M = 7200*100/72M = 0.01s

打开定时器中断的使能:

之后,和上一节后续的一样,在时钟选项卡设置主时钟为72M;在project Manager选项卡设置工程名和路径,生成工程代码。

2)keil中的编程和下载

在keil中打开生成的工程,可以看到软件生成的代码中,main函数中已经有硬件初始化的代码,比上一节基本的GPIO多了定时器的初始化。

我们先在main函数中添加如下语句,功能是打开定时器3中断。

然后,我们打开stm32f1xx_it.c这个文件,这个文件里的函数是各中断的服务程序,我们找到定时器3的中断服务程序,通过前面的设置,这个函数会在每10ms被调用一次:

再通过其中调用的HAL_TIM_IRQHandler函数,发现它内部是这么实现中断处理的:

由于我们只使用了最基本的定时器更新中断,所以在这个函数里,只会进入TIM Update event这个处理内部,清除中断标志后,还会调用HAL_TIM_PeriodElapsedCallback这个函数。

而HAL_TIM_PeriodElapsedCallback这个函数是这么实现的:

它有一个__weak关键词修饰,函数内部是空的,没做任何处理。

这种有__weak修饰的函数,是可以被用户重写的。HAL_TIM_PeriodElapsedCallback这类函数一般称为回调函数,是留给用户的接口函数,用于给用户重写实现,以加入自己的功能。

我们在tim.c文件里重写这个回调函数,在其中加入读取PA0引脚(按键)状态的语句,这样就实现了每10ms读取一次按键的状态,存在key_state这个变量中:

然后,在main.c文件中加入如下代码:

这段代码在主循环中检测按键key_state的状态,如果按下(key_state为0),则点亮LED,反之熄灭LED。

要注意定义key_state变量时,一定要加上volatile修饰,否则优化等级开得比较高的话,主循环中可能检测不到按键的变化。

然后就可以编译、下载到开发板运行了。下载成功后,按下按键,可以看到LED灯点亮,松开后LED熄灭。

好了本节就到这里了。这一节主要的知识点有:定时器的配置回调函数的使用volatile关键词的使用

欢迎关注我的公众号,文章同步更新,可留言获取相关资料和软件:

  • 36
    点赞
  • 184
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
在使用STM32F103HAL库中的定时器中断时,可以通过以下步骤来设置中断回调函数: 1. 首先,需要在CubeMX中配置定时器中断使能。 2. 在生成代码后,打开生成的工程,在`stm32f1xx_hal_conf.h`文件中找到相应的定时器中断宏定义,比如`TIMx_IRQn`和`TIMx_IRQHandler`,其中`x`表示定时器的编号。 3. 找到生成的工程中的`stm32f1xx_it.c`文件,这是用来处理中断的文件。 4. 在`stm32f1xx_it.c`文件中,找到对应定时器中断处理函数,这个函数的命名通常是`TIMx_IRQHandler`,其中`x`表示定时器的编号。 5. 在中断处理函数中,可以编写你自己的逻辑代码。 具体来说,你可以按照以下步骤进行设置: 1. 在主函数中初始化定时器,并启动定时器。 ```c /* 初始化定时器 */ HAL_TIM_Base_Start_IT(&htimx); // htimx定时器句柄 ``` 2. 在`stm32f1xx_it.c`文件中找到对应定时器中断处理函数。 ```c void TIMx_IRQHandler(void) { HAL_TIM_IRQHandler(&htimx); // htimx定时器句柄 } ``` 3. 在中断处理函数中添加你的逻辑代码。 ```c void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htimx) { // 在这里添加你的逻辑代码 } } ``` 在上面的代码片段中,`HAL_TIM_PeriodElapsedCallback`是HAL库提供的定时器中断回调函数,当定时器溢出时会自动调用该函数。你可以在这个函数中添加你的逻辑代码来处理定时器中断事件。 注意,上述代码中的`TIMx`需要替换成你使用的定时器的编号,比如`TIM2`、`TIM3`等。另外,还需要根据你的需求进行相应的修改。 希望以上信息对你有帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值