精簡封裝技巧5----函數指針_鬧鐘

//這周分享一個函數指針在嵌入式軟體編程的應用,筆者把它命名為---鬧鐘

1、簡單回憶一下函數指針

在上一篇文章中,筆者提出了一種重新定義的數據類型,返回值空,參數表空的函數指針類型------void_func_point。

typedef void (*void_func_point) (void);

並且在上一篇文章中提到了一個在MODBUS協議實現的一個應用,不知道是否對諸君有所啟發。

2、鬧鐘

在現實生活中,咱們經常會用到鬧鐘,今天晚上十一點睡覺了,我只想睡7個小時,因為明天還得上班,於是我就設定了一個鬧鐘,7個小時之後,我就得起床。即十一點這個時刻,開啟一個定時任務,定時器時間到(Timeup),那麼執行某個任務----起床。

在嵌入式軟體代碼中,上述情況是非常常用的,我們經常會遇到定時做某一件事的情況,那麼這樣的代碼該如何構建呢?請看下文。

3、實現鬧鐘的兩種寫法

單片機中有定時器模塊,熟悉單片機的朋友們一定對定時器情有獨鍾。

如果我們想使用定時器,必須首先對定時器的寄存器進行編程,然後我們再去編寫中斷服務函數的內容。那麼單片機就會定時的執行中斷服務函數了。

筆者設定一個典型的期望任務,就是打開一個鬧鐘,10S之後打開一個燈。

我們假定已經封裝好了這些函數,完成特定功能。

void set_led_status(led_t on_off); //led_t為枚舉,on開 off關

void init_timer(uint16_t T);//配置定時器的中斷時間為T s

void enable_timer(void);//使能定時器中斷

void disable_timer(void);//關閉定時器中斷

寫法1

void main(void){

init_timer(10);

enable_timer();

}

//timer_isr 是中斷服務函數

#pragma vector=TIMERA0_VECTOR

__interrupt void timer_isr(void){

set_led_status(on);

disable_timer();

}

寫法1是典型的寫法,在main函數中初始化中斷時間,然後進入中斷,執行需要執行的任務,然後關閉定時器中斷,實現鬧鐘功能。這樣的寫法並沒有什麼大問題,但是請讀者對比下述寫法。

typedef void (*void_func_point) (void);

void null_func(void){}

void_func_point exe_func_in_timer = null_func;

void config_alarm(uint16_t alarm_time , void_func_point exe_func){

init_timer(alarm_time);

enable_timer();

exe_func_in_timer = exe_func;

}

static void open_led(void){

set_led_status(on);

}

void main(void){

config_alarm(10,open_led);

}

//timer_isr 是中斷服務函數

#pragma vector=TIMERA0_VECTOR

__interrupt void timer_isr(void){

exe_func_in_timer();

disable_timer();

}

寫法二很明顯要比寫法一複雜的多,乍看起來並沒什麼好的地方。但仔細思想,寫法二封裝了一個config_alarm函數,這個函數有一個參數表是函數指針,那麼如果我需要10s後做其他的事情,只需要傳入其他函數指針就可以了,並不需要修改中斷函數內容,因為中斷函數中執行的不是特定函數,而是一個函數指針指向的函數,我們可以通過參數表傳值給中斷服務函數,從而改變中斷服務函數里的內容。

值得一提的是,安全起見,一定要定義一個空函數,為函數指針賦予安全初值。

寫法二是一種封裝的技巧,今後我再想定時執行一個任務,只需要配置config_alarm(定時時間,時間到了之後運行的函數指針)就可以完成任務,無需再多修改原有的結構代碼。脫離了特定的任務代碼,從而把定時器驅動放在了一個通用代碼的位置上,這樣的好處是很強的可移植性,你重新開啟一個新的工程,完全複製粘貼這邊的代碼就可以了。

這樣封裝使得他成為一個通用的工具,而不是特定的、指定的、完全量身定做的工具!

4、筆者思考

工具的封裝,好比一個鎚子。開發者不需要知道你用鎚子幹什麼,只是把自己應有的功能封裝到了鎚子裡面。寫法1就好比開發者為某一個工程項目量身定做了一個鎚子,只能在此項目中用,而寫法二提供了一個通用的鎚子,用在哪都行,我想這是封裝的意義吧!

今晚筆者看了平昌冬奧會的開幕式,感覺蠻震撼的!特別是無人機組成奧運五環的畫面,他們用了自己的理解,詮釋科技與生活的交融。

未來,多麼充滿神秘的詞語!

未來的生活輕便而舒適,未來的醫療令人感受不到病痛折磨。未來,我們的未來,孩子們的未來。無論未來如何,我們得守護未來。

聖奧林匹斯休戰,朝鮮半島的和平關乎每一個人,我們又能做什麼呢?唯獨做好自己的本分工作,祈求著世界能夠朝著和平發展!

我想未來的科技創新中心一定在中國,我們也有聰明的工程師,我們有睿智的科學家,我們處在祖國強盛的時代,絕不能輸給自古以來就崇拜中華的高麗民族。

與諸君共勉,共同砥礪奮進!

願孩子們的笑容永在,世界和平,人類幸福!


推薦閱讀:

TAG:C編程語言 | 單片機 | C指針 |