stm32串口助手打印按键按下时间长短的stm32cubemx_HAL库配置过程
之前有人问了关于检测按键按下时间长短的问题,这里记录一种解决的办法
思路:通过开启按键GPIO的双边沿中断,和TIM1计数来记录按键按下的时间
现在我们来实现一下!!!
对了如果不想积分下载我博客园最下方有网盘链接
https://www.cnblogs.com/hjf-log/p/12542474.html
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中我们可以在下图中找到
22、把初始化TIM1定时器放在这里
23、进入定时器中断也一个callback函数,我们也复制到main.c中,就是下图这个
24、复制到main.c我们写一段代码测试一下,效果是一秒打印一次test2
25、我们现在就可以写我们要的功能了,先初始三个函数
26、修改GPIO中断callback里面的代码,下面也会贴出
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_2)
{
if(i == 0)
{
state = 1;
i=1;
printf("state:1\r\n");
}
else if(i == 1)
{
state = 0;
i = 0;
printf("按下按键的秒数:%0.2f\r\n",seconds/10);
seconds = 0;
printf("state:0\r\n");
}
}
}
27、修改TIM1的中断的callback代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM1)
{
if(state == 1)
{
seconds++;
}
}
}
28、将代码烧入IC中,然后按下按键可以看到串口助手效果
打印state:1表示按下,然后放开按键会打印按下的秒数和state:0
29、这里只精确到了个位的秒数,怎么修改按下的精度呢
我们接下来说一下如何把精度修改为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);
我们看看效果
30、好吧就记录到这里,还有在上面关于开启了两个tim1中断的问题我们来看看是哪个在起作用
哟注释掉了第一组TIM1_BRK串口助手还能正常打印数据说明这个没用上
我们回到MX关掉中断在重新生成一遍工程就行了
到此为止啦各位大佬们点个赞吧,需要工程的在博客园有网盘链接,同时上传CSDN在评论区放链接