<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                >[success] **技術支持說明** > 1.**客服**提供簡單的技術支持,一般自主學習為主 > 2.可到官方問答社區中提問:[**去提問**](https://bbs.csdn.net/forums/nb-iot) > 3.工程師**會盡快**解答社區問題,但他們是一線開發,【**難以保證**】解答時效,解答辛苦,感謝理解! <br/> ## **按鍵原理簡介** &emsp;&emsp;在LED相關課程中,把GPIO配置為輸出模式,然后通過控制該GPIO輸出高/低電平來控制LED的亮/滅。然而,與之相反,按鍵是一種被動器件,即由外界把按鍵相關的信號輸入到主控芯片中,因此需要把GPIO配置為輸入模式。 ### **電路原理簡介** 配套的開發板帶有一個名為“PA0”的按鍵,如下圖所示。 ![](https://img.kancloud.cn/7f/25/7f255c0346cc531b0a02fc34645643c1_1671x1884.png =200x) ### 其原理圖如下所示。 ![](https://img.kancloud.cn/f9/1b/f91b89a1f9375403b7db7d1a450ad00a_673x236.png =500x) >[warning] 如您未能看懂此原理圖,需要補充一下相關知識。 <br/> 從原理圖中可以看出,此按鍵與STM32的PA0引腳相連接。在把PA0配置為輸入模式后,當按鍵被按下時,PA0接地,即輸入低電平。與此同時,可以通過內部上拉的方式實現沒有按下時即輸入高電平。此時,程序通過檢測PA0輸入電平即可檢測按鍵是否被按下: * 按鍵沒有被按下時,PA0輸入高電平 * 按鍵被按下后,PA0輸入低電平 >[info] 如果讀者不了解何謂內部上拉,可暫時跳過 <br/> ## **按鍵HAL API 設計** 通過前面的原理分析,可以知道按鍵是一種被動器件,需要檢測PA0的輸入電平高低變化。在設計此類型API時,可以使用注冊回調的思想,即上層應用在HAL中注冊已給回調函數,一旦HAL檢測到按鍵按下,就會回調給上層應用,如圖所示。 ![](https://img.kancloud.cn/cc/c9/ccc9a3c8665bdbd80de9b3e0428ebf47_464x481.png =250x) ### 接下來通過代碼來講解這個設計。 <br/> **編寫代碼** 筆者在本節課配套的源代碼中新建了 hal\_button.h 和 hal\_button.c文件,如圖所示。 ![](https://img.kancloud.cn/6c/65/6c655c550a158648a25887de4122061d_600x1056.png =200x) ### 打開本節課配套的工程,筆者把hal\_button.c以及必要的標準庫文件添加進工程了,如圖所示。 ![](https://img.kancloud.cn/8f/cb/8fcb72807c8aef9309099f80a2faaefb_375x535.png =250x) <br/> hal_button.h文件的代碼如下: ``` #ifndef __HAL_BUTTON_H__ #define __HAL_BUTTON_H__ /*定義按鍵連接的GPIO口PA0*/ #define HAL_BUTTON_PORT GPIOA #define HAL_BUTTON_PIN GPIO_Pin_0 /*定義GPIOA對應的時鐘 */ #define HAL_BUTTON_CLOCK RCC_AHBPeriph_GPIOA #define HAL_BUTTON_TRIGGER_LEVEL 0 /* * 按鍵初始化 * @param onClick - 按鍵回調函數,當按鍵被按下時執行此函數 */ void halButtonInit(void (*onClick)(void)); /* * 檢測到按鍵按下時,執行回調回調函數 */ void halButtonPoll(void); #endif /* #ifndef __HAL_BUTTON_H__ */ ``` <br/> hal_button.c文件的代碼如下: ### ``` #include "hal_button.h" #include "hal_system.h" #include "stm32f0xx_gpio.h" static void (*halButtonOnClick)(void) = 0; /* * 按鍵初始化 * @param onClick - 按鍵回調函數,當按鍵被按下時執行此函數 */ void halButtonInit(void (*onClick)(void)) { halButtonOnClick = onClick;//保存回調函數 GPIO_InitTypeDef buttonGPIO;//定義GPIO配置 buttonGPIO.GPIO_Mode = GPIO_Mode_IN;//配置為輸入模式 buttonGPIO.GPIO_PuPd = GPIO_PuPd_UP,//配置為上拉 buttonGPIO.GPIO_Speed = GPIO_Speed_2MHz;//速率為2MHz buttonGPIO.GPIO_Pin = HAL_BUTTON_PIN;//引腳 RCC_AHBPeriphClockCmd(HAL_BUTTON_CLOCK, ENABLE);//使用按鍵時鐘 GPIO_Init(HAL_BUTTON_PORT, &buttonGPIO);//初始化PA0 } /* * 檢測到按鍵按下時,執行回調函數 */ void halButtonPoll(void) { /* 如果按鍵沒有被按下,如果沒有則返回*/ if (GPIO_ReadInputDataBit(HAL_BUTTON_PORT, HAL_BUTTON_PIN) != HAL_BUTTON_TRIGGER_LEVEL) return; /* 延遲10ms,去除機械按鍵抖動 */ halSystemDelayUs(1000 * 10); /* 再次檢測按鍵是否被按下,如果沒有則返回*/ if (GPIO_ReadInputDataBit(HAL_BUTTON_PORT, HAL_BUTTON_PIN) != HAL_BUTTON_TRIGGER_LEVEL) return; /* 等待按鍵松開 */ while(GPIO_ReadInputDataBit(HAL_BUTTON_PORT, HAL_BUTTON_PIN) == HAL_BUTTON_TRIGGER_LEVEL) halSystemDelayUs(1000); /* 如果定義回調函數,則調用回調函數 */ if (halButtonOnClick != 0) halButtonOnClick(); } ``` **處理機械按鍵抖動** 上述代碼包含了按鍵抖動的處理,對其簡單講解一下。由于按鍵內部采用了彈簧,所以當按鍵被按下或松開的時候,會產生一定的震動,這種震動可以稱為機械抖動。這種機械抖動會導致電平的抖動,如下圖所示。 ![](https://img.kancloud.cn/bf/f5/bff52fc67f3feab02d1677a500e74037_582x324.png =300x) ### 上圖展示了按鈕從按下到松開這個過程的電平變化。按鍵被按下時產生的抖動稱為前沿抖動,松開時產生的是后沿抖動。這個抖動時間一般持續5~10ms。因此在代碼上當檢測到按鈕被按下后,需要延后10ms后再檢測一次按鈕是否真的被按下。 <br/> ## **使用按鍵 HAL API** 編寫好按鍵 HAL API后,按鍵的使用非常簡單。在配套工程的main.c文件中添加如下代碼: ``` /* * 按鍵回調函數,當按鍵被按下后即執行此函數 */ static void buttonOnClick() { halLedToggle();//反轉LED燈的亮滅狀態 } int main(void) { halSystemInit();//系統初始化 halLedInit();//LED初始化 /*按鍵初始化,并且傳入了回調函數*/ halButtonInit(buttonOnClick); /*使用while循環來持續檢測按鍵是否被按下*/ while (1) { halButtonPoll(); } } ``` 上述代碼實現了當按鍵別按下并松開后,反轉LED燈的狀態,代碼非常簡潔! <br/> <br/> ## **商務合作** 如有以下需求,可掃碼添加管理員好友,注明“**商務合作**” * 項目定制開發,技術范圍:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等; * 入駐平臺,成為講師; * 接項目賺外快; * 善學坊官網:[www.sxf-iot.com](https://www.sxf-iot.com/) ![](https://img.kancloud.cn/ca/73/ca739f92cab220a3059378642e3bd502_430x430.png =150x) (非商務合作**勿擾**,此處**非**技術支持)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看