<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                * 導師視頻講解:[**去聽課**](https://www.bilibili.com/video/BV1k34y1D7Vz/) >[success] **技術支持說明:** >**1**.一般以自主學習為主 > **2**.可到官方問答社區中提問:[**去提問**](https://bbs.csdn.net/forums/zigbee) > **3**.工程師**會盡快**解答社區問題,但他們是一線開發,【**難以保證**】解答時效,解答辛苦,感謝理解! <br/> 上節課講解HAL 按鍵的API的使用,本節課將深入分析一下其中原理。**如果讀者暫時不需要學習其中的原理,可以跳過本節課**。 ### HAL的按鍵框架的主要代碼在hal_key.c文件中,打開該文件可以找到以下這幾個重要的函數: ### ``` HalKeyInit HalKeyConfig HalKeyPoll HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) ``` <br/> ## **初始化函數HalKeyInit** ``` 1.void?HalKeyInit(?void?)???? 2.{???? 3.??/*?Initialize?previous?key?to?0?*/???? 4.??halKeySavedKeys?=?0;???? 5.???? 6.??HAL_KEY_SW_6_SEL?&=?~(HAL_KEY_SW_6_BIT);??//?I/O為普通GPIO?? 7.???? 8.#if?!?defined?ENABLE_LED4_DISABLE_S1???? 9.??HAL_KEY_SW_6_DIR?&=?~(HAL_KEY_SW_6_BIT);??//?I/O配置為輸入?? 10.#endif???? 11.?????? 12.??HAL_KEY_JOY_MOVE_SEL?&=?~(HAL_KEY_JOY_MOVE_BIT);?? 13.??HAL_KEY_JOY_MOVE_DIR?&=?~(HAL_KEY_JOY_MOVE_BIT);??? 14.???? 15.??/*?Initialize?callback?function?*/???? 16.??pHalKeyProcessFunction??=?NULL;???? 17.???? 18.??/*?Start?with?key?is?not?configured?*/???? 19.??HalKeyConfigured?=?FALSE;???? 20.} ``` 初始化函數主要是用于配置GPIO為輸入功能,HAL\_KEY\_SW\_6\_SEL等定義其實是按鍵GPIO配置相關的寄存器,這些定義可以在hal\_key.c中找到,如果我們需要添加其他按鍵,也遵循這個方法即可! 配置HAL\_KEY\_6相關寄存器的定義如下: ![](https://img.kancloud.cn/1c/38/1c3884768710099f204a728ffa2b66a5_738x594.png =600x) ### 在初始化函數HalKeyInit中有個地方需要說明,這個函數中有一段代碼(用了快配置HAL\_KEY\_SW\_6這個按鍵的引腳為輸入功能): ``` 1.#if?!?defined?ENABLE_LED4_DISABLE_S1???? 2.??HAL_KEY_SW_6_DIR?&=?~(HAL_KEY_SW_6_BIT);??//?I/O配置為輸入?? 3.#endif ``` ZStack的本意是S1按鍵引腳P0\_1可以用來驅動LED,就是和按鍵復用了,是否用作LED取決于宏ENABLE\_LED4\_DISABLE\_S1是否定義,但是協議棧沒有開源的那部分代碼中定義了這個宏,也算是ZStack的一個Bug,所以這段代碼我們需做修改,把預編譯去掉(注釋掉),否則按鍵引腳不會被配置為輸入: ``` 1.//?#if?!?defined?ENABLE_LED4_DISABLE_S1???? 2.??HAL_KEY_SW_6_DIR?&=?~(HAL_KEY_SW_6_BIT);??//?I/O配置為輸入?? 3.//?#endif ``` ## **HalKeyConfig** 這個函數主要用來配置和中斷相關的內容: ``` 1.void?HalKeyConfig?(bool?interruptEnable,?halKeyCBack_t?cback) 2.{?? 3.??Hal_KeyIntEnable?=?interruptEnable;??// 標志:是否使能中斷 4.?? 5.??pHalKeyProcessFunction?=?cback;? // 回調函數,按鍵按下時調用 6.?? 7.??/*?Determine?if?interrupt?is?enable?or?not?*/?? 8.??if?(Hal_KeyIntEnable)??// 如果使能了中斷,必須配置中斷相關內容 9.??{?? 10.????PICTL?&=?~(HAL_KEY_SW_6_EDGEBIT);?/*?Clear?the?edge?bit?*/?? 11.????/*?For?falling?edge,?the?bit?must?be?set.?*/?? 12.??#if?(HAL_KEY_SW_6_EDGE?==?HAL_KEY_FALLING_EDGE)?? 13.????PICTL?|=?HAL_KEY_SW_6_EDGEBIT;?? 14.??#endif?? 15. 16.????/*?Interrupt?configuration:? 17.?????*?-?Enable?interrupt?generation?at?the?port? 18.?????*?-?Enable?CPU?interrupt? 19.?????*?-?Clear?any?pending?interrupt? 20.?????*/?? 21.????HAL_KEY_SW_6_ICTL?|=?HAL_KEY_SW_6_ICTLBIT;?? 22.????HAL_KEY_SW_6_IEN?|=?HAL_KEY_SW_6_IENBIT;?? 23.????HAL_KEY_SW_6_PXIFG?=?~(HAL_KEY_SW_6_BIT);?? 24. 25. .........??// 屏蔽無關緊要的代碼 26. 27.????if?(HalKeyConfigured?==?TRUE)?? 28.????{?? 29.????osal_stop_timerEx(Hal_TaskID,?HAL_KEY_EVENT);?// 不需要輪詢 30.????}?? 31.??}?? 32.??else???// 如果沒有使用中斷,必須把中斷相關內容關閉掉 33.??{?? 34.????HAL_KEY_SW_6_ICTL?&=?~(HAL_KEY_SW_6_ICTLBIT);? 35.????HAL_KEY_SW_6_IEN?&=?~(HAL_KEY_SW_6_IENBIT);? 36.????osal_set_event(Hal_TaskID,?HAL_KEY_EVENT);??// 按鍵輪詢事件 37.??}?? 38. 39.??HalKeyConfigured?=?TRUE;?? 40.} ``` <br/> ## **HalKeyPoll** ``` 1.void?HalKeyPoll?(void)???? 2.{???? 3.??uint8?keys?=?0;???? 4.??if?((HAL_KEY_JOY_MOVE_PORT?&?HAL_KEY_JOY_MOVE_BIT))??? 5.??{???? 6.????keys?=?halGetJoyKeyInput();???? 7.??}???? 8.??/*?? 9.???*???.........? 10.???*/???? 11.??if?(!Hal_KeyIntEnable)???? 12.??{???? 13.????if?(keys?==?halKeySavedKeys)???? 14.????{???? 15.??????return;???? 16.????}???? 17.????halKeySavedKeys?=?keys;???? 18.??}???? 19.??else???? 20.??{???? 21.????/*?Key?interrupt?handled?here?*/???? 22.??}???? 23.??if?(HAL_PUSH_BUTTON1())??//?檢測HAL_KEY_SW_6是否按下,添加其他 24. ?{????????????????????????//?按鍵時,同樣也需要在這里做檢測!?? 25.????keys?|=?HAL_KEY_SW_6;???? 26.??}???? 27.?????? 28.??if?(pHalKeyProcessFunction???? 29.#ifdef?HAL_LEGACY_KEYS???? 30.????&&?keys?? 31.#endif???? 32.????)???? 33.??{???? 34.????(pHalKeyProcessFunction)?(keys,?HAL_KEY_STATE_NORMAL);???? 35.??}???? 36.} ``` 這個函數是用來查詢按鍵是否按鍵,如果是中斷方式,檢測到中斷時去抖然后進入這個函數;如果不是中斷方式那么采用周期性輪詢查看按鍵是否按下。 ### 函數HAL\_ISR\_FUNCTION( halKeyPort0Isr, P0INT\_VECTOR ): 這是個中斷處理函數,中斷向量是P0INT\_VECTOR也就是P0口的中斷,按鍵連接的是P0\_1,按下產生中斷就會來到這個函數: ``` 1.HAL_ISR_FUNCTION(?halKeyPort0Isr,?P0INT_VECTOR?)???? 2.{???? 3.??HAL_ENTER_ISR();??? 4.??if?(HAL_KEY_SW_6_PXIFG?&?HAL_KEY_SW_6_BIT)??//?P0_1中斷?? 5.??{???? 6.????halProcessKeyInterrupt();??//?調用這個函數來處理中斷?? 7.??????????????????????????????????//?最終會調用?HalKeyPoll?? 8.??}???? 9.??/*?? 10.????Clear?the?CPU?interrupt?flag?for?Port_0?? 11.????PxIFG?has?to?be?cleared?before?PxIF?? 12.??*/???? 13.??HAL_KEY_SW_6_PXIFG?=?0;??????//?清除中斷標志?? 14.??HAL_KEY_CPU_PORT_0_IF?=?0;???? 15.??CLEAR_SLEEP_MODE();???? 16.??HAL_EXIT_ISR();???? 17.} ``` 最終中斷會在函數halProcessKeyInterrupt()中被處理: ``` 1.void?halProcessKeyInterrupt?(void)?? 2.{?? 3.??bool?valid=FALSE;?? 4.??// 清除HAL_KEY_SW_6引腳對應的中斷標志位 5.??if?(HAL_KEY_SW_6_PXIFG?&?HAL_KEY_SW_6_BIT) 6.??{?? 7.????HAL_KEY_SW_6_PXIFG?=?~(HAL_KEY_SW_6_BIT); 8.????valid?=?TRUE;?? 9.??} 10.?? 11.??if?(valid)?? 12.??{?? // 啟動一個事件,25ms后到期(去抖),事件會在hal_drivers.c 13. // 中被處理(Hal_ProcessEvent),最終會調用HalKeyPoll osal_start_timerEx?(Hal_TaskID,?HAL_KEY_EVENT,? HAL_KEY_DEBOUNCE_VALUE);?? 14.??}?? 15.} ``` 問題:上面講解的函數最終會在哪里被調用呢? ### 我們提供一種方法可以用來在IAR中查看所有與關鍵字相關的內容,進而可以找到函數被調用的地方: ![](https://img.kancloud.cn/ca/de/caded0f93e01a9b381e348292fa232b7_768x792.png =600x) ### 這個搜索功能是全局搜索,也就是說會IAR搜索工程中的所有文件,然后匹配我們要搜索的關鍵字,再將結果顯示出來;比如我們想搜索與關鍵字HalKeyInit相關的所有內容,可以在彈出的對話框中輸入這個關鍵字,然后點擊”Find”即可,然后我們根據搜索出來的結果,可以通過鼠標雙擊對應的結果來查看相關內容: ![](https://img.kancloud.cn/30/3c/303c0830ae3252688d305902511c66b9_732x618.png =600x) <br/> <br/> ## **項目定制** * 如需項目定制開發,可掃碼添加項目經理好友(注明“**項目定制**”) * 定制范圍:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等IoT技術方案 * 善學坊官網:[www.sxf-iot.com](https://www.sxf-iot.com/) ![](https://img.kancloud.cn/ca/73/ca739f92cab220a3059378642e3bd502_430x430.png =200x) * 非項目定制**勿擾**,此處**非**技術支持
                  <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>

                              哎呀哎呀视频在线观看