周立功教授新書《面向AMetal框架與接口的編程(上)》,對AMetal框架進行了詳細介紹,通過閱讀這本書,你可以學到高度復用的軟件設計原則和面向接口編程的開發思想,聚焦自己的“核心域”,改變自己的編程思維,實現企業和個人的共同進步。經周立功教授授權,即日起,致遠電子公眾號將對該書內容進行連載,愿共勉之。
第七章為面向通用接口的編程,本文內容為7.6 數碼管。
7.6 數碼管
>>> 7.6.1 通用數碼管接口
AMetal 提供了一套通用數碼管接口,詳見表7.7。
表7.7 數碼管通用接口(am_digitron_disp.h)
1. 設置段碼解碼函數
數碼管的各個段可以組合顯示出多種圖形,使用該函數可以自定義字符的解碼函數,其函數原型為:
其中,id 表示設置數碼管顯示器的編號,這里的id 指的是顯示器的編號,而不是數碼管的位索引。一般情況下,僅只有一個數碼管顯示器,比如,MiniPort-View 顯示器,其包含兩位數碼管,僅只有一個數碼管顯示器時,id 為0。
pfn_decode 為函數指針,其指向的函數即為設置的解碼函數,解碼函數的參數為uint16_t類型的字符,返回值為uint16_t 類型的編碼。
絕大部分情況下,對于8 段數碼管,如字符'0' ~ '9'等都是有默認編碼的,為此,AMetal提供了默認的8 段數碼管解碼函數,可以支持常見的字符'0' ~ '9'以及 'A' 、'B'、 'C' 、'D'、'E'、 'F'等的字符的解碼。其在am_digitron_disp.h 文件中聲明:
如無特殊需求,直接將該函數作為pfn_decode 的實參傳遞,范例程序詳見程序清單7.40。
程序清單7.40 am_digitron_disp_decode_set()范例程序
若由于應用特殊需求,要求字符使用自定義的特殊編碼,如要使字符'O'的編碼為 0xFC,則可以自定義如下解碼函數:
然后將該函數作為pfn_decode 的實參傳遞即可:
2. 設置數碼管閃爍
該函數可以指定數碼管顯示器的某一位數碼管閃爍,其函數原型為:
其中,id 為數碼管顯示器編號;index 為數碼管索引,如MiniPort-View 有兩位數碼管,則兩個數碼管的索引分別為 0 和1;blink 表示該位是否閃爍,若其值為AM_TRUE,則閃爍,反之,則不閃爍,默認情況下,所有數碼管均處于未閃爍狀態。如設置1 號數碼管閃爍的范例程序詳見程序清單7.41。
程序清單7.41 am_digitron_disp_blink_set()范例程序
3. 顯示指定的段碼圖形
該函數用于不經過解碼函數解碼,直接顯示段碼指定的圖形,可以靈活的顯示任意特殊圖形,其函數原型為:
其中,id 為數碼管顯示器編號;index 為數碼管索引;seg 為顯示的段碼。如在8 段數碼管上顯示字符'-',即需要g 段點亮,對應的段碼為0x02(即:0000 0010),范例程序詳見程序清單7.42。
程序清單7.42 am_digitron_disp_at()范例程序
4. 顯示單個字符
該函數用于在指定位置顯示一個字符,字符經過解碼函數解碼后顯示,若解碼函數不支持該字符,則不顯示任何內容,其函數原型為:
其中,id 為數碼管顯示器編號,index 為數碼管索引,ch 為顯示的字符。比如,顯示字符'H'的范例程序詳見程序清單7.43。
程序清單7.43 am_digitron_disp_char_at()范例程序
5. 顯示字符串
該函數用于從指定位置開始顯示一個字符串,其函數原型為:
其中,id 為數碼管顯示器編號,index 為顯示字符串的數碼管起始索引,即從該索引指定的數碼管開始顯示字符串,len 指定顯示的長度,p_str 指向需要顯示的字符串。
實際顯示的長度是len 和字符串長度的較小值,若數碼管位數不夠,則多余字符不顯示。如顯示字符"HELLO"的范例程序詳見程序清單7.44。
程序清單7.44 am_digitron_disp_str()范例程序
若使用的是MiniPort-View,由于只存在兩個數碼管,因此最終只會顯示"HE"。
通常情況下,需要顯示一些數字,如顯示變量的值,此時,可以先將變量通過格式化字符串函數輸出到字符串緩沖區中,然后再使用am_digitron_disp_str()函數顯示該字符串。比如,顯示一個變量i 的值,范例程序詳見程序清單7.45。
程序清單7.45 使用am_digitron_disp_str()顯示整數變量值的范例程序
其中,am_snprintf()與標準C 函數snprintf()函數功能相同,均用于格式化字符串到指定的緩沖區中,其函數原型為(am_vdebug.h):
其與am_kprintf()函數的區別是,am_kprintf()將信息直接通過調試串口打印輸出,而am_snprintf()函數將信息輸出到大小為sz 的buf 緩沖區中。
6. 顯示清屏
該函數用于顯示清屏,清除數碼管顯示器中的所有內容,其函數原型為:
其中,id 為數碼管顯示器編號,范例程序詳見程序清單7.46。
程序清單7.46 am_digitron_disp_clr()范例程序
基于數碼管通用接口,可以編寫一個簡易的60s 倒計時程序,當倒計時還剩5s 時,數碼管閃爍。基于模塊化編程思想,將應用程序存放到app_digitron_count_down.c 文件中,并將其接口聲明到app_digitron_count_down.h 文件中,詳見程序清單7.47 和程序清單7.48。
程序清單7.47 倒計時應用程序實現(app_digitron_count_down.c)
程序清單7.48 倒計時應用程序接口聲明(app_digitron_count_down.h)
由此可見,要使用此應用程序,只需在調用其入口函數app_digitron_count_down()時,指定應用程序所使用的數碼管顯示器編號即可。應用程序與具體MCU、數碼管驅動方式無關,可以在任何AMetal 平臺上運行。
顯然,要使應用程序可以使用通用操作數接口操作數碼管,就需要為具體的數碼管提供相應的驅動。AMetal 提供了MiniPort-View 的驅動,用戶可以直接使用。
>>> 7.6.2 數碼管驅動
AMetal 數碼管驅動提供了一個初始化函數,使用該函數初始化一個數碼管實例后,即可使用通用數碼管接口操作數碼管。其函數原型為:
其中,p_dev 為指向am_digitron_scan_gpio_dev_t 類型實例的指針,p_info 為指向am_digitron_scan_gpio_info_t 類型實例信息的指針。
1. 實例
定義am_digitron_scan_gpio_dev_t 類型(am_digitron_scan_gpio.h)實例如下:
其中,miniport_view 為用戶自定義的實例,其地址作為p_dev 的實參傳遞。
2. 實例信息
實例信息主要描述與數碼管相關的信息,比如,使用的GPIO 引腳號、數碼管個數等以及本實例對應的顯示器編號(通用接口即可使用該顯示器編號操作該數碼管實例)等。其類型am_digitron_scan_gpio_info_t 的定義(am_digitron_scan_gpio.h)如下:
其中,scan_info 是數碼管動態掃描相關的信息,包含了掃描頻率、掃描方式和緩存的定義等;base_info 是數碼管基礎信息,如數碼管個數、段碼位數等;p_seg_pins 指向存放各個段對應引腳號的數組,p_com_pins 指向存放各個位選對應引腳號的數組。若使用AM824-Core 開發板與MiniPort-View 直接連接,其段碼引腳為PIO0_8 ~ PIO0_15,位選引腳分別為PIO0_17 和PIO0_23。分別定義存放段碼引腳號和位選引腳號的數組:
g_digitron_seg_pins 數組的地址即可作為p_seg_pins 的值;g_digitron_com_pins 數組的地址即可作為p_com_pins 的值。
scan_info 成員的類型am_digitron_scan_devinfo_t 定義(am_digitron_scan.h)如下:
其中,devinfo 是標準數碼管設備的信息,其僅包含顯示器ID 號,其類型定義(am_digitron_dev.h)如下:
當前只連接了單個數碼管實例,因此,將id 設置為0,在使用數碼管通用接口時,將顯示器id 參數賦值為0 即可操作此處初始化的數碼管實例。
scan_freq 指定掃描的頻率,通常情況下,為避免看到閃爍現象,將頻率設置為50Hz。blink_on_time 和blink_off_time 分別指定了數碼管閃爍時,數碼管點亮的時間和熄滅的時間,以此可以達到調節閃爍效果的作用。通常情況下,數碼管以1Hz 頻率閃爍,點亮和熄滅的時間分別設置為500ms。
p_disp_buf 指向數碼管的顯存,顯存的類型為uint8_t,顯存的大小與數碼管個數相同。對于MiniPort-View,共計有兩個數碼管,因此大小為2 的顯存定義如下:
g_disp_buf 數組的地址即可作為p_disp_buf 的值。
p_scan_buf 指向數碼管的掃描緩存,用于存儲單次掃描到的數碼管的段碼,對于8 段數碼管,其緩存的類型為uint8_t ,緩存的大小與單次掃描的數碼管個數相同, 對于MiniPort-View,一次只能掃描一個數碼管,因此掃描緩存的大小為1,掃描緩存可定義如下:
g_scan_buf 數組的地址即可作為p_scan_buf 的值。
base_info 成員的類型am_digitron_base_info_t 定義(am_digitron_base.h)如下:
其中,num_segment 表示數碼管的段數,對于MiniPort-View,其數碼管為8 段數碼管,因此num_segment 的值為8。num_rows 和num_cols 分別表示數碼管的行數和列數,對于MiniPort-View,其數碼管的排布方式為 1×2,即單行兩個數碼管,因此num_rows 和num_cols的值分別為1 和2。
如表7.8 所示為數碼管掃描方式,scan_mode 表示數碼管的掃描方式,可選的掃描方式有行掃描或列掃描方式,掃描方式是由硬件決定的,對于MiniPort-View,其僅單行兩個數碼管,橫向的兩個數碼管共用段碼引腳,因此,只能使用列掃描方式,即一次掃描一列(一個數碼管),scan_mode 的值為AM_DIGITRON_SCAN_MODE_COL。
表7.8 數碼管掃描方式
seg_active_low 表示驅動段點亮的有效電平是否為低電平,由于MiniPort-View 使用的是共陽數碼管,因此,段的驅動電平為低電平,seg_active_low 的值為AM_TRUE。
com_active_low 表示驅動位選有效的電平是否為低電平,雖然共陽數碼管的公共端是高
電平有效,但由于添加了三極管驅動電路,三極管是GPIO 輸出低電平時導通,進而使數碼管公共端為高電平。因此驅動位選有效的同樣是低電平,com_active_low 的值為AM_TRUE。基于以上信息,實例信息定義如下:
基于實例和實例信息,即可完成MiniPort-View 數碼管的初始化:
當完成初始化后,可使用通用數碼管接口操作顯示器編號為0 的數碼管設備。為了便于配置數碼管(修改實例信息)。基于模塊化編程思想,將初始化相關的實例、實例信息等的定義存放到數碼管的配置文件中,通過頭文件引出實例初始化函數接口,源文件和頭文件的程序范例分別詳見程序清單7.49 和程序清單7.50。
程序清單7.49 數碼管實例初始化函數實現(am_hwconf_miniport_view.c)
程序清單7.50 數碼管實例初始化函數聲明(am_hwconf_miniport_view.h)
后續只需使用無參數的實例初始化函數,即可執行以下語句完成數碼管實例的初始化:
當完成初始化后,可使用通用數碼管接口操作顯示器編號為0 的數碼管設備,運行如程序清單7.47 所示的倒計時程序,檢驗能否達到預期的效果,主程序詳見程序清單7.51。
程序清單7.51 運行倒計時應用程序的主程序
>>> 7.6.3 數碼管驅動(HC595 輸出段碼)
當GPIO 資源不足時,則可以在AM824-Core 與MiniPort-View 之間增加MiniPort-595,使用HC595 驅動數碼管的段碼,達到節省引腳的目的。
顯然,在前面的數碼管驅動中,8 位段碼是直接由GPIO 輸出的,若改由HC595 輸出段碼,則使用的驅動也需要發生相應的改變。AMetal 提供了使用HC595 輸出段碼的數碼管驅動,僅包含一個初始化函數,使用該函數初始化一個數碼管實例后,即可使用通用數碼管接口操作數碼管。其函數原型為:
-
p_dev 為指向am_digitron_scan_hc595_gpio_dev_t 類型實例的指針;
-
p_info 為指向am_digitron_scan_hc595_gpio_info_t 類型實例信息的指針。
1. 實例
am_digitron_scan_hc595_gpio_dev_t 類型(am_digitron_scan_hc595_gpio.h)實例的定義
如下:
其中,miniport_view_595 為用戶自定義的實例,其地址作為p_dev 的實參傳遞。
2. 實例信息
實例信息主要描述與數碼管相關的信息,比如,使用的位選GPIO 引腳號、數碼管個數等以及本實例對應的顯示器編號(通用接口即可使用該顯示器編號操作該數碼管實例)等。
其類型am_digitron_scan_hc595_gpio_info_t 的定義(am_digitron_scan_hc595_gpio.h)如下:
將其與GPIO 輸出段碼的數碼管實例信息相比(am_digitron_scan_gpio_info_t)可以發現,其僅僅少了一個數據成員p_seg_pins,其它信息都是完全一樣的。這是由于當使用595輸出段碼時,不再需要使用GPIO 輸出段碼,因此,也就不用指定段碼引腳。基于此,只需要從GPIO 輸出段碼的數碼管實例信息中去掉段碼引腳,即可得到HC595 輸出段碼的數碼管實例信息:
3. HC595 句柄handle
若使用Miniport-595 輸出碼段,則應通過MiniPort-595 的實例初始化函數獲得HC595的句柄。即:
HC595 句柄即可直接作為handle 的實參傳遞。
基于實例、實例信息和HC595 句柄,可以完成數碼管實例的初始化。比如:
當完成初始化后,可使用通用數碼管接口操作顯示器編號為0 的數碼管設備。基于模塊化編程思想,將初始化相關的實例、實例信息等的定義存放到數碼管的配置文件中,將相關內容新增到am_hwconf_miniport_view.c 文件中,同時,將實例初始化函數的聲明新增到am_hwconf_miniport_view.h 文件中,詳見程序清單7.52 和程序清單7.53。
程序清單7.52 數碼管實例初始化函數實現(am_hwconf_miniport_view.c)
程序清單7.53 am_hwconf_miniport_view.h 文件更新
后續只需使用無參數的實例初始化函數,即可執行以下語句完成數碼管實例的初始化:
當完成初始化后,可調用通用數碼管接口操作顯示器編號為0 的數碼管,運行如程序清單7.47 所示的倒計時程序,檢驗能否達到預期的效果,主程序詳見程序清單7.54。
程序清單7.54 運行倒計時應用程序的主程序
-
數碼管
+關注
關注
32文章
1874瀏覽量
90943 -
接口編程
+關注
關注
0文章
9瀏覽量
8732
原文標題:周立功:面向通用接口的編程——數碼管
文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠電子】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論