周立功教授新書《面向AMetal框架與接口的編程(上)》,對(duì)AMetal框架進(jìn)行了詳細(xì)介紹,通過閱讀這本書,你可以學(xué)到高度復(fù)用的軟件設(shè)計(jì)原則和面向接口編程的開發(fā)思想,聚焦自己的“核心域”,改變自己的編程思維,實(shí)現(xiàn)企業(yè)和個(gè)人的共同進(jìn)步。
第七章為面向通用接口的編程,本文內(nèi)容為7.4 溫度采集接口、7.5 鍵盤。
7.4 溫度采集接口
>>> 7.4.1 溫度傳感器通用接口
AMetal 提供了溫度采集的通用接口,僅包含一個(gè)溫度讀取接口,用于讀取當(dāng)前的溫度值,其函數(shù)原型為(am_temp.h):
其中,handle 為溫度傳感器的句柄,其可以通過初始化具體的溫度傳感器(如LM75)獲得,p_temp 為輸出參數(shù),用于返回當(dāng)前的溫度值,為了避免小數(shù)運(yùn)算,這里使用有符號(hào)的32 位整數(shù)表示溫度值(單位:攝氏度),且其值為實(shí)際溫度值的1000 倍,表示溫度值的分辨率為0.001℃。讀取溫度的范例程序詳見程序清單7.25。
程序清單7.25 am_temp_read()范例程序
顯然要使應(yīng)用程序可以使用通用接口讀取溫度,就必須獲取溫度傳感器的handle,這就需要為具體的溫度傳感器提供相應(yīng)的驅(qū)動(dòng)。
>>> 7.4.2 LM75B 驅(qū)動(dòng)
LM75B 是NXP 半導(dǎo)體推出的具有I2C接口的數(shù)字溫度傳感器芯片,AMetal 已經(jīng)提供了其對(duì)應(yīng)的驅(qū)動(dòng),僅包含一個(gè)初始化函數(shù),其函數(shù)原型(am_temp_lm75.h)為:
該函數(shù)意在獲取LM75 溫度傳感器的實(shí)例句柄,進(jìn)而使用通用接口讀取溫度。其中:
-
p_lm75 為指向am_temp_lm75_t 類型實(shí)例的指針;
-
p_devinfo 為指向am_temp_lm75_info_t 類型實(shí)例信息的指針。
1. 實(shí)例
定義am_temp_lm75_t 類型(am_temp_lm75.h)實(shí)例如下:
其中,g_temp_lm75 為用戶自定義的實(shí)例,其地址作為p_lm75 的實(shí)參傳遞。
2. 實(shí)例信息
實(shí)例信息主要描述了與LM75 相關(guān)的信息,即LM75 的I2C從機(jī)地址等,其類型am_temp_lm75_info_t 的定義(am_temp_lm75.h)如下:
其中,i2c_addr 指定了LM75 的7-bit 從機(jī)地址(在很多應(yīng)用中,常常使用8 位數(shù)據(jù)表示從機(jī)地址, 8 位地址的最低位為讀寫方向位,由于在AMetal 中,讀寫方向位無需用戶控制,驅(qū)動(dòng)會(huì)自動(dòng)實(shí)現(xiàn)對(duì)讀寫方向位的控制,因此在AMetal 中需要由用戶提供的7-bit 從機(jī)地址不包含讀寫方向位),LM75 的7-bit 從機(jī)地址為1001A2A1A0,最低三位由A0~A2 引腳電平?jīng)Q定,在AM824-Core 中,板載了一個(gè)LM75 溫度傳感器。由此可見,A0~A2 均與地連接,為低電平,因此,板載LM75 的地址為1001000,即:0x48。其實(shí)例信息定義如下:
其中,g_temp_lm75_info 為用戶自定義的實(shí)例信息,其地址作為p_info 的實(shí)參傳遞。
3.I2C句柄i2c_handle
以I2C1 為例,其實(shí)例初始化函數(shù)am_lpc82x_i2c1_inst_init()的返回值即可作為實(shí)參傳遞給i2c_handle。即:
4. 實(shí)例句柄
基于實(shí)例、實(shí)例信息和I2C句柄,即可完成LM75 的初始化。比如:
初始化函數(shù)的返回值即為溫度傳感器的句柄,若返回值為NULL,說明初始化失敗;若返回值不為NULL,說明返回了有效的handle,其可以作為溫度讀取接口的參數(shù)。為了便于配置LM75(如修改7-bit 從機(jī)地址等)。基于模塊化編程思想,將初始化相關(guān)的實(shí)例、實(shí)例信息等的定義存放到LM75 的配置文件中,通過頭文件引出實(shí)例初始化函數(shù)接口,源文件和頭文件的程序范例分別詳見程序清單7.26 和程序清單7.27。
程序清單7.26 LM75 實(shí)例初始化函數(shù)實(shí)現(xiàn)(am_hwconf_lm75.c)
程序清單7.27 LM75 實(shí)例初始化函數(shù)聲明(am_hwconf_lm75.h)
后續(xù)只需要使用無參數(shù)的實(shí)例初始化函數(shù)即可完成LM75 實(shí)例的初始化,獲取溫度傳感器句柄,即執(zhí)行如下語句:
當(dāng)完成初始化后,即可使用通用的溫度讀取接口獲取當(dāng)前溫度值,讀取并通過串口打印當(dāng)前溫度值的范例程序詳見程序清單7.28。
程序清單7.28 使用LM75 檢測(cè)當(dāng)前溫度的范例程序
7.5 鍵盤
>>> 7.5.1 通用鍵盤接口
由于此前的按鍵處理方式與具體的MCU、鍵盤的組織形式(獨(dú)立按鍵或矩陣鍵盤等)完全耦合在一起,為此AMetal 提供了一種通用鍵盤接口。其函數(shù)原型為:
其中,p_handler 為指向按鍵事件處理器的指針,pfn_cb 為指向用戶自定義按鍵處理函數(shù)的指針,p_arg 為按鍵處理函數(shù)的用戶參數(shù)。
1. p_handler
am_input_key_handler_t 是按鍵事件處理器的類型,它是在am_input.h 文件中使用typedef自定義的一個(gè)類型。即:
基于此,在使用按鍵時(shí),首先需要定義一個(gè)該類型的按鍵事件處理器實(shí)例(對(duì)象),其本質(zhì)是定義一個(gè)結(jié)構(gòu)體變量。比如:
即可該實(shí)例的地址&key_handler 作為參數(shù)傳遞給函數(shù)的形參p_handler。
2. pfn_cb
am_input_cb_key_t 是按鍵處理函數(shù)的指針類型,它是在am_input.h 文件中使用typedef自定義的一個(gè)類型。即:
當(dāng)有按鍵事件發(fā)生時(shí)(按鍵按下或按鍵釋放),均會(huì)調(diào)用pfn_cb 指向的按鍵處理函數(shù),完成相應(yīng)的按鍵處理功能。當(dāng)該函數(shù)被調(diào)用時(shí),傳遞給p_arg 的值為用戶參數(shù),傳遞給key_code 的值為按鍵的編碼,它是在am_input_code.h 文件中使用宏進(jìn)行定義的,比如,KEY_1、KEY_2 等,傳遞給key_state 的值為按鍵的狀態(tài),詳見表7.5。
表7.5 按鍵狀態(tài)
以AM824-Core 開發(fā)板為例,KEY 對(duì)應(yīng)的按鍵編碼為KEY_KP0。當(dāng)KEY 鍵按下時(shí),則LED0 點(diǎn)亮;當(dāng)KEY 鍵釋放后,則LED0 熄滅,相應(yīng)的按鍵處理函數(shù)詳見程序清單7.29。
程序清單7.29 按鍵處理函數(shù)范例程序
函數(shù)名即可作為參數(shù)傳遞給am_input_key_handler_register()函數(shù)的形參pfn_cb。
3. p_arg
通常調(diào)用am_input_key_handler_register()函數(shù)傳遞給形參p_arg 的值會(huì)在調(diào)用事件處理回調(diào)函數(shù)時(shí),傳遞給事件處理函數(shù)的p_arg 形參。
如果不使用,則在調(diào)用am_input_key_handler_register()函數(shù)時(shí),將p_arg 的值設(shè)置為NULL,注冊(cè)按鍵處理器的范例程序詳見程序清單7.30。
程序清單7.30 按鍵處理函數(shù)范例程序
注冊(cè)按鍵處理器后,當(dāng)有鍵按下或按鍵釋放時(shí),均會(huì)調(diào)用注冊(cè)按鍵處理器時(shí)指定的回調(diào)函數(shù),即程序清單7.29 中的__input_key_proc ()函數(shù)。為了分離各個(gè)鍵的處理代碼,可以注冊(cè)多個(gè)按鍵事件處理器,每個(gè)處理器負(fù)責(zé)處理一個(gè)或多個(gè)鍵,詳見程序清單7.31。
程序清單7.31 注冊(cè)多個(gè)按鍵處理器范例程序
通用鍵盤接口的特點(diǎn)是屏蔽了底層的差異性,使應(yīng)用程序與底層MCU、鍵盤的具體形式無關(guān),可以輕松地實(shí)現(xiàn)應(yīng)用程序的跨平臺(tái)。
在實(shí)際的應(yīng)用中,鍵盤的表現(xiàn)形式是多種多樣的,比如,直接使用GPIO 驅(qū)動(dòng)的獨(dú)立鍵盤(一個(gè)或多個(gè)獨(dú)立按鍵組成的鍵盤)和矩陣鍵盤和標(biāo)準(zhǔn)的PS/2 接口鍵盤,以及使用ZLG推出的I2C接口的ZLG72128 鍵盤與數(shù)碼管驅(qū)動(dòng)芯片制作的鍵盤等。雖然各種按鍵的檢測(cè)方法都不相同,但只要提供相應(yīng)的驅(qū)動(dòng),即可將接口統(tǒng)一起來。如同在PC 上使用外部設(shè)備時(shí),需要安裝對(duì)應(yīng)的驅(qū)動(dòng)一樣。AMetal 提供了常用鍵盤的驅(qū)動(dòng),用戶直接使用無需關(guān)心按鍵檢測(cè)的方法或按鍵消抖等細(xì)節(jié)問題。
>>> 7.5.2 獨(dú)立鍵盤驅(qū)動(dòng)
AMetal 獨(dú)立鍵盤的驅(qū)動(dòng)提供了一個(gè)初始化函數(shù),使用該函數(shù)初始化一個(gè)獨(dú)立鍵盤實(shí)例后,即可使用通用接口使用按鍵。其函數(shù)原型為:
其中,p_dev 為指向am_key_gpio_t 類型實(shí)例的指針,p_info 為指向am_key_gpio_info_t類型實(shí)例信息的指針。
1. 實(shí)例
定義am_key_gpio_t 類型(am_key_gpio.h)實(shí)例如下:
其中,g_key_gpio 為用戶自定義的實(shí)例,其地址作為p_dev 的實(shí)參傳遞。
2. 實(shí)例信息
實(shí)例信息主要描述與獨(dú)立鍵盤相關(guān)的信息,比如,使用的GPIO 引腳號(hào),獨(dú)立按鍵的個(gè)數(shù),以及對(duì)應(yīng)的按鍵編碼等信息。其類型am_key_gpio_info_t 的定義(am_key_gpio.h)如下:
其中,p_pins 指向存放各獨(dú)立按鍵對(duì)應(yīng)引腳號(hào)的數(shù)組,如在AM824-Core 開發(fā)板上,有一個(gè)多功能按鍵可以當(dāng)做獨(dú)立按鍵使用。當(dāng)J14 的1 和2 短接時(shí),KEY 與PIO_KEY(PIO0_1)連接,此時(shí),按鍵KEY 當(dāng)做獨(dú)立按鍵使用。基于此,可以定義一個(gè)存放引腳號(hào)的數(shù)組:
該數(shù)組的地址即可作為p_pins 的值。由于AM824 開發(fā)板只有一個(gè)獨(dú)立按鍵,因此數(shù)組僅有一個(gè)元素,其值為與該獨(dú)立按鍵連接的引腳號(hào),即PIO0_1。當(dāng)存在多個(gè)獨(dú)立按鍵時(shí),繼續(xù)在該數(shù)組后添加數(shù)據(jù)元素即可。同時(shí),由于引腳號(hào)在系統(tǒng)啟動(dòng)后不會(huì)修改,因此使用了const 修飾符。
為了區(qū)分各個(gè)按鍵,要求每個(gè)按鍵都具有一個(gè)唯一的編碼值,因此需要為獨(dú)立鍵盤中的各個(gè)按鍵指定一個(gè)編碼,p_codes 即指向存放各獨(dú)立按鍵對(duì)應(yīng)編碼的數(shù)組,其編碼與p_pins指向的數(shù)組中各個(gè)獨(dú)立按鍵一一對(duì)應(yīng)。比如,設(shè)置AM824ZB 開發(fā)板中的獨(dú)立按鍵對(duì)應(yīng)編碼為KEY_KP0,則可以定義如下數(shù)組:
該數(shù)組的地址即可作為p_codes 的值。在通用按鍵處理接口的程序范例中,使用了按鍵編碼KEY_F1 作為獨(dú)立按鍵的編碼,按鍵編碼KEY_F1 就是在這里配置的,如果需要使用其它按鍵編碼,直接修改即可。按鍵編碼可以是任意整數(shù)值,但建議使用類似KEY_KP0 這樣的標(biāo)準(zhǔn)按鍵編碼,其是在am_input_code.h 文件中定義的宏。
pin_num 指定了獨(dú)立鍵盤中獨(dú)立按鍵的個(gè)數(shù),其應(yīng)該與p_pins 和p_codes 指向的數(shù)組大小保持一致,在AM824-Core 開發(fā)板上只有一個(gè)獨(dú)立按鍵,因此該值為1。
對(duì)于獨(dú)立按鍵來講,不同的電路可能影響按鍵按下時(shí)的電平,為了讓驅(qū)動(dòng)準(zhǔn)確獲取這一信息,使用active_low 成員表明按鍵按下時(shí)的電平,若按鍵按下時(shí)為低電平,則該值為AM_TRUE,反之該值為AM_FALSE。查看相應(yīng)的原理圖可知,當(dāng)按鍵按下時(shí),GPIO 引腳為低電平,因此active_low 的值應(yīng)該設(shè)置為AM_TRUE。
scan_interval_ms 指定了按鍵掃描的時(shí)間間隔,即每隔該段時(shí)間執(zhí)行一次按鍵檢測(cè),檢測(cè)是否有按鍵事件發(fā)生(按鍵按下或按鍵釋放),通常將該值設(shè)置為10 ms。基于以上信息,實(shí)例信息定義如下:
基于實(shí)例和實(shí)例信息,即可完成獨(dú)立鍵盤的初始化。比如:
初始化完成后,即可使用通用鍵盤處理接口處理編碼為KEY_KP0 的按鍵。為了便于配置獨(dú)立鍵盤(修改實(shí)例信息)。基于模塊化編程思想,將初始化相關(guān)的實(shí)例和實(shí)例信息等的定義存放到獨(dú)立鍵盤的配置文件中,通過頭文件引出實(shí)例初始化函數(shù)接口,源文件和頭文件的程序范例分別詳見程序清單7.32 和程序清單7.33。
程序清單7.32 獨(dú)立鍵盤實(shí)例初始化函數(shù)實(shí)現(xiàn)(am_hwconf_key_gpio.c)
程序清單7.33 獨(dú)立鍵盤實(shí)例初始化函數(shù)聲明(am_hwconf_key_gpio.h)
后續(xù)只需要使用無參數(shù)的實(shí)例初始化函數(shù),即可完成獨(dú)立鍵盤實(shí)例的初始化:
初始化完成后,即可使用通用鍵盤處理接口處理編碼為KEY_KP0 的按鍵。
在AM824ZB 中,獨(dú)立鍵盤作為一種板載資源,在系統(tǒng)啟動(dòng)時(shí)已經(jīng)默認(rèn)進(jìn)行了獨(dú)立鍵盤的初始化操作,因此在程序清單7.30 所示的范例程序中,沒有調(diào)用獨(dú)立鍵盤實(shí)例初始化函數(shù)就可以使用板載的獨(dú)立按鍵。
若用戶不需要使用獨(dú)立按鍵,為了節(jié)省內(nèi)存空間,可以將am_prj_config.h 工程配置文件中的AM_CFG_KEY_GPIO_ENABLE 宏值修改為0,裁剪掉獨(dú)立鍵盤,該宏本質(zhì)上控制了板級(jí)初始化函數(shù)中的一段程序,詳見程序清單7.34。
程序清單7.34 在板級(jí)初始化中裁剪獨(dú)立鍵盤的原理
注:板級(jí)初始化函數(shù)在系統(tǒng)啟動(dòng)時(shí)自動(dòng)調(diào)用,初始化完畢后才會(huì)進(jìn)入應(yīng)用程序入口,即am_main()。
>>> 7.5.3 矩陣鍵盤驅(qū)動(dòng)
類似地,AMetal 矩陣按鍵的驅(qū)動(dòng)也提供了一個(gè)初始化函數(shù),使用該函數(shù)初始化一個(gè)矩陣鍵盤實(shí)例后,即可使用通用接口使用按鍵。其函數(shù)原型為:
其中的p_dev 為指向am_key_matrix_gpio_softimer_t 類型實(shí)例的指針,p_info 為指向am_key_matrix_gpio_softimer_info_t 類型實(shí)例信息的指針。
1. 實(shí)例
定義am_key_matrix_gpio_softimer_t 類型(am_key_matrix_gpio.h)實(shí)例如下:
其中,miniport_key 為用戶自定義的實(shí)例,其地址作為p_dev 的實(shí)參傳遞。
2. 實(shí)例信息
實(shí)例信息描述了與矩陣鍵盤相關(guān)的信息,其類型am_key_matrix_gpio_softimer_info_t 的定義(am_key_matrix_gpio.h)如下:
其中, key_matrix_gpio_info 成員包含了GPIO 驅(qū)動(dòng)型矩陣鍵盤的相關(guān)信息;scan_interval_ms 指定了按鍵掃描的時(shí)間間隔(單位:毫秒),即每隔該段時(shí)間執(zhí)行一次按鍵檢測(cè),檢測(cè)是否有按鍵事件發(fā)生(按鍵按下或按鍵釋放),該值一般設(shè)置為5 ms 即可。
key_matrix_gpio_info 類型am_key_matrix_gpio_info_t 定義(am_key_matrix_gpio.h)為:
其中,base_info 成員包含了矩陣鍵盤的基礎(chǔ)信息,如矩陣鍵盤的行數(shù)和列數(shù)、各按鍵對(duì)應(yīng)的編碼等。p_pins_row 指向存放矩陣鍵盤行線對(duì)應(yīng)引腳號(hào)的數(shù)組,p_pins_col 指向存放矩陣鍵盤列線對(duì)應(yīng)引腳號(hào)的數(shù)組。
若使用MiniPort-Key 與AM824-Core 相連接時(shí),KR0、KR1 為行線,分別與PIO0_6 和PIO0_7 連接,KL0、KL1 為列線,分別與PIO0_17 和PIO0_23 連接。定義行線引腳數(shù)組和列線引腳數(shù)組為:
兩個(gè)數(shù)組的地址可分別作為p_pins_row 和p_pins_col 的值。
base_info 成員的類型am_key_matrix_base_info_t 定義(am_key_matrix_base.h)如下:
其中,row 和col 分別表示矩陣鍵盤的行數(shù)目和列數(shù)目,若使用MiniPort-Key 矩陣鍵盤,其為2×2 的矩陣鍵盤,因此行數(shù)目和列數(shù)目均為2。
p_codes 指向存放矩陣鍵盤中各按鍵對(duì)應(yīng)編碼的數(shù)組,為了與硬件標(biāo)號(hào)一致,分配給各個(gè)按鍵的編碼依次為:KEY_0、KEY_1、KEY_2、KEY_3。則可以定義如下數(shù)組:
該數(shù)組的地址即可作為p_codes的值。active_low 表明按鍵按下是否為低電平,由電路的設(shè)計(jì)可知,行線外接了上拉電阻,配置為輸入模式時(shí)默認(rèn)會(huì)是高電平。因此,應(yīng)該使用低電平驅(qū)動(dòng)方式,列線輸出低電平,當(dāng)按鍵按下時(shí),就會(huì)檢測(cè)到低電平, 即該值應(yīng)為AM_TRUE。scan_mode 表示掃描方式,支持的方式有行掃描和列掃描方式,它們對(duì)應(yīng)的宏名詳見表7.6。如使用列掃描,則該值為AM_KEY_MATRIX_SCAN_MODE_COL。基于以
上信息,完整的實(shí)例信息可以定義如下:
表7.6 矩陣鍵盤掃描方式
基于實(shí)例和實(shí)例信息,即可完成MiniPort-Key 矩陣鍵盤的初始化。比如:
初始化完成后,即可使用通用鍵盤處理接口處理編碼為KEY_0~KEY_3 的按鍵。為了便于配置矩陣鍵盤(修改實(shí)例信息)。基于模塊化編程思想,將初始化相關(guān)的實(shí)例、實(shí)例信息等的定義存放到獨(dú)立鍵盤的配置文件中,通過頭文件引出實(shí)例初始化函數(shù)接口,源文件和頭文件的程序范例分別詳見程序清單7.35 和程序清單7.36。
程序清單7.35 矩陣鍵盤實(shí)例初始化函數(shù)實(shí)現(xiàn)(am_hwconf_miniport _key.c)
程序清單7.36 矩陣鍵盤實(shí)例初始化函數(shù)聲明(am_hwconf_miniport_key.h)
后續(xù)只需要使用無參數(shù)的實(shí)例初始化函數(shù),即可完成矩陣鍵盤實(shí)例的初始化:
當(dāng)完成初始化后,即可使用通用鍵盤處理接口處理編碼為KEY_0~KEY_3 的按鍵。在AM824-Core 中,矩陣鍵盤作為可選的配板資源,在系統(tǒng)啟動(dòng)時(shí)沒有像獨(dú)立鍵盤那樣默認(rèn)就執(zhí)行了初始化操作,因此如需使用矩陣鍵盤,則必須手動(dòng)調(diào)用矩陣鍵盤實(shí)例初始化函數(shù)。
基于按鍵通用接口編寫一個(gè)簡(jiǎn)易的應(yīng)用程序:當(dāng)有鍵按下時(shí),蜂鳴器在發(fā)出“嘀”的一聲的同時(shí),通過LED0 和LED1 的組合顯示按鍵編號(hào)。比如,當(dāng)KEY0 鍵按下時(shí),兩個(gè)LED燈均熄滅。當(dāng)KEY1 按下時(shí),則顯示01,即LED0 亮,LED1 熄滅,依此類推。將應(yīng)用程序存放在app_key_code_led_show.c 文件中,其接口聲明在app_key_code_led_show.h 文件中,詳見程序清單7.37 和程序清單7.38。
程序清單7.37 矩陣鍵盤應(yīng)用程序?qū)崿F(xiàn)(app_key_code_led_show.c)
程序清單7.38 矩陣鍵盤應(yīng)用程序接口聲明(app_key_code_led_show.h)
使用MiniPort-Key 的4 個(gè)按鍵展示此應(yīng)用程序的功能的主程序詳見程序清單7.39。
程序清單7.39 矩陣鍵盤應(yīng)用程序主程序
-
溫度傳感器
+關(guān)注
關(guān)注
48文章
2912瀏覽量
155888 -
接口
+關(guān)注
關(guān)注
33文章
8497瀏覽量
150834 -
周立功
+關(guān)注
關(guān)注
38文章
130瀏覽量
37584
原文標(biāo)題:周立功:面向通用接口的編程——溫度采集接口、鍵盤
文章出處:【微信號(hào):Zlgmcu7890,微信公眾號(hào):周立功單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論