【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关键词的使用

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

猜你喜欢

转载自blog.csdn.net/little_grapes/article/details/121044808