Insert title here

stm32打印按键按下时间长短的stm32cubemx_HAL库配置过程

之前有人问了关于检测按键按下时间长短的问题,这里记录一种解决的办法

 

这个工程我也分享在百度网盘

 

链接:https://pan.baidu.com/s/18nLuknQdWnysi7i7zNeZnA 
提取码:hi3r

思路:通过开启按键GPIO的双边沿中断,和TIM1计数来记录按键按下的时间

现在我们来实现一下!!!

1、打开MX选择一款IC,这里我用的开发板是stm32f103vet6

 

2、在MX中配置SW模式下载

 

3、配置外部高速晶振,低速的就是32.768k了RTC用的,这里用不上就不开了

 

 

4、配置好上面必要的步骤后,来看看我们按钮原理图和接到了哪个IO口

 

 

 5、上图一眼就能看出是接到了PE2,而且不按下默认已经和GND连接了,这个也方便我们之后不用内部下拉,那么把PE2配置成中断吧

 

6、那么配置PE2要选择双边沿中断,如下图配置

 

7、其他的就不用配置成内部上拉或者下拉了

 

8、把GPIO的中断打开,顺便把中断降级,别和其他中断冲突了

 

 

 

9、配置一下usart1设置成异步

 

10、我们先别急配置TIM1先去配置一下时钟树,我们用的8M晶振倍频为72M,这里记住APB2的晶振是72M,我们TIM1用的是APB2

 

11、现在我们回去配置TIM1,打开TIM1的时钟

 

12、接下来配置TIM1的预分频值和重装载值

 

这里很重要需要解释一下

我们的晶振是72M也就是一秒记72 00 0000次,72 00 0000Hz

Prescaler预分频值设置7200-1是因为预分频值从0开始

我们把72M除以预分频值7200就是我们定时器速度,速度变为了一秒记10000次

Counter Period重装载值设置为10000,也就是定时器从0开始记了10000次以后就又回归从0开始计算到10000一直循环

我们定时器的速度为1秒记10000次,重装载值也刚好是10000,那么记一次重装载要的时间就是1秒,那么速度刚好是1Hz

比如我们设置重装载值为1000,定时器速度是10000Hz,记一次重装载值的速度只要0.1秒也是10Hz

定时器的10000除以重装载的1000也就是10,就是定时器配置成了10Hz

 

 

 13、我们配置好后顺便打开定时器的中断,因为不知道是哪个我们先把两个都打开,之后写完代码在来看看是哪个有效

 

14、也要给TIM1的中断降级避免冲突

 

15、设置好这些之后我们配置下工程的名称,路径和开发工具

 

16、把这个打钩代表生成单独的配置文件,不用全部塞在main.c比较好看

 

17、我们要先测试一下printf能不能正常打印程序,这里之前已经写过博客,只复制链接不重复介绍了https://www.cnblogs.com/hjf-log/p/12522796.html

 

18、我们到中断函数中可以看到我们配置的中断函数

 

19、我们程序进入中断都会执行对应的callback函数也就是回调函数中,我们进入中断函数就可以看到

 

 20、我们将callback函数复制到main.c的保护区测试一下,不是main里面

这个效果是按键按下到释放,一共打印2次,因为我们之前配置的是双边沿中断,按下低变高是上升沿,释放是高变低下降沿,打印2次没错,这里就不截图串口助手了

 

 

 21、因为我们要使用TIM1定时器,定时器有个初始化代码要放在main中我们可以在下图中找到

 

23、把初始化TIM1定时器放在这里

 

24、进入定时器中断也一个callback函数,我们也复制到main.c中,就是下图这个

 

 

25、复制到main.c我们写一段代码测试一下,效果是一秒打印一次test2

 

 26、我们现在就可以写我们要的功能了,先初始三个函数

 

27、修改GPIO中断callback里面的代码,下面也会贴出

 

 

 1 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 2 {
 3     if(GPIO_Pin == GPIO_PIN_2)
 4     {
 5         if(i == 0)
 6         {
 7             state = 1;
 8             i=1;
 9             printf("state:1\r\n");
10         }
11         else if(i == 1)
12         {
13             state = 0;
14             i = 0;
15             printf("按下按键的秒数:%0.2f\r\n",seconds/10);
16             seconds = 0;
17             printf("state:0\r\n");
18         }
19     }
20 }
HAL_GPIO_EXTI_Callback

 

 28、修改TIM1的中断的callback代码

 

 1 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
 2 {
 3     if(htim->Instance == TIM1)
 4     {
 5         if(state == 1)
 6         {
 7             seconds++;
 8         }
 9     }
10 }
HAL_TIM_PeriodElapsedCallback

 

 29、将代码烧入IC中,然后按下按键可以看到串口助手效果

打印state:1表示按下,然后放开按键会打印按下的秒数和state:0

 

30、这里只精确到了个位的秒数,怎么修改按下的精度呢

 

我们接下来说一下如何把精度修改为0.1秒

 

回到MX中,将重装载值修改为1000,就和我们上面说的一样现在定时器为10Hz

 

原本我们的定时器速度是1Hz,一秒记一次,我们的定时器中断的效果就是每记一次seconds数加1

 

现在把速度改为10Hz,记一次时间是0.1s,记一次seconds+1那么seconds记到的数单位就是0.1秒

 

因为原本的seconds定义成了int,之后要修改为float

 

记10次就seconds加到了10,也就是1秒,所以seconds除以10才是秒数嘛

 

printf("按下按键的秒数:%0.2f\r\n",seconds/10);

 

我们看看效果

 

31、好吧就记录到这里,还有在上面关于开启了两个tim1中断的问题我们来看看是哪个在起作用

 

 哟注释掉了第一组TIM1_BRK串口助手还能正常打印数据说明这个没用上

我们回到MX关掉中断在重新生成一遍工程就行了

 

 

 

 

 

 到此结束啦加油啊

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-03-21 21:41  这一切足够了  阅读(1638)  评论(0编辑  收藏  举报
复制代码