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關掉中斷在重新生成一遍工程就行了

 

 

 

 

 

 到此結束啦加油啊

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM