網站首頁 編程語言 正文
下文將學習到;
- 程序架構的核心理念和需求
- 掌握回調函數的作用
- 掌握回調函數的程序編寫
- 掌握回調函數在產品中的應用
1.程序架構
一個好的程序架構至少要達到以下要求:
硬件層和應用層的程序代碼分開,相互之間的控制和通訊使用接口,而且不會共享的全局變量或者數組。
用專業術語描述就是可移植性、可擴展性。
在51單片機寫程序時,基本上一個.c文件解決,包括寄存器配置,產品功能。到了stm32時,我們會把不同的外設功能,比如led,按鍵,串口等外設功能代碼分別寫在不同的.c文件里,然后統一用函數接口去調用它,比方說控制一個LED燈亮,直接在led.c文件里寫一個驅動led燈狀態的函數然后給外部調用就好了。硬件層和應用層代碼分開,應用層用硬件層提供的接口來控制,而且不會有硬件層和應用層共享的全部變量或數組。
還有一種情況,應用程序需要收集硬件層的數據,比如串口接收數據,按鍵采集,adc值采集,這種值應該怎么樣從硬件層獲取呢?
簡單的方法就是用全局變量或者數組,比方說硬件層串口接收到數據了,那么我們把數據丟到數組里面,然后把接收完成的全局變量標志置為1,比方說全局變量名為RcvFlag,然后應用層程序會輪詢判斷RcvFlag==1?是的話就把數組里面的數據取出來解析。
但是這種方法存在實時性差和移植性差的問題,比如說需要把串口的硬件層封裝起來給客戶使用,不能讓客戶看到實現的源碼,只能提供函數接口給客戶使用,不可能通過告訴客戶先判斷哪個變量為1,然后在取哪個數組中的數據這種做法。
在這里就需要回調函數了。
2.回調函數的作用
在stm32中,像外部中斷、定時器中斷、串口中斷都有點類似回調函數,這種函數的目的是把采集到的數據傳遞給cpu使用。
回調函數的核心作用:
- 把數據從一個.c文件傳遞到另一個.c文件。
3.掌握回調函數的程序編寫
傳統寫法的缺點:
- 1、移植性差
- 2、實時性差
- 3、功能代碼封裝難
回調函數寫法:
main.c代碼:
#include#include "key.h"? void KeyScanHandle(KEY_ID_TYPEDEF KeyID,KEY_STATE_TYPEDEF KeyState) { //?? ?if(KeyID == KEY2) //?? ?{ //?? ??? ?if(KeyState = KEY_PRESS) //?? ??? ?{ ?? ??? ??? ? ?? ??? ??? ?printf("KeyID=%d, KeyState=%d\r\n",KeyID,KeyState); //?? ??? ?} //?? ?} } int main(int argc, char *argv[]) { ?? ?KeyInit(); ?? ?KeyScanCBSRegister(KeyScanHandle); ?? ?KeyPoll(); ? ?? ?return 0; }
key.c代碼:
#include "key.h" KEY_ID_TYPEDEF keyVal;?? ?//按鍵ID KEY_STATE_TYPEDEF keyState;?? ? pKeyScanCallBack pKeyScanCBS; void KeyInit() { ?? ?keyVal = 0; ?? ?keyState = KEY_IDLE; ?? ?pKeyScanCBS = 0; }? void KeyScanCBSRegister(pKeyScanCallBack pCBS) { ?? ?if(pKeyScanCBS == 0) ?? ?{ ?? ??? ?pKeyScanCBS = pCBS; ?? ?} } void KeyPoll() { ?? ?printf("Please Enter key value:"); ?? ?if(scanf("%d",&keyVal)==1) ?? ?{ ?? ??? ?printf("\r\n"); ?? ??? ?printf("Please enter key state:"); ?? ??? ?if(scanf("%d",&keyState)==1) ?? ??? ?{ ?? ??? ??? ?if(pKeyScanCBS != 0) ?? ??? ??? ?{ ?? ??? ??? ??? ?pKeyScanCBS(keyVal,keyState); ?? ??? ??? ?} ?? ??? ?}?? ??? ? ?? ?} }
key.h代碼:
#ifndef _KEY_H_ #define _KEY_H_ typedef enum? { ?? ?KEY1, ?? ?KEY2,?? ? }KEY_ID_TYPEDEF; typedef enum { ?? ?KEY_IDLE,?? ?//空閑? ?? ?KEY_PRESS,?? ?//按鍵短按 ?? ?KEY_LONG_PRESS,?? ?//按鍵長按 ?? ?KEY_RELEASE,//按鍵釋放 ? }KEY_STATE_TYPEDEF;? typedef void (*pKeyScanCallBack)(KEY_ID_TYPEDEF KeyID,KEY_STATE_TYPEDEF KeyState); ? void KeyInit(); void KeyPoll(); void KeyScanCBSRegister(pKeyScanCallBack pCBS); #endif
4.回調函數在產品中的應用
根據收到的不同幀內容,做出不同的功能
原文鏈接:https://blog.csdn.net/weixin_44795447/article/details/123226449
相關推薦
- 2022-10-27 Python數值求解微分方程方法(歐拉法,隱式歐拉)_python
- 2023-01-05 C++?Boost?Utility超詳細講解_C 語言
- 2022-08-02 C#中的延時函數sleep_C#教程
- 2023-10-15 獲取當天開始時間零點和結束時間24點的時間以及時間戳
- 2022-11-23 關于vba代碼運行時錯誤1004?應用程序定義或對象定義錯誤問題_VBA
- 2022-11-21 C#基礎知識之字符串和正則表達式_C#教程
- 2022-05-31 C++核心編程之內存分區詳解_C 語言
- 2022-09-10 pycharm中沒有找到database的解決方案_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支