有許多朋友在移植CHX01超聲波傳感器的過程中可能會遇到一些挑戰(zhàn),因此本文將重點介紹一些核心問題。雖然本來有想以手把手的方式來教授如何移植,但是由于之前移植的時候沒有保存具體過程中的圖文,所以需要花費很長的時間來重新完成這項工作。文末也提供了獲取資源的接口,以幫助大家解決移植中出現(xiàn)的問題。
01準備資料
1. 從官網(wǎng)獲取 SmartSonic_HelloChirp_Example_v1_31_0.exe
源碼(CHx01 官網(wǎng)源碼的硬件平臺 MCU: ATSAMG55;IDE:Microchip Studio)
2. 獲取一個 STM32F103CB 的例程,比如我直接使用 STM32CubeF1 的模板。(當然你也可以用 STM32CubeIDE 創(chuàng)建一個工程)在這之前,假設(shè)你已經(jīng)掌握了 Keil IDE 工程下的文件添加、編譯等操作。比如,如下截圖,我精簡了STM32CubeF1 的模板,將工程名稱修改為:SmartSonic_HelloChirp,并在工程下新建了 Drivers/BSP 和 Drivers/chirpmicro 兩個Groups。
3. 將SmartSonic_HelloChirp_Example_v1_31_0文件中
SmartSonic_HelloChirp_v1.31.0sourcedriverschirpmicro路徑下的src 和 inc 文件夾拷貝到自己的STM32工程的smart-sonic_-hello-chirpDriverschirpmicro目錄下
02API接口封裝
我在之前的文章《超聲波傳感器(CHx01) 學習筆記 Ⅲ-API介紹》中提到所需API接口的相關(guān)內(nèi)容。同樣,在官方提供的例程中有一個 chbsp_dummy.c 文件,它使用 `attribute((weak))` 的方式提供了可選板支持包IO功能的虛擬實現(xiàn),可以讓平臺依據(jù)需求來支持所需的功能。這種 `attribute((weak))` 例程能夠滿足來自其他代碼的引用,避免鏈接出現(xiàn)錯誤,但它們不會執(zhí)行任何操作。所有板卡支持包接口的詳細信息,包括這些可選功能,都可以在 chirp_bsp.h 中找到。
/* Functions supporting debugging */ __attribute__((weak)) void chbsp_debug_toggle(uint8_t __attribute__((unused)) dbg_pin_num) {} __attribute__((weak)) void chbsp_debug_on(uint8_t __attribute__((unused)) dbg_pin_num) {} __attribute__((weak)) void chbsp_debug_off(uint8_t __attribute__((unused)) dbg_pin_num) {} __attribute__((weak)) void chbsp_print_str(char *str) { (void)(str); } __attribute__((weak)) uint32_t chbsp_timestamp_ms() { return 0; } __attribute__((weak)) int chbsp_i2c_deinit(void){ return 0; } /* Functions supporting interrupt-based operation */ __attribute__((weak)) void chbsp_group_io_interrupt_enable(ch_group_t *grp_ptr) { (void)(grp_ptr); } __attribute__((weak)) void chbsp_io_interrupt_enable(ch_dev_t *dev_ptr) { (void)(dev_ptr); } __attribute__((weak)) void chbsp_group_io_interrupt_disable(ch_group_t *grp_ptr) { (void)(grp_ptr); } __attribute__((weak)) void chbsp_io_interrupt_disable(ch_dev_t *dev_ptr) { (void)(dev_ptr); } /* Functions supporting non-blocking operation */ __attribute__((weak)) int chbsp_i2c_write_nb(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes) { (void)(dev_ptr); (void)(data); (void)(num_bytes); return 1; } __attribute__((weak)) int chbsp_i2c_mem_write_nb(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes) { (void)(dev_ptr); (void)(mem_addr); (void)(data); (void)(num_bytes); return 1; } __attribute__((weak)) int chbsp_i2c_read_nb(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes) { (void)(dev_ptr); (void)(data); (void)(num_bytes); return 1; } __attribute__((weak)) int chbsp_i2c_mem_read_nb(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes) { (void)(dev_ptr); (void)(mem_addr); (void)(data); (void)(num_bytes); return 1; } /* Functions supporting controlling int pins of individual sensors (originally only controllable in a group) */ __attribute__((weak)) void chbsp_set_io_dir_out(ch_dev_t *dev_ptr) { (void)(dev_ptr); } __attribute__((weak)) void chbsp_set_io_dir_in(ch_dev_t *dev_ptr) { (void)(dev_ptr); } __attribute__((weak)) void chbsp_io_clear(ch_dev_t *dev_ptr) { (void)(dev_ptr); } __attribute__((weak)) void chbsp_io_set(ch_dev_t *dev_ptr) { (void)(dev_ptr); } __attribute__((weak)) void chbsp_external_i2c_irq_handler(chdrv_i2c_transaction_t *trans){ (void)(trans); }
超聲波傳感器(CHx01) 學習筆記 Ⅱ- I2C讀寫操作》中有詳細的介紹,按照上述API接口逐個封裝函數(shù)內(nèi)容即可。
03API接口驗證
假設(shè)你已經(jīng)將MAX3378EEUD和74LVC1T45用于IO口電平轉(zhuǎn)換,接下來就是如何獲取傳感器的固定ID,以此來驗證I2C通信接口的正確性。獲取ID的方式可以幫助我們更好地驗證I2C通信接口的封裝正確性。
獲取傳感器 ID流程圖
獲取傳感器 IDI2C讀時序圖
04關(guān)鍵API接口介紹
`int chbsp_i2c_mem_read(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes)`
這個 API 使用內(nèi)存尋址從I2C從機讀取字節(jié)。需要封裝成一個,指定一個字節(jié)寄存器地址并從Slave讀取多個字節(jié)的函數(shù)。
與 STM32 HAL庫相關(guān)的函數(shù)是:HAL_I2C_Mem_Read(&hi2c1, Address << 1, RegisterAddr, 1, (uint8_t *)(uint32_t)RegisterValue, (uint16_t)RegisterLen, 1000)
`int chbsp_i2c_read(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes)`
這個 API 是原始的I2C從機讀取字節(jié)。需要封裝成一個,從Slave讀取多字節(jié)的函數(shù)。
與 STM32 HAL庫相關(guān)的函數(shù)是:HAL_I2C_Master_Receive(&hi2c1, (Address << 1), (uint8_t *)(uint32_t)data, (uint16_t)len, 1000)
`int chbsp_i2c_mem_write(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes)`
這個 API 使用內(nèi)存尋址將字節(jié)寫入I2C從機。需要封裝成一個,指定一個字節(jié)寄存器地址并將多個字節(jié)寫入從機的函數(shù)。
與 STM32 HAL庫相關(guān)的函數(shù)是:HAL_I2C_Mem_Write(&hi2c1, Address << 1, RegisterAddr, 1, (uint8_t *)(uint32_t)RegisterValue, (uint32_t)RegisterLen, 1000)
`int chbsp_i2c_write(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes)`
這個 API 是原始的將字節(jié)寫入I2C從機。需要封裝成一個,將多字節(jié)寫入從機的函數(shù)。
與 STM32 HAL庫相關(guān)的函數(shù)是:HAL_I2C_Master_Transmit(&hi2c1, (Address << 1), (uint8_t *)(uint32_t)data, (uint32_t)len, 1000)
`void chbsp_delay_ms(uint32_t num_ms)`
`void chbsp_delay_us(uint32_t us)`
這兩個延時函數(shù)要精準,尤其是 chbsp_delay_ms 毫秒延時,會直接影響傳感器的輸出頻率。
下面這兩個函數(shù),我們無需自行封裝任何內(nèi)容,但是它們非常重要。
`int chdrv_group_detect_and_program(ch_group_t *grp_ptr)`
這個函數(shù)用來檢測、編程和啟動傳感器。對于每個檢測到的傳感器,會將傳感器固件被編程到設(shè)備中,并設(shè)置應用程序I2C地址。然后傳感器復位并開始執(zhí)行。
一旦啟動,傳感器設(shè)備將開始內(nèi)部初始化和自檢序列。chdrv_group_wait_for_lock()函數(shù)可用于等待此序列在設(shè)備上完成。此函數(shù)完成后,將使設(shè)備的PROG引腳解除。
`void chdrv_group_measure_rtc(ch_group_t *grp_ptr)`
這個函數(shù)用來 校準傳感器實時時鐘。在這個函數(shù)里 觸發(fā)IO引腳上的脈沖 時與選擇的主處理器的時鐘相關(guān)。
此函數(shù)在INT 引腳上向傳感器設(shè)備發(fā)送一個脈沖(由主機MCU定時),然后回讀每個單獨設(shè)備上該脈沖期間經(jīng)過的傳感器RTC周期的計數(shù)。結(jié)果存儲在每個設(shè)備的ch_dev_config結(jié)構(gòu)中,隨后在范圍計算期間使用。
脈沖的長度為dev_ptr->rtc_cal_pulse_ms毫秒(通常為100)。此值在ch_init()期間設(shè)置。
如果有多個傳感器時,校準脈沖會同時發(fā)送到所有設(shè)備。因此,所有連接的設(shè)備將看到相同的參考脈沖長度。
還需要實現(xiàn)兩個外設(shè)功能
定時器,定時周期100ms,在定時器回調(diào)函數(shù)中周期性調(diào)用
`int chdrv_group_hw_trigger(ch_group_t *grp_ptr)` 啟動硬件觸發(fā)模式下開始測量。
int chdrv_group_hw_trigger(ch_group_t *grp_ptr) 函數(shù)通過簡單地檢測INT 引腳上每個傳感器開始被觸發(fā)的測量。在調(diào)用此函數(shù)之前,每個傳感器必須已置于硬件觸發(fā)模式。
GPIO外部中斷,在外部中斷回調(diào)函數(shù)中調(diào)用
`sensor_int_callback()` 檢測傳感器的中斷信號。每次調(diào)用此函數(shù)時,都會在data_ready_devices變量中設(shè)置一個位以標識中斷設(shè)備。當傳感器產(chǎn)生中斷(通過與active_devices變量比較找到)時,DATA_READY_FLAG被設(shè)置。該標志將在main()循環(huán)中檢測到。
一個完成的硬件觸發(fā)INT硬件,并接收傳感器返回的INT信號的時序圖
05程序流程圖
主程序
定時器服務程序
INT外部中斷服務程序
-
mcu
+關(guān)注
關(guān)注
146文章
17269瀏覽量
352055 -
接口
+關(guān)注
關(guān)注
33文章
8677瀏覽量
151593 -
STM32
+關(guān)注
關(guān)注
2270文章
10918瀏覽量
356890 -
移植
+關(guān)注
關(guān)注
1文章
382瀏覽量
28157 -
STM32F103
+關(guān)注
關(guān)注
33文章
478瀏覽量
63747
原文標題:基于STM32F103的CH101驅(qū)動程序移植
文章出處:【微信號:SmartHWFW,微信公眾號:SmartHWFW】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論