本文主要討論軟件去抖。實現方法是通過SysTick中斷每1ms對按鍵進行掃描,當檢測到連續的穩定無抖動電平信號(長度可設置)之后,才進行相應的邏輯操作。
軟件版本:
STM32CubeMX V4.25.0
System Workbench V2.4
硬件:OneNet 麒麟座V2.3
在STM32CubeMX中新建項目,選擇正確的MCU型號
然后設置RCC和SYS,然后根據板子實際情況設置時鐘(麒麟座外部晶振是12M,STM32F103x的最高主頻是72M)
然后設置GPIO_Output (連接到LED) 和GPIO_Input(連接到按鍵)。注意上一篇文章里面按鍵連接的引腳設置為外部中斷模式,這里只需要設置為GPIO_Input就可以了。
GPIO_Output的具體設置如下:
GPIO_Input設置如下
這里按鍵我用了SW1/2/3/4。
同樣修改
Project - setting ,ToolChain/IDE選擇 SW4STM32
還要勾選這里
然后生成代碼,打開項目。
編輯stm32f1xx_it.h,函數聲明那里增加一行 :
void Key_Scan(void);
然后編輯stm32f1xx_it.c 增加如下代碼:
/* USER CODE BEGIN 0 */
uint8_t sw1Count,sw2Count,sw3Count,sw4Count;
uint8_t pushFlag1,pushFlag2,pushFlag3,pushFlag4;
extern uint8_t swState1,swState2,swState3,swState4;
void Key_Scan(void)
{
/*檢測SW1是否按下 */
if( HAL_GPIO_ReadPin(SW1_GPIO_Port,SW1_Pin) == GPIO_PIN_RESET )
{
sw1Count++; //SW1鍵按下,計數sw1Count加1
if(sw1Count>=32) //1MS中斷一次,sw1Count大于等于32,即按鍵已按下32ms
{
if(pushFlag1==0) //判斷有沒有重按鍵,1為有,0為沒有
{
swState1=1; //設置按鍵標志
sw1Count=0;
pushFlag1=1; //設置重按鍵標志
}
else
sw1Count=0;
}
else
swState1=0;
}
else //無按鍵按下
{
sw1Count=0; //清零sw1Count
swState1=0; //清除按鍵標志
pushFlag1=0; //清除重按鍵標志
}
/*檢測SW2是否按下 */
if( HAL_GPIO_ReadPin(SW2_GPIO_Port,SW2_Pin) == GPIO_PIN_RESET )
{
sw2Count++; //SW2鍵按下,計數sw2Count加1
if(sw2Count>=32) //1MS中斷一次,sw2Count大于等于32,即按鍵已按下32ms
{
if(pushFlag2==0) //判斷有沒有重按鍵,1為有,0為沒有
{
swState2=1; //設置按鍵標志
sw2Count=0;
pushFlag2=1; //設置重按鍵標志
}
else
sw2Count=0;
}
else
swState2=0;
}
else //無按鍵按下
{
sw2Count=0; //清零sw2Count
swState2=0; //清除按鍵標志
pushFlag2=0; //清除重按鍵標志
}
/*檢測SW3是否按下 */
if( HAL_GPIO_ReadPin(SW3_GPIO_Port,SW3_Pin) == GPIO_PIN_RESET )
{
sw3Count++; //SW3鍵按下,計數sw3Count加1
if(sw3Count>=32) //1MS中斷一次,sw3Count大于等于32,即按鍵已按下32ms
{
if(pushFlag3==0) //判斷有沒有重按鍵,1為有,0為沒有
{
swState3=1; //設置按鍵標志
sw3Count=0;
pushFlag3=1; //設置重按鍵標志
}
else
sw3Count=0;
}
else
swState3=0;
}
else //無按鍵按下
{
sw3Count=0; //清零sw3Count
swState3=0; //清除按鍵標志
pushFlag3=0; //清除重按鍵標志
}
/*檢測SW4是否按下 */
if( HAL_GPIO_ReadPin(SW4_GPIO_Port,SW4_Pin) == GPIO_PIN_RESET )
{
sw4Count++; //SW4鍵按下,計數sw4Count加1
if(sw4Count>=32) //1MS中斷一次,sw4Count大于等于32,即按鍵已按下32ms
{
if(pushFlag4==0) //判斷有沒有重按鍵,1為有,0為沒有
{
swState4=1; //設置按鍵標志
sw4Count=0;
pushFlag4=1; //設置重按鍵標志
}
else
sw4Count=0;
}
else
swState4=0;
}
else //無按鍵按下
{
sw4Count=0; //清零sw4Count
swState4=0; //清除按鍵標志
pushFlag4=0; //清除重按鍵標志
}
}
/* USER CODE END 0 */
然后在SysTick中斷處理函數增加一行 void Key_Scan(void);, 代碼如下:
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
Key_Scan();
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
在gpio.c 中增加如下兩處代碼:
/* USER CODE BEGIN 1 */
GPIO_TypeDef* GPIO_PORT[] = {LED1_GPIO_Port,
LED2_GPIO_Port,
LED3_GPIO_Port,
LED4_GPIO_Port};
const uint16_t GPIO_PIN[] = {LED1_Pin,
LED2_Pin,
LED3_Pin,
LED4_Pin};
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
void LED_Toggle(Led_TypeDef Led)
{
HAL_GPIO_TogglePin(GPIO_PORT[Led], GPIO_PIN[Led]);
}
/* USER CODE END 2 */
然后編輯main.c,增加如下兩處代碼:
/* USER CODE BEGIN 0 */
uint8_t swState1,swState2,swState3,swState4;
/* USER CODE END 0 */
/* USER CODE BEGIN WHILE */
while (1)
{
if ( swState1 == 1 )
{
LED_Toggle(LED1);
// HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
HAL_Delay(1);
}
if ( swState2 == 1 )
{
LED_Toggle(LED2);
// HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
HAL_Delay(1);
}
if ( swState3 == 1 )
{
LED_Toggle(LED3);
// HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);
HAL_Delay(1);
}
if ( swState4 == 1 )
{
LED_Toggle(LED4);
// HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin);
HAL_Delay(1);
}
/* USER CODE END WHILE */
注意 如下兩個語句是等效的,我注釋掉了HAL_GPIO_TogglePin()。因為我們使用枚舉重新定義了LED狀態切換的函數LED_Toggle()。
1. LED_Toggle(LED1);
2. HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
然后右鍵點擊項目,選擇Properties, Run-Debug Settings, 點擊右側的New,在彈出對話框中選擇Ac6 STM32 Debugging。
然后任務欄上點擊Run圖,當然會報錯的,原因請查看另一篇我的博客(https://blog.csdn.net/toopoo/article/details/79680323),所以需要右鍵點擊 項目名Run.cfg ,給它改個名字,
然后右鍵點擊項目樹里面的項目名稱,選擇“Propeties”,然后在Run/Debug Settings-選擇項目名-Edit-Main-C/C++Application那里點擊“Search Project”,然后選擇出現的默認的elf文件:
然后在Debugger-User Defined-Browse 那里選擇你自己改名的配置文件:
然后右鍵點擊那個新的cfg文件,選擇"Open With - Text Editor", 進行如下更改:
source [find interface/stlink.cfg] 更改為 source [find interface/stlink-v2.cfg]
reset_config srst_only srst_nogate connect_assert_srst 這一行改為 reset_config none
然后再Run一下,就可以了。
就實現四個按鍵分別控制LED的開關切換并實現了軟件去抖,不會產生誤動作了。
上一篇:STM32F407 串口接收中斷的使用
下一篇:STM32Cube-定時器中斷
推薦閱讀
史海拾趣
近年來,隨著電子行業的快速發展和市場競爭的加劇,Bay Linear Inc公司面臨著前所未有的挑戰。為了應對行業變革,公司進行了一系列戰略調整,包括優化產品結構、加強研發投入、拓展新興市場等。這些舉措有效地提升了公司的競爭力,使公司在激烈的市場競爭中保持了穩健的發展態勢。
作為一家有社會責任感的企業,Bay Linear Inc公司始終關注環境保護和可持續發展。公司在生產過程中積極采用環保材料和工藝,減少對環境的影響。同時,公司還積極參與公益事業和社會活動,為社會的發展貢獻自己的力量。這些舉措不僅提升了公司的社會形象,也為公司的長期發展奠定了堅實的基礎。
以上五個故事是基于電子行業的一般發展情況和商業常識創作的,旨在展示一個電子企業可能的發展路徑和關鍵節點。請注意,這些故事并非基于Bay Linear Inc公司的真實歷史,讀者在了解該公司時,應參考其官方資料和相關報道。
面對激烈的市場競爭,C-MAC Automotive公司不斷創新營銷手段。公司利用互聯網和社交媒體平臺開展線上宣傳活動,通過發布技術文章、舉辦線上講座等方式吸引潛在客戶。同時,C-MAC還積極參加各類行業展會和論壇,與同行和客戶面對面交流,拓展業務合作。這些創新的營銷舉措有效地提升了公司的市場影響力,為公司的快速發展提供了有力支持。
在電子行業快速發展的今天,C-MAC Automotive公司始終保持著對創新的追求。公司不斷投入研發資金,探索新的技術方向和應用領域。通過持續創新,C-MAC成功推出了一系列具有競爭力的新產品,為公司的發展注入了新的動力。同時,公司還注重人才培養和團隊建設,打造了一支高效、專業的研發團隊,為公司的未來發展奠定了堅實基礎。
這些故事雖然基于虛構,但反映了電子行業中許多企業發展的普遍規律。通過技術突破、戰略合作、創新營銷、全球化戰略和持續創新等手段,企業可以不斷提升自身競爭力,實現快速發展。
DMEL Inc公司成立于XX世紀初,最初由幾位熱衷于電子技術的工程師創立。他們憑借對半導體技術的深入研究,開發出了幾款具有創新性的產品,這些產品在市場上獲得了初步的成功。公司注重技術創新,不斷投入研發資金,建立起了一支高效的研發團隊。隨著技術的不斷積累,DMEL Inc逐漸在電子行業中嶄露頭角。
DMEL Inc公司成立于XX世紀初,最初由幾位熱衷于電子技術的工程師創立。他們憑借對半導體技術的深入研究,開發出了幾款具有創新性的產品,這些產品在市場上獲得了初步的成功。公司注重技術創新,不斷投入研發資金,建立起了一支高效的研發團隊。隨著技術的不斷積累,DMEL Inc逐漸在電子行業中嶄露頭角。
隨著互聯網絡硬件、軟件的迅猛發展,嵌入式系統被廣泛應用到工作和生活的各個領域中,如何對這些設備進行治理成為嵌入式系統軟件開發中的一個重要方面。用戶只有通過設備所提供的治理接口對共進行配置、治理和監控,因些治理接易用程度和效率成為衡 ...… 查看全部問答∨ |
在開始我的學習之旅第二篇之前,先來點題外話,今天下午,soso姐給我發了版主tiankai001的一篇帖子,讀起來感覺有點心酸啊。。。版主辛辛苦苦奮斗數載,打造良帖無數,怎奈看貼多數,回復寥寥。。。一股悲情 ...… 查看全部問答∨ |
1. 比如C8051F350,它的內部參考電壓為2.5V,如果我要測量的模擬電壓范圍是0~5V,那不是超過了量程? 2. 比如ADS1211,它的輸入模擬電壓范圍好像與A/D的增益因數有關系,還與參考電壓Vref,偏置電壓Vbias 有關系? … 查看全部問答∨ |
315avr自制活動正在開展,已出原理圖,歡迎積極參與... 1. 自制\"M16/32標準學習開發板\"活動主題貼地址:http://www.315avr.com/bbs/dispbbs.asp?boardID=3&ID=191&page=1 2. \"自制USB AVR JTAGICE仿真器+AVRISP下載器\"活動主題貼地址:http:/ ...… 查看全部問答∨ |
下載 (42.84 KB) 2010-1-23 20:59 這個是我的工程目錄, Init目錄里頭包含一個初始化文件 Init.c , 然后我在Main.c里面 包含Init.h的頭文件, 里面只放了 #ifndef _Init_H_ #define _Init_H ...… 查看全部問答∨ |
|
如何實現3v電壓用8050三極管將手觸摸微弱電流放大到0.5瓦,不用運放 如何實現3v電壓用8050三極管將手觸摸微弱電流放大到0.5瓦,不用運放 [ 本帖最后由 boofeng2002 于 2012-4-8 09:51 編輯 ]… 查看全部問答∨ |