6.1 通用LED接口
AWorks提供了操作LED的通用接口,詳見表6.1。
表6.1 通用LED接口(aw_led.h)
1. 設置LED的狀態(tài)
設置LED狀態(tài)的函數(shù)原型為:
其中,id為LED編號,系統(tǒng)為每個LED都分配了一個唯一ID,通常都是從0開始順序為各個LED編號。如有2個LED,則LED的編號為0~1。布爾類型on參數(shù)表明是否點亮LED,若其值為AW_TRUE,則表示點亮LED;若其值為AW_FALSE,則表示熄滅LED。
aw_bool_t類型是AWorks在aw_types.h文件中自定義的布爾類型,使用該類型定義的數(shù)據(jù),其值只能為真(AW_TRUE)或假(AW_FALSE)。
點亮編號為0的LED范例程序詳見程序清單6.1。
程序清單6.1 使用aw_led_set()點亮LED的范例程序
熄滅編號為0的LED范例程序詳見程序清單6.2。
程序清單6.2 使用aw_led_set()熄滅LED范例程序
函數(shù)的返回值表示本次操作的結(jié)果,其類型為aw_err_t,該類型在aw_errno.h文件中定義的一個有符號的整數(shù)類型。若接口返回值的類型為aw_err_t,則具有通用的含義:
-
若返回值為AW_OK(常量宏,值為0),則表示操作成功;
-
若返回值為負值,則表示操作失敗,失敗的原因通過返回值確定;
-
若返回值為正數(shù),則具體含義由接口定義,無特殊說明時,表明不會返回正數(shù)。
實際上AW_OK是在aw_common.h文件中定義的常量宏,其值為0,定義如下:
當返回負值時,則表示操作失敗,具體失敗的原因可根據(jù)返回值查找aw_errno.h文件中定義的錯誤號,通過錯誤號的含義即可確定失敗的原因,詳見表6.2。
表6.2 常見錯誤號的含義(aw_errno.h)
假設硬件只有兩個LED,其操作編號為100的LED,由于LED不存在,將返回-AW_ENODEV,表示設備不存在。注意:AW_ENODEV的前面有一個負號,操作無效ID的范例程序詳見程序清單6.3。
程序清單6.3 操作無效ID的范例程序
通常操作LED,只要LED編號是有效的,這操作均會成功,其返回值為AW_OK。
2. 點亮LED
點亮LED的函數(shù)原型為:
其中,id為LED編號,函數(shù)的返回值為標準錯誤號,點亮編號為0的LED范例程序詳見程序清單6.4。
程序清單6.4 aw_led_on()范例程序
3. 熄滅LED
熄滅LED的函數(shù)原型為:
其中,id為LED編號,函數(shù)的返回值為標準錯誤號,熄滅編號為0的LED范例程序詳見程序清單6.5。
程序清單6.5 aw_led_off()范例程序
4. 翻轉(zhuǎn)LED的狀態(tài)
翻轉(zhuǎn)LED的狀態(tài)就是使LED由點亮狀態(tài)轉(zhuǎn)變?yōu)橄鐮顟B(tài)或由熄滅狀態(tài)轉(zhuǎn)變?yōu)辄c亮狀態(tài),其函數(shù)原型為:
其中,id為LED編號,函數(shù)的返回值為標準錯誤號,通過翻轉(zhuǎn)LED狀態(tài)的接口可以實現(xiàn)LED閃爍,其范例程序詳見程序清單6.6。
程序清單6.6 aw_led_toggle()范例程序
為了展示接口的使用方法,該程序使用了3種方式實現(xiàn)LED的閃爍,詳見程序清單6.7。
程序清單6.7 LED閃爍范例程序
6.2 通用鍵盤接口
AWorks實現(xiàn)了一個輸入子系統(tǒng)架構(gòu),可以統(tǒng)一管理按鍵、鼠標、觸摸屏等外部輸入事件。這里以使用按鍵為例,講述輸入系統(tǒng)的使用方法。
對于鍵盤,無論是獨立鍵盤、矩陣鍵盤還是外接的外圍鍵盤管理芯片(如ZLG72128),均可以使用輸入系統(tǒng)進行管理。
對于用戶來講,要使用按鍵,即需要對外部輸入的按鍵事件進行處理,為此,需要向系統(tǒng)中注冊一個輸入事件處理器,該處理器中,包含了用戶自定義的事件處理函數(shù),當有按鍵事件發(fā)生時,系統(tǒng)將自動回調(diào)事件處理器中的用戶函數(shù)。
AWorks提供了注冊輸入事件處理器的接口,其函數(shù)原型為:
其中,p_input_handler為指向輸入事件處理器的指針,pfn_cb為指向用戶自定義的輸入事件處理函數(shù)的指針,p_usr_data為按鍵處理函數(shù)的用戶參數(shù)。當輸入事件發(fā)生時,系統(tǒng)會回調(diào)pfn_cb指向的用戶處理函數(shù),并將p_usr_data作為參數(shù)傳遞給用戶處理函數(shù)。
1. 輸入事件處理器
p_input_handler指向輸入事件處理器,其類型為:aw_input_handler_t,在
aw_input.h文件中定義,用戶無需關心該類型的具體定義,僅需使用該類型定義一個輸入事件處理器的實例。即:
其中,key_handler為用戶自定義的輸入事件處理器,其地址可以作為p_input_handler的實參傳遞。
2. 用戶自定義事件處理函數(shù)
pfn_cb指向用戶自定義的輸入事件處理函數(shù),其類型aw_input_cb_t為事件處理函數(shù)的類型,其在aw_input.h文件中定義如下:
當輸入事件發(fā)生時,無論是按鍵事件,還是其它坐標事件,比如:鼠標、觸摸屏等。均會調(diào)用pfn_cb指針指向的函數(shù),當該函數(shù)被調(diào)用時,p_input_data為輸入事件相關的數(shù)據(jù),包含事件類型(區(qū)分按鍵事件或坐標事件,比如:鼠標、觸摸屏等)、按鍵編碼、坐標等信息,用戶可以根據(jù)這些數(shù)據(jù)作出相應的處理動作。p_usr_data為用戶自定義的參數(shù),其值與注冊事件處理器時傳遞的p_usr_data參數(shù)一致,若不使用該參數(shù),則可以在注冊事件處理器時,將p_usr_data參數(shù)的值設置為NULL。
p_input_data的類型為aw_input_event_t指針類型,該類型在aw_input.h文件中定義如下:
其本質(zhì)上是一個結(jié)構(gòu)體類型,僅包含一個數(shù)據(jù)成員,用于表示事件的類型,若為按鍵事件,則該值為AW_INPUT_EV_KEY;若為絕對事件(比如,觸摸屏),則該值為AW_INPUT_EV_ABS。
若p_input_data指向的數(shù)據(jù)中,ev_type的值為AW_INPUT_EV_KEY,則表示其指向的數(shù)據(jù)本質(zhì)上是一個完整的按鍵事件數(shù)據(jù),其類型為aw_input_key_data_t,該類型在aw_input.h文件中定義如下:
該類型的第一個數(shù)據(jù)成員為input_ev,其中包含了事件的具體類型。也正因為其第一個數(shù)據(jù)成員的類型為aw_input_event_t,系統(tǒng)才可以在回調(diào)用戶自定義的函數(shù)時,將aw_input_key_data_t類型的指針轉(zhuǎn)換為指向aw_input_event_t類型的指針使用。
key_code為按鍵編碼,用于區(qū)分系統(tǒng)中多個不同的按鍵。例如,系統(tǒng)中存在4個按鍵,則各個按鍵對應的編碼可能分別為:KEY_0、KEY_1、KEY_2、KEY_3。這些編碼都是在aw_input_code.h文件中使用宏的形式定義的。
key_state表示本次按鍵事件具體對應的按鍵狀態(tài),用以區(qū)分按鍵事件是按下事件還是釋放事件。若該值不為0,則表示按鍵按下;否則,表示按鍵釋放。
基于此,為了獲取到更多的按鍵相關信息,比如:按鍵編碼、按鍵狀態(tài)(按下還是釋放)等??梢詫_input_data強制轉(zhuǎn)換為aw_input_key_data_t指針類型使用,詳見程序清單6.8。
程序清單6.8 根據(jù)輸入事件的類型使用數(shù)據(jù)
實際上,不同類型的輸入事件,其需要包含的數(shù)據(jù)是不同的,例如,對于觸摸屏事件,則需要包含橫坐標和縱坐標。為了統(tǒng)一各種不同類型的事件處理函數(shù)類型,將aw_input_event_t類型的數(shù)據(jù)作為所有事件實際數(shù)據(jù)類型的第一個成員。這樣,可以統(tǒng)一使用aw_input_event_t類型的指針指向?qū)嶋H的數(shù)據(jù),以此統(tǒng)一事件處理函數(shù)的類型,用戶在事件處理函數(shù)中,通過查看事件類型,即可進一步將該指針強制轉(zhuǎn)換為指向?qū)嶋H數(shù)據(jù)類型的指針,使用其中更多的信息。
如圖6.1所示的類圖表示了這種關系,實際數(shù)據(jù)類型均是從基類派生而來的,aw_input_prt_data_t是指針型輸入事件,比如觸摸屏觸摸事件等,其包含了具體坐標信息。
圖6.1 各種類型的輸入事件對應的實際數(shù)據(jù)類圖
例如,使用一個按鍵(按鍵編碼為KEY_0)控制LED0,當按鍵按下時,則LED0點亮;當按鍵釋放后,則LED0熄滅,相應的按鍵處理函數(shù)詳見程序清單6.9。
程序清單6.9 按鍵處理函數(shù)范例程序
完成按鍵處理函數(shù)的定義后,函數(shù)名可作為參數(shù)傳遞給aw_input_handler_register()函數(shù)的pfn_cb形參。綜合范例程序詳見程序清單6.10。
程序清單6.10 注冊事件處理器范例程序
注冊按鍵處理器后,當按鍵按下或釋放時,均會調(diào)用注冊按鍵處理器時指定的回調(diào)函數(shù),即程序清單6.10中的__key_process()函數(shù)。
若系統(tǒng)中存在多個按鍵,且各個按鍵的處理動作毫不相關,為了分離各個按鍵的處理代碼,可以注冊多個按鍵事件處理器,每個處理器負責處理一個或多個按鍵,范例程序詳見程序清單6.11。
程序清單6.11 注冊多個按鍵處理器范例程序
6.3 通用蜂鳴器接口
AWorks提供了操作蜂鳴器的通用接口,詳見表6.3。
表6.3 通用蜂鳴器接口(aw_buzzer.h)
1. 設置蜂鳴器的響度
該函數(shù)用于設置蜂鳴器鳴叫的響度,即控制蜂鳴器發(fā)聲的音量。其函數(shù)原型為:
beep_level即為鳴叫的響度,其值被量化為百分比,有效值為0 ~ 100。為0時表示靜音,為100時表示聲音最大。設置響度為80%的范例程序詳見程序清單6.12。
程序清單6.12 aw_buzzer_loud_set()范例程序
該接口僅用于設置蜂鳴器的響度,并不會使蜂鳴器立即發(fā)聲,必須調(diào)用aw_buzzer_on()或aw_buzzer_beep()接口,才能使蜂鳴器發(fā)聲。默認情況下,響度為0,因此,在調(diào)用相關接口使蜂鳴器鳴叫前,必須正確設置響度。
特別地,部分硬件不支持響度設置,響度是固定的,這種情況下,調(diào)用該接口是無效的,返回值為-AW_ENOTSUP(錯誤號,表示不支持)。
2. 打開蜂鳴器
打開蜂鳴器的函數(shù)原型為:
打開蜂鳴器,使蜂鳴器開始鳴叫的范例程序詳見程序清單6.13。
程序清單6.13 aw_buzzer_on()范例程序
打開蜂鳴器后,蜂鳴器開始鳴叫,若響度為0,將聽不到聲音。
3. 關閉蜂鳴器
關閉蜂鳴器的函數(shù)原型為:
關閉蜂鳴器,使蜂鳴器停止鳴叫的范例程序詳見程序清單6.14。
程序清單6.14 aw_buzzer_off()范例程序
4. 蜂鳴器鳴叫指定時間(同步)
該函數(shù)用于打開蜂鳴器,使蜂鳴器鳴叫指定時間后自動關閉,該函數(shù)會一直等到蜂鳴器鳴叫結(jié)束后返回。其函數(shù)原型為:
使蜂鳴器鳴叫50毫秒(“嘀”一聲)的范例程序詳見程序清單6.15。
程序清單6.15 aw_buzzer_beep()范例程序
注意,由于該函數(shù)會一直等到蜂鳴器鳴叫結(jié)束后才會返回,因此主程序調(diào)用該函數(shù)后,會阻塞50ms。
5.蜂鳴器鳴叫指定時間(異步)
該函數(shù)用于打開蜂鳴器,使蜂鳴器鳴叫指定時間后自動關閉,與aw_buzzer_beep()函數(shù)不同的是,該函數(shù)會立即返回,不會等待蜂鳴器鳴叫結(jié)束。其函數(shù)原型為:
使蜂鳴器鳴叫50毫秒(“嘀”一聲)的范例程序詳見程序清單6.16。
程序清單6.16 aw_buzzer_beep_async()范例程序
注意,由于該函數(shù)不會等待蜂鳴器鳴叫結(jié)束,因此,當調(diào)用該函數(shù)后,會立即返回,不會被阻塞。這是其與aw_buzzer_beep()接口的本質(zhì)區(qū)別。
基于蜂鳴器通用接口,可以編寫一個簡易測試程序,按鍵按下,蜂鳴器鳴叫;按鍵釋放,蜂鳴器停止鳴叫。范例程序詳見程序清單6.17。
程序清單6.17 蜂鳴器使用范例程序
基于此,若需要實現(xiàn)一個按鍵按下,蜂鳴器“嘀”一聲的效果,按照上述示例,可以簡單修改事件處理函數(shù),使用aw_buzzer_beep()函數(shù)實現(xiàn)“嘀”一聲的效果,范例程序詳見程序清單6.18.
程序清單6.18 事件處理函數(shù)修改(1)
實際測試會發(fā)現(xiàn),上述程序并不能正常工作,不能觀察到預期的現(xiàn)象。這是由于aw_buzzer_beep()函數(shù)會阻塞調(diào)用者一定的時間,而按鍵事件回調(diào)函數(shù)是在中斷環(huán)境中運行的,中斷上下文不能被阻塞,因此,aw_buzzer_beep()接口不能夠直接在按鍵事件回調(diào)函數(shù)中使用。為了實現(xiàn)該應用,可以使用不阻塞的蜂鳴器鳴叫接口aw_buzzer_beep_async()替代,范例程序詳見程序清單6.19。
程序清單6.19 事件處理函數(shù)修改(2)
6.4 通用數(shù)碼管接口
AWorks提供了操作數(shù)碼管的通用接口,詳見表6.4。
表6.4 通用數(shù)碼管接口(aw_digitron_disp.h)
1. 設置段碼解碼函數(shù)
數(shù)碼管的各個段可以組合顯示出多種圖形,使用該函數(shù)可以自定義字符的解碼函數(shù),其函數(shù)原型為:
其中,id表示設置數(shù)碼管顯示器的編號,這里的id指的是顯示器的編號,而不是數(shù)碼管的位索引,一個數(shù)碼管顯示器可以包含多位數(shù)碼管,比如,MiniPort-View顯示器,其包含兩位數(shù)碼管。系統(tǒng)中的數(shù)碼管顯示器通常從0開始編號,例如,系統(tǒng)中共計有3個數(shù)碼管顯示器,則id為0 ~ 2。絕大部分情況下,系統(tǒng)中僅有一個數(shù)碼管顯示器,此時,其id為0。
pfn_decode為函數(shù)指針,其指向的函數(shù)即為設置的解碼函數(shù),解碼函數(shù)的參數(shù)為uint16_t類型的字符,返回值為uint16_t類型的編碼。
實際應用中,對于8段數(shù)碼管,字符'0' ~ '9'等都是有默認編碼的,為此,AWorks提供了默認的8段數(shù)碼管解碼函數(shù),可以支持常見的字符'0' ~ '9'以及 'A' 、'B'、 'C' 、'D'、 'E'、 'F'等字符的解碼。其在aw_digitron_disp.h文件中聲明:
如無特殊需求,可以直接將該函數(shù)作為相應數(shù)碼管顯示器的字符解碼函數(shù),將該函數(shù)作為pfn_decode的實參傳遞,范例程序詳見程序清單6.20。
程序清單6.20 aw_digitron_disp_decode_set()范例程序
若由于應用特殊需求,要求字符使用自定義的特殊編碼,例如,要使字符'O'的編碼為 0xFC,則可以自定義如下解碼函數(shù):
然后將該函數(shù)作為pfn_decode的實參傳遞即可:
注意,對于一個數(shù)碼管顯示器,只能設置一個解碼函數(shù)。
2. 設置數(shù)碼管閃爍
該函數(shù)可以指定數(shù)碼管顯示器的某一位數(shù)碼管閃爍,其函數(shù)原型為:
其中,id為數(shù)碼管顯示器編號;index為數(shù)碼管索引,當一個數(shù)碼管顯示器存在多位數(shù)碼管時,使用index參數(shù)指定具體操作的數(shù)碼管的位置。如MiniPort-View有兩位數(shù)碼管,則兩個數(shù)碼管的索引分別為0和1;blink表示該位是否閃爍,若其值為AW_TRUE,則閃爍,反之,則不閃爍,默認情況下,所有數(shù)碼管均處于未閃爍狀態(tài)。如設置1號數(shù)碼管閃爍的范例程序詳見程序清單6.21。
程序清單6.21 aw_digitron_disp_blink_set()范例程序
3. 顯示指定的段碼圖形
該函數(shù)用于不經(jīng)過解碼函數(shù)解碼,直接顯示段碼指定的圖形,可以靈活的顯示任意特殊圖形,其函數(shù)原型為:
其中,id為數(shù)碼管顯示器編號;index為數(shù)碼管索引;seg為顯示的段碼。如在8段數(shù)碼管上顯示字符'-',即需要g段點亮,對應的段碼為0x02(即:0000 0010),范例程序詳見程序清單6.22。
程序清單6.22 aw_digitron_disp_at()范例程序
4. 顯示單個字符
該函數(shù)用于在指定位置顯示一個字符,字符經(jīng)過解碼函數(shù)解碼后顯示,若解碼函數(shù)不支持該字符,則不顯示任何內(nèi)容,其函數(shù)原型為:
其中,id為數(shù)碼管顯示器編號,index為數(shù)碼管索引,ch為顯示的字符。比如,顯示字符'H'的范例程序詳見程序清單6.23。
程序清單6.23 aw_digitron_disp_char_at()范例程序
5. 顯示字符串
該函數(shù)用于從指定位置開始顯示一個字符串,其函數(shù)原型為:
其中,id為數(shù)碼管顯示器編號,index為顯示字符串的數(shù)碼管起始索引,即從該索引指定的數(shù)碼管開始顯示字符串,len指定顯示的長度,p_str指向需要顯示的字符串。
實際顯示的長度是len和字符串長度的較小值,若數(shù)碼管位數(shù)不夠,則多余字符不顯示。
如顯示字符"HELLO"的范例程序詳見程序清單6.24。
程序清單6.24 aw_digitron_disp_str()范例程序
若使用的是MiniPort-View,由于只存在兩個數(shù)碼管,因此最終只會顯示"HE"。
通常情況下,需要顯示一些數(shù)字,如顯示變量的值,此時,可以先將變量通過格式化字符串函數(shù)輸出到字符串緩沖區(qū)中,然后再使用aw_digitron_disp_str()函數(shù)顯示該字符串。比如,顯示一個變量i的值,范例程序詳見程序清單6.25。
程序清單6.25 使用aw_digitron_disp_str()顯示整數(shù)變量值的范例程序
其中,aw_snprintf()與標準C函數(shù)snprintf()函數(shù)功能相同,均用于格式化字符串到指定的緩沖區(qū)中,其函數(shù)原型為(aw_vdebug.h):
其與aw_kprintf()函數(shù)的區(qū)別是,aw_kprintf()將信息直接通過調(diào)試串口打印輸出,而aw_snprintf()函數(shù)將信息輸出到大小為sz的buf緩沖區(qū)中。
6. 顯示清屏
該函數(shù)用于顯示清屏,清除數(shù)碼管顯示器中的所有內(nèi)容,其函數(shù)原型為:
其中,id為數(shù)碼管顯示器編號,范例程序詳見程序清單6.26。
程序清單6.26 aw_digitron_disp_clr()范例程序
7. 使能數(shù)碼管顯示
數(shù)碼管默認是處于使能狀態(tài)的,只有當被禁能后,才需要使用該函數(shù)重新使能。數(shù)碼管僅在使能狀態(tài)下才可以正常顯示。
該函數(shù)用于顯示清屏,清除數(shù)碼管顯示器中的所有內(nèi)容,其函數(shù)原型為:
其中,id為數(shù)碼管顯示器編號,范例程序詳見程序清單6.27。
程序清單6.27 aw_digitron_disp_enable()范例程序
8. 禁能數(shù)碼管實現(xiàn)
數(shù)碼管默認處于使能狀態(tài),可以正常顯示。清屏狀態(tài)下只是清空了數(shù)碼管顯示的內(nèi)容,數(shù)碼管實際上還是處于工作狀態(tài),對于動態(tài)掃描類數(shù)碼管,依然處于動態(tài)掃描狀態(tài),需要消耗CPU資源。若長時間不使用數(shù)碼管顯示器,可以徹底關閉數(shù)碼管顯示器,關閉數(shù)碼管掃描,節(jié)省CPU資源,甚至是關閉數(shù)碼管的電源,降低系統(tǒng)功耗。關閉數(shù)碼管顯示器的函數(shù)原型為:
其中,id為數(shù)碼管顯示器編號,范例程序詳見程序清單6.28。
程序清單6.28 aw_digitron_disp_disable()范例程序
數(shù)碼管被禁能后,將不能再正常顯示,若需正常顯示,必須使用aw_digitron_disp_enable()接口重新使能數(shù)碼管。
基于數(shù)碼管通用接口,可以編寫一個簡易的60s倒計時程序,當?shù)褂嫊r還剩5s時,數(shù)碼管閃爍。范例程序詳見程序清單6.29。
程序清單6.29 倒計時應用程序?qū)崿F(xiàn)
程序中,將應用程序使用的數(shù)碼管顯示器編號使用宏__DIGITRON_ID進行了定義,若一個系統(tǒng)中存在多個數(shù)碼管顯示器,則僅需修改該宏對應的宏值,就可以使該倒計時應用程序在不同的數(shù)碼管顯示器上運行。
6.5 通用傳感器接口
AWorks提供了通用的傳感器接口,適用于各式各樣的傳感器,例如,溫度、濕度、電壓、電流、壓強、加速度、角速度、光照傳感器等等。
在一個系統(tǒng)中,可能存在多種類型的傳感器,例如,溫度、濕度、電流、壓強等。同時,還可能存在多個同種類型的傳感器,例如,可能連接10個溫度傳感器以測試10個溫度檢測點的溫度。此外,部分傳感器可以采集多路信號,例如,溫濕度傳感器SHT11可以同時采集溫度和濕度。
為了實現(xiàn)對各式各樣的傳感器進行統(tǒng)一管理,在AWorks中,定義了“傳感器通道”的抽象概念,一個傳感器通道用于完成一路物理信號的采集。對于只能采集單一信號的傳感器,每個傳感器只能為系統(tǒng)提供一路傳感器通道,例如,LM75溫度傳感器僅能采集一路溫度信號;對于可以采集多路信號的傳感器,則每個傳感器可以為系統(tǒng)提供多路傳感器通道,例如,SHT11可以同時采集溫度和濕度,其可以為系統(tǒng)提供一路溫度傳感器通道和一路濕度傳感器通道。此外,也可能存在多個相同的傳感器,以便為系統(tǒng)提供多個同類型的的傳感器通道。
如此一來,一個系統(tǒng)中可能存在多個傳感器通道,為了區(qū)分各個傳感器通道,在AWorks中,為每個傳感器通道分配了一個唯一 id。例如,某一系統(tǒng)中存在溫度、加速度、角速度等多種傳感器,各傳感器通道對應的id分配范例詳見表6.5。
表6.5 傳感器通道id分配(僅作示意)
實際中,id 與具體硬件平臺相關,用戶應查看SDK中的用戶手冊,獲知系統(tǒng)中可用的傳感器通道資源,以正確使用各個傳感器通道。
對于應用程序來講,僅需通過id使用各個傳感器通道即可,無需關心這些通道具體是由哪個傳感器提供的。例如,某一應用需要采集一路溫度和一路濕度,底層硬件可以是一個SHT11溫濕度傳感器,也可以是一個溫度傳感器和一個濕度傳感器。
常用的傳感器接口詳見表6.6。
表6.6 通用傳感器接口(aw_sensor.h)
1. 獲取傳感器通道類型
傳感器通道有類型之分,不同的類型的傳感器通道采集的物理信號不同,不同物理信號具有不同的基本單位不同。例如,電壓的基本單位為伏特(V);電流的基本單位為安培(A);溫度的基本單位為℃。為便于使用,在AWorks中,將傳感器類型使用宏的形式進行了定義,常用的傳感器類型詳見表6.7。
表6.7 常用的傳感器類型定義(aw_sensor.h)
在AWorks中,提供了獲取傳感器通道類型的接口,其函數(shù)原型為:
其中,id為傳感器通道的編號。若函數(shù)返回值為非負數(shù)(>=0),則表示獲取傳感器類型成功,此時,返回值即為以AW_SENSOR_TYPE_ 為前綴的宏值;否則,表示獲取傳感器類型失敗,此時,返回值為標準錯誤碼,表示了獲取類型失敗的原因。例如,返回值為-AW_ENODEV時,表示id對應的傳感器通道不存在,沒有與之對應的傳感器設備。例如,判斷通道0是否為溫度傳感器的范例程序詳見程序清單6.30。
程序清單6.30 獲取傳感器通道類型的范例程序
2. 使能傳感器通道
在AWorks中,使用一個傳感器通道采集數(shù)據(jù)的一般流程為:
(1)使能通道;
(2)獲取數(shù)據(jù)(可以多次獲?。?/p>
(3)禁能通道,不再使用時可以禁能通道,以使傳感器進入最佳的低功耗狀態(tài)(若支持)。
AWorks為每一個步驟都提供了兩類接口:一類接口用于操作單個傳感器通道,該類接口適用于僅使用單個傳感器通道的應用程序;一類接口用于操作一組(多個)傳感器通道,該類接口適用于需要使用多個傳感器通道的應用程序。當應用需要使用多個傳感器通道時,建議使用操作一組(多個)傳感器通道的接口,而不是多次使用操作單個傳感器通道的接口,后者效率較低,影響系統(tǒng)性能。
在獲取數(shù)據(jù)前,必須使能傳感器通道,AWorks提供了兩類接口,分別用于使能單個傳感器通道和使能一組(多個)傳感器通道。
-
使能單個傳感器通道
使能單個傳感器通道的函數(shù)原型為:
其中,id為傳感器通道的編號。若函數(shù)返回值為AW_OK,則表示通道使能成功;否則,表示通道使能失敗,返回值為標準錯誤碼,可以據(jù)此判定失敗的原因。例如,返回值為-AW_ENODEV時,表示id對應的傳感器通道不存在。例如,使能通道0的范例程序詳見程序清單6.31。
程序清單6.31 使能單個傳感器通道的范例程序
-
使能一組(多個)傳感器通道
使能一組(多個)傳感器通道的函數(shù)原型為:
其中,p_ids為指向傳感器通道id列表的指針;num表示通道的數(shù)目,即id列表的大?。籶_result指向用于存儲各個通道使能結(jié)果的緩存,緩存大小應該與num一致。其類型aw_sensor_val_t 為傳感器數(shù)據(jù)類型,其詳細定義詳見程序清單6.32。
程序清單6.32 aw_sensor_val_t類型定義(aw_sensor.h)
該類型的本意是表示一個傳感器數(shù)據(jù),如電壓、電流、溫度等,當表示一個傳感器數(shù)據(jù)時,val和unit都有著特殊的含義,具體含義將在數(shù)據(jù)獲取接口中詳細介紹。當該類型使用于此時,unit的值無效,僅使用val值表示各個通道使能的結(jié)果,此時,val值即為標準錯誤碼,若其值為AW_OK,則表示相應的通道使能成功;否則,表示相應的通道使能失敗,例如,值為-AW_ENODEV時,表示對應通道不存在。
aw_sensor_group_enable()函數(shù)的返回值同樣為標準錯誤碼,若其值為AW_OK,則表示所有通道使能成功,此時,p_result中所有數(shù)據(jù)的val值均為AW_OK,因此,當返回值為AW_OK時,無需判斷p_result中的值即可斷定所有通道使能成功;否則,表示存在使能失敗的通道,此時,可以逐一檢查p_result中的值來判斷具體哪些通道使能成功,哪些通道使能失敗。使能一組通道(通道0、3、5、6、8、9)的范例程序詳見程序清單6.33。
程序清單6.33 使能一組(多個)傳感器通道的范例程序
3. 獲取傳感器數(shù)據(jù)
通道使能后,可以獲取傳感器中的數(shù)據(jù), AWorks提供了兩類接口,分別用于獲取單個傳感器通道的數(shù)據(jù)和獲取一組(多個)傳感器通道的數(shù)據(jù)。
-
獲取單個傳感器通道的數(shù)據(jù)
該函數(shù)用于獲取單個傳感器通道的數(shù)據(jù),其函數(shù)原型為:
其中,id為傳感器通道的編號,p_val為輸出參數(shù),用以返回獲取到的傳感器值。函數(shù)返回值為標準錯誤碼,若其值為AW_OK,則表示數(shù)據(jù)獲取成功;否則,表示數(shù)據(jù)獲取失敗。
aw_sensor_val_t表示傳感器數(shù)據(jù)類型,回顧(首次定義詳見程序清單6.32)其定義如下:
其中,val為傳感器數(shù)值,unit表示了數(shù)據(jù)單位。
例如:
"M"(106,“兆”)、"k"(103,“千”),"m"(10-6,“毫”)等等,unit使用10的冪進行表示,例如,單位為"m",則unit的值為-3。
為了規(guī)范unit的使用,unit不可以為任意值,AWorks根據(jù)國際單位制(SI)定義的詞頭(比如:"m"、"μ"、"p"、"n"等等)對其可用取值進行了定義,詳見表6.8。
表6.8 uint可用取值
表中的最后一列即為unit的值,其值表示了10的冪,比如,-9表示的是10-9。單位符號區(qū)分大小寫,例如,"m"表示“毫”,對應10-3;而"M"表示“兆”,對應106。英文前綴表示在英文單詞中,通常可以在計量單位的單詞前增加該前綴形成新的單詞,例如,長度單位米的英文單詞為:meter;而千米對應的單詞為:kilometer,這里列出英文單詞前綴,可以方便讀者理解宏值和單位符號的定義。中文讀音為該單位符號的一般讀法,括號內(nèi)的字在不致混淆的情況下可以省略(通常均省略)。
傳感器val值的實際單位為將表中所示“單位符號”作為基本單位(基本單位與傳感器類型相關,詳見表6.7)的前綴形成的單位。例如,電壓傳感器的基本單位為V,若一個電壓傳感器數(shù)據(jù)的val為1234,unit為AW_SENSOR_UNIT_MILLI(即:-3),由于-3對應的單位符號為"m",因此,該傳感器數(shù)據(jù)的單位為"mV",對應的電壓值即為1234mV。
如需將傳感器數(shù)據(jù)的單位轉(zhuǎn)換為基本單位,可以使用如下公式:
data值的數(shù)據(jù)單位即為基本單位,比如,安培(A)、伏特(V)等。
使用一個“整數(shù)”和一個“單位”來對傳感器數(shù)據(jù)進行表示,可以有效的避免使用浮點數(shù)(為了保證系統(tǒng)性能,AWorks內(nèi)部不直接使用浮點數(shù),當然,應用程序依然可以使用浮點數(shù))。
例如,電壓傳感器采集到的電壓可能為1.234V,為了避免使用小數(shù),可以縮小單位至mV("m"表示“毫”,10-3),此時,1.234V即可表示為1234mV。若使用aw_sensor_val_t類型的數(shù)據(jù)表示該電壓值,則val值為1234,unit為-3(表示10-3,對應了單位前綴:"m",即“毫”)。
由此可見, unit為負數(shù)時可以表示一個小數(shù)。此外,val值的類型為有符號32位整數(shù),其可以表示的數(shù)據(jù)范圍為:-2147483648 ~ 2147483647。若數(shù)據(jù)超過該范圍,則也可以將unit設置為正數(shù),例如,若傳感器數(shù)據(jù)為2147483647000,則可以將val的值設置為2147483647,unit的值設置為AW_SENSOR_UNIT_KILO(即:3,表示103,對應了符號:"k",即“千”)。
假設傳感器通道0為一個溫度傳感器通道,則獲取溫度的范例程序詳見程序清單6.34。
程序清單6.34 獲取單通道傳感器數(shù)據(jù)的范例程序
其中,pow()函數(shù)為標準C庫提供的數(shù)學運算函數(shù)(在math.h文件中聲明),用于求取一個數(shù)的冪,其函數(shù)原型為:
其返回值即為x的y次方,即:xy。該函數(shù)的操作數(shù)均為double類型的雙精度浮點數(shù),運算效率較低。通常情況下,如非必要,都不建議引入浮點運算。例如,一個傳感器數(shù)據(jù)僅僅只需要打印顯示,則不需要將其轉(zhuǎn)換為浮點數(shù),僅需將小數(shù)點顯示至合適的位置即可。例如,對于一個溫度傳感器數(shù)據(jù),若其unit為-3,則以基本單位℃為單位進行數(shù)值的打印顯示時,應顯示3位小數(shù),比如,45087應顯示為45.087℃,基于此,分別顯示整數(shù)部分和小數(shù)部分即可:
程序中,將val值整除1000作為了整數(shù)部分,對1000取余作為了小數(shù)部分(打印小數(shù)部分時,位寬固定為3位,且不足3位時,應在前面補0,比如45087對1000取余的結(jié)果為87,但應顯示為"087")。
由此可見,打印顯示時,完全可以避免浮點運算。需要注意的是,unit的值不一定為-3,也可能為-6或其它值。這種情況下,就要分別處理,例如,為-6時,應打印顯示6位小數(shù):
顯然,這樣處理起來略顯復雜,需要分別為不同的unit值打印不同的小數(shù)位數(shù)。但在實際應用中,顯示的小數(shù)位數(shù)往往是固定的,其通常由實際顯示器(比如:數(shù)碼管位數(shù),顯示器位寬等)或具體應用需求決定,不難想象,如果一個顯示器一會兒顯示3位小數(shù),一會兒顯示6位小數(shù),用戶體驗將很難得到保證。
如果應用需要將顯示的小數(shù)位數(shù)固定為3,那么當unit為-6時,可以將unit轉(zhuǎn)換為-3后再按照3位小數(shù)進行顯示,例如:
程序中,首先將unit的值增加了3,即表示將數(shù)據(jù)擴大了103,即1000倍。為了使數(shù)據(jù)保持不變,需要將val值縮小1000倍。如此一來,temp_val中的unit值又變?yōu)?3了,而后即可按照3位小數(shù)進行打印顯示。由于val值整除了1000,那么原來低三位的數(shù)據(jù)均會丟失,也就意味著,精度會存在損失,實際上, 6位小數(shù)僅顯示3位,本身就是一種精度的舍棄。例如,原val值為25234167,unit為-6,表示了25.234167℃。經(jīng)過轉(zhuǎn)換后,val值為25234,unit為-3,表示了25.234℃,即完成了由6位小數(shù)精度到3位小數(shù)精度的轉(zhuǎn)換。
如果一個系統(tǒng)中固定溫度顯示的精度為3位小數(shù),那么可以將所有溫度數(shù)據(jù)的unit轉(zhuǎn)換為-3。為便于用戶使用,AWorks提供了傳感器數(shù)據(jù)單位轉(zhuǎn)換函數(shù),其轉(zhuǎn)換原理如下。
若是擴大單位(增加unit的值),假定unit增加的值為n,則會將val的值整除10n,由于存在整除,將會使原val值的精度減小。精度減小時,遵循四舍五入法則。例如,原數(shù)據(jù)為1860mV,若將單位轉(zhuǎn)換為V,則轉(zhuǎn)換的結(jié)果為2V;原數(shù)據(jù)為1245mV,若將單位轉(zhuǎn)換為V,則轉(zhuǎn)換的結(jié)果為1V。由于存在精度的損失,單位的擴大應該謹慎使用。
若是縮小單位(減小unit的值),假定unit減小的值為n,則會將val的值乘以10n,但應特別注意,val值的類型為32位有符號數(shù),其能夠表示的數(shù)據(jù)范圍為:-2147483648 ~ 2147483647。不應使val值擴大10n后超過該范圍??s小單位不存在精度的損失,但應注意數(shù)據(jù)的溢出,不應將一個數(shù)據(jù)縮小至太小的單位。若數(shù)據(jù)可能溢出,則轉(zhuǎn)換會失敗,原數(shù)據(jù)的值和單位均會保持不變。
特別地,若轉(zhuǎn)換前后的單位沒有發(fā)生變化,則整個傳感器的值保持不變。
傳感器數(shù)據(jù)單位轉(zhuǎn)換的函數(shù)原型為:
其中,p_buf為傳感器數(shù)據(jù)緩存,num為緩存大小,表示需要轉(zhuǎn)換單位的數(shù)據(jù)個數(shù),to_unit表示目標單位,其值為AW_SENSOR_UNIT_* (比如: AW_SENSOR_UNIT_MILLI)。若返回值為AW_OK,表示所有數(shù)據(jù)轉(zhuǎn)換成功;否則,表明存在轉(zhuǎn)換失敗的數(shù)據(jù),轉(zhuǎn)換失敗可能是由于在縮小單位時,val值無法完成擴大,即擴大10n后會超過有符號32位數(shù)所能夠表示的范圍。轉(zhuǎn)換失敗的數(shù)據(jù)val值和unit值將保持不變,用戶可以根據(jù)數(shù)據(jù)轉(zhuǎn)換結(jié)束后的單位是否為目標單位來判斷某一數(shù)據(jù)是否轉(zhuǎn)換成功。
例如,從傳感器中獲取數(shù)據(jù),并按照3位小數(shù)進行打印顯示的范例程序詳見程序清單6.35。
程序清單6.35 傳感器數(shù)據(jù)單位轉(zhuǎn)換的范例程序
程序中,假定了通道0為溫度傳感器通道,由于val值能夠表示的數(shù)據(jù)范圍為-2147483648 ~ 2147483647,當unit為-3時,其可以表示的溫度范圍為:-2147483.648 ~ 2147483.647℃。在一般應用環(huán)境中,溫度不會超過該范圍,因此,單位轉(zhuǎn)換必然會成功,當能夠確定數(shù)據(jù)不會超過表示范圍時,可以不用判斷單位轉(zhuǎn)換函數(shù)的返回值。
-
獲取一組(多個)傳感器通道的數(shù)據(jù)
該函數(shù)用于獲取一組(多個)傳感器通道的數(shù)據(jù),其函數(shù)原型為:
其中,p_ids為指向傳感器通道id列表的指針;num表示通道的數(shù)目,即id列表的大小;p_buf指向用于存儲各通道數(shù)據(jù)的緩存,緩存大小應該與num一致,函數(shù)執(zhí)行結(jié)束后,其中將包含各個通道的數(shù)據(jù)。
若返回值為AW_OK,則表示所有通道的數(shù)據(jù)均獲取成功,p_buf所指緩存中存放了有效的數(shù)據(jù);否則,表示存在數(shù)據(jù)獲取失敗的通道,此時,p_buf所指緩存中,這些失敗的通道對應的數(shù)據(jù)將為無效值,即:使用 AW_SENSOR_VAL_IS_VALID()宏判斷數(shù)據(jù)有效性時,將返回FALSE,用戶可以使用AW_SENSOR_VAL_IS_VALID()宏逐一檢查各個通道的數(shù)據(jù),以判斷哪些通道的數(shù)據(jù)獲取成功,哪些通道的數(shù)據(jù)獲取失敗。特別注意,當數(shù)據(jù)為無效值時,val值將為標準錯誤碼,用戶可以根據(jù)val值判斷該通道失敗的原因,例如,值為-AW_ENODEV時,表示對應通道不存在。
AW_SENSOR_VAL_IS_VALID()宏用于判斷一個數(shù)據(jù)的有效性,其原型(aw_sensor.h)為:
其中,data為aw_sensor_val_t類型的數(shù)據(jù),僅當該宏返回TRUE時,才表示data為有效的傳感器數(shù)據(jù)。否則,data為無效值,此時,unit值無效,val值表示標準錯誤碼,其反應了數(shù)據(jù)無效(即某種操作失?。┑脑颉?/p>
獲取一組通道(通道0、3、5、6、8、9)數(shù)據(jù)的范例程序詳見程序清單6.36。
程序清單6.36 獲取一組(多個)通道數(shù)據(jù)的范例程序(1)
通常情況下,為了使程序更加簡潔,也可以不判斷函數(shù)的返回值,僅需在最后使用傳感器數(shù)據(jù)前,判斷傳感器數(shù)據(jù)是否有效即可,范例程序詳見程序清單6.37。
程序清單6.37 獲取一組(多個)通道數(shù)據(jù)的范例程序(2)
4.禁能傳感器通道
當某些傳感器通道使用完畢,暫時不需要從其中獲取數(shù)據(jù)時,可以禁能相應的通道,使其進入一種最佳的低功耗狀態(tài)(若支持)。AWorks提供了兩類禁能接口,分別用于禁能單個傳感器通道和禁能一組(多個)傳感器通道。
-
禁能單個傳感器通道
禁能單個傳感器通道的函數(shù)原型為:
其中,id為傳感器通道的編號。若函數(shù)返回值為AW_OK,則表示通道禁能成功;否則,表示通道禁能失敗,返回值為標準錯誤碼,可以據(jù)此判定失敗的原因。例如,返回值為-AW_ENODEV時,表示id對應的傳感器通道不存在。禁能通道0的范例程序詳見程序清單6.38。
程序清單6.38 禁能單個傳感器通道的范例程序
-
禁能一組(多個)傳感器通道
禁能一組(多個)傳感器通道的函數(shù)原型為:
其中,p_ids為指向傳感器通道id列表的指針;num表示通道的數(shù)目,即id列表的大??;p_result指向用于存儲各個通道禁能結(jié)果的緩存,緩存大小應該與num一致。函數(shù)執(zhí)行結(jié)束后,其中將包含各個通道禁能的結(jié)果,其數(shù)據(jù)含義與使能通道時的數(shù)據(jù)含義一致,即:unit的值無效,僅使用val值表示各個通道禁能的結(jié)果。此時,val值即為標準錯誤碼,若其值為AW_OK,則表示相應的通道禁能成功;否則,表示相應的通道禁能失敗,例如,值為-AW_ENODEV時,表示對應通道不存在。
aw_sensor_group_disable()函數(shù)的返回值同樣為標準錯誤碼,若其值為AW_OK,則表示所有通道禁能成功,此時,p_result中所有數(shù)據(jù)的val值均為AW_OK,因此,當返回值為AW_OK時,無需判斷p_result中的值即可斷定所有通道禁能成功;否則,表示存在禁能失敗的通道,此時,可以逐一檢查p_result中的值來判斷具體哪些通道禁能成功,哪些通道禁能失敗。禁能一組通道(通道0、3、5、6、8、9)的范例程序詳見程序清單6.39。
程序清單6.39 禁能一組(多個)傳感器通道的范例程序
基于數(shù)碼管接口和通用傳感器接口,可以實現(xiàn)一個簡單的應用:使用數(shù)碼管實時顯示當前溫度值。范例程序詳見程序清單6.40。
程序清單6.40 使用數(shù)碼管實時顯示溫度的范例程序
應用程序中,將需要使用到的傳感器通道id和數(shù)碼管顯示器id使用宏的形式在程序前進行了定義(詳見程序清單6.40的第7 ~ 8行),當前id均定義為0,若實際使用的id發(fā)生變化,僅需修改這兩個宏值即可。
6.6 溫控器
下面將結(jié)合此前介紹的接口,使用LED、蜂鳴器、數(shù)碼管、矩陣鍵盤和溫度采集,實現(xiàn)一個簡易的溫控器。
1. 功能簡介
使用標準I2C接口的LM75B溫度傳感器采集溫度并在數(shù)碼管上顯示,由于只有兩位數(shù)碼管,因此只顯示整數(shù)部分;當溫度為負數(shù)時,也不顯示負,僅顯示溫度值。
可設置溫度上限值和溫度下限值,當溫度高于上限值或低于下限值時,則蜂鳴器鳴叫。
2. 狀態(tài)指示
在調(diào)節(jié)過程中,使用LED0和LED1兩個LED用于狀態(tài)指示:
-
LED0亮:表明當前值為上限值,數(shù)碼管顯示上限值;
-
LED1亮:表明當前值為下限值,數(shù)碼管顯示下限值;
-
兩燈閃爍:表明正常運行狀態(tài),數(shù)碼管顯示環(huán)境溫度值。
3. 操作說明
設置上下限值時,共計使用4個按鍵。即:
-
SET鍵:用于進入設置狀態(tài)。點擊后首先進入溫度上限值設定,再次點擊可進入溫度下限值設定,再次點擊回到正常運行狀態(tài);
-
左移/右移鍵:用于切換當前調(diào)節(jié)的位(個位/十位)。當進入設置狀態(tài)后,當前調(diào)節(jié)的位會不斷的閃爍;點擊該鍵可以切換當前調(diào)節(jié)的位,由個位切換到十位,或由十位切換到個位;
-
加1鍵:當進入設置狀態(tài)后,當前調(diào)節(jié)的位會不斷的閃爍,按該鍵可以使該位上的數(shù)值增加1;
-
減1鍵:當進入設置狀態(tài)后,當前調(diào)節(jié)的位會不斷的閃爍,按該鍵可以使該位上的數(shù)值增減1。
(1)設置上限值
首次按下SET鍵進入上限值設置,此時LED0點亮,數(shù)碼管顯示上限值溫度,個位不停閃爍。按“加1鍵”或“減1鍵”可以對當前閃爍位上得值進行調(diào)整,按下“左移/右移鍵”可以切換當前調(diào)節(jié)的位。
(2)設置下限值
在設置上限值的基礎上,再次點擊SET鍵即可進入下限值的設定,此時LED1點亮,數(shù)碼管顯示下限值溫度,個位不停閃爍。按“加1鍵”或“減1鍵”可以對當前閃爍位上的值進行調(diào)整,按“左移/右移鍵”可以切換當前調(diào)節(jié)的位。
4. 功能實現(xiàn)
溫控器的實現(xiàn)范例程序詳見程序清單6.41。程序中比較繁瑣的是按鍵的處理程序。為了使程序結(jié)構(gòu)更加清晰,分別對3種按鍵:切換狀態(tài)(KEY0)、切換當前調(diào)節(jié)位(KEY2)、調(diào)節(jié)當前位的值(KEY1和KEY3)寫了3個函數(shù),各個函數(shù)直接在__key_callback()按鍵回調(diào)函數(shù)中調(diào)用。其它部分均在while(1)主循環(huán)中完成,主要完成3件事情:溫度值的采集,每隔500ms進行一次;溫度值的判斷,判斷是否過高或過低,以便報警;正常狀態(tài)下LED0和LED1的閃爍。
程序清單6.41 使用通用接口實現(xiàn)溫控器代碼
-
接口
+關注
關注
33文章
8598瀏覽量
151163 -
周立功
+關注
關注
38文章
130瀏覽量
37632
原文標題:AWorks軟件篇 — 通用設備接口
文章出處:【微信號:Zlgmcu7890,微信公眾號:周立功單片機】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論