我一直在研究一系列PSoC 6項目,以準備一些新視頻并在Embedded World上使用。對于其中一個項目,我需要一個動作敏感的遙控器......并且我們很方便地將一臺博世BMI160運動傳感器放到了CY8CKIT-062-BLE開發(fā)套件隨附的新CY8CKIT-028-EPD屏蔽罩上。
在本文中,我將向您展示如何使用PSoC 6制作完整的測試系統(tǒng)來與BMI160進行通話。步驟是:
-
克隆博世BMI160驅(qū)動程序庫
-
創(chuàng)建一個新的PSoC 6項目并添加驅(qū)動程序庫
-
為博世驅(qū)動程序創(chuàng)建HAL
-
創(chuàng)建主要固件并進行測試
克隆博世BMI160驅(qū)動程序庫
當我開始這個時,我知道董事會有一個運動傳感器,但我不知道是什么樣的。我假設(shè)它是基于I2C的傳感器,所以我連接了橋接控制面板并探測I2C總線。但是這就是它所說的:
那么......到底什么?然后,我看了看董事會,試圖弄清楚發(fā)生了什么......低下,看看......我的電路板是在添加運動傳感器之前完成的原型。這里是:
這里是一塊帶有傳感器的電路板。
當我插入該板并使用Bridge Control Panel進行測試時,我會得到:
接下來我做的就是看原理圖。OK,您可以看到慣性測量單元(IMU)是連接到I2C總線的BMI160。另一件很酷的事情是,devkit團隊連接了兩條中斷線。這些線路通常用于IMU向PSoC 6發(fā)送信號(例如,用戶可能開始移動)。
查看原理圖后,下一步是查看BMI160數(shù)據(jù)表并嘗試弄清楚如何與設(shè)備進行連接。通常這些設(shè)備有一堆寄存器,其位數(shù)字段的數(shù)量令人難以置信。這一直是這個過程中不好玩的部分。但是這次當我去博世網(wǎng)站上的BMI160設(shè)備頁面時,有一個按鈕顯示“文檔和驅(qū)動程序”,當您點擊它時,會有一個鏈接到BMI160驅(qū)動程序的GitHub。得分了!
要做到這一點,你只需要“git clonegit@github.com:BoschSensortec / BMI160_driver.git”
使用博世BMI160驅(qū)動程序庫創(chuàng)建新的PSoC 6項目
所以,讓我們繼續(xù)測試它。首先創(chuàng)建一個新的PSoC 63項目
使用空白示意圖
給它一個名字
添加Retarget I / O和FreeRTOS(從構(gòu)建設(shè)置菜單中)
添加一個UART和一個I2C主控
要使I2C成為主設(shè)備,您需要雙擊并將其更改為主設(shè)備
然后分配引腳
運行“構(gòu)建 - >生成應用程序”來獲得您需要的所有PDL固件。
編輯stdio_user.h以使用UART(掃描stdio_user.h找到正確的位置)
#include"project.h" /*Mustremainuncommentedtousethisutility*/ #defineIO_STDOUT_ENABLE #defineIO_STDIN_ENABLE #defineIO_STDOUT_UARTUART_1_HW #defineIO_STDIN_UARTUART_1_HW 將“BMI_driver”目錄添加到CM4項目的包含路徑。(要進入此菜單,請右鍵單擊該項目并選擇“構(gòu)建設(shè)置”)
將Bosch Driver文件添加到項目中
為博世驅(qū)動程序創(chuàng)建HAL
使用博世驅(qū)動器很簡單。你所需要做的就是更新HAL。
-
提供寫入I2C寄存器的功能
-
提供讀取I2C寄存器的功能
-
提供延遲指定毫秒數(shù)的功能
-
創(chuàng)建一個結(jié)構(gòu)來保存初始化信息和函數(shù)指針
該器件實現(xiàn)了賽普拉斯所稱的“EZI2C”協(xié)議,該協(xié)議也稱為I2C EEPROM協(xié)議。該器件被組織為一系列寄存器。每個寄存器都有一個從0-> 0xFF(單字節(jié)地址)的地址。要寫入注冊表,您需要
-
發(fā)送I2C啟動
-
發(fā)送7位I2C地址
-
發(fā)送一個寫入位(aka a 0)
-
發(fā)送要寫入的寄存器地址(不要將I2C地址與內(nèi)部BMI160地址混淆)
-
發(fā)送您想要寫入的8位值
-
發(fā)送一個停止
EZI2C的一個很酷的事情是,它可以跟蹤地址,并在每次寫入時自動遞增寄存器地址。這意味著您可以編寫一個地址序列,而無需為每個地址執(zhí)行完整的事務(wù)。
鑒于引入寫函數(shù)很簡單:
staticint8_tBMI160BurstWrite(uint8_tdev_addr,uint8_treg_addr,uint8_t*data,uint16_tlen) { Cy_SCB_I2C_MasterSendStart(I2C_1_HW,dev_addr,CY_SCB_I2C_WRITE_XFER,0,&I2C_1_context); Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,reg_addr,0,&I2C_1_context); for(inti=0;i為了閱讀你做一個類似的交易來寫。具體的步驟是:
發(fā)送I2C啟動
發(fā)送7位I2c地址
發(fā)送一個WRITE位aka 0
發(fā)送您想要讀取的寄存器地址
發(fā)送I2C重新啟動
讀一個字節(jié)
發(fā)送NAK
發(fā)送一個停止
讀取事務(wù)與寫入類似,您可以通過發(fā)送ACK繼續(xù)讀取連續(xù)字節(jié)。您讀取的最后一個字節(jié)應該是NAK,以告訴遠程設(shè)備您正在讀取。鑒于代碼也很簡單。
//ThisfunctionsupportstheBMP180libraryandreadI2CRegisters staticint8_tBMI160BurstRead(uint8_tdev_addr,uint8_treg_addr,uint8_t*data,uint16_tlen) { Cy_SCB_I2C_MasterSendStart(I2C_1_HW,dev_addr,CY_SCB_I2C_WRITE_XFER,0,&I2C_1_context); Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,reg_addr,0,&I2C_1_context); Cy_SCB_I2C_MasterSendReStart(I2C_1_HW,dev_addr,CY_SCB_I2C_READ_XFER,0,&I2C_1_context); for(inti=0;i我的讀寫功能都有一個錯誤。那個錯誤是?沒有錯誤檢查。我看到了一些間歇性的奇怪現(xiàn)象,其中I2C總線被鎖定,最終需要重置才能修復。這可以通過檢查I2C功能上的錯誤代碼來防止。
既然我們有讀寫功能,我們可以設(shè)置我們的設(shè)備:要做到這一點:
設(shè)置一個類型為bmi160_dev的結(jié)構(gòu)
初始化函數(shù)指針
初始化設(shè)備的設(shè)置
最后發(fā)送設(shè)置
staticstructbmi160_devbmi160Dev; staticvoidsensorsDeviceInit(void) { int8_trslt; vTaskDelay(500);//guess /*BMI160*/ bmi160Dev.read=(bmi160_com_fptr_t)BMI160BurstRead; bmi160Dev.write=(bmi160_com_fptr_t)BMI160BurstWrite; bmi160Dev.delay_ms=(bmi160_delay_fptr_t)vTaskDelay; bmi160Dev.id=BMI160_I2C_ADDR;//I2Cdeviceaddress rslt=bmi160_init(&bmi160Dev);//initializethedevice if(rslt==0) { printf("BMI160I2Cconnection[OK]. "); bmi160Dev.gyro_cfg.odr=BMI160_GYRO_ODR_800HZ; bmi160Dev.gyro_cfg.range=BMI160_GYRO_RANGE_125_DPS; bmi160Dev.gyro_cfg.bw=BMI160_GYRO_BW_OSR4_MODE; /*SelectthepowermodeofGyroscopesensor*/ bmi160Dev.gyro_cfg.power=BMI160_GYRO_NORMAL_MODE; bmi160Dev.accel_cfg.odr=BMI160_ACCEL_ODR_1600HZ; bmi160Dev.accel_cfg.range=BMI160_ACCEL_RANGE_4G; bmi160Dev.accel_cfg.bw=BMI160_ACCEL_BW_OSR4_AVG1; bmi160Dev.accel_cfg.power=BMI160_ACCEL_NORMAL_MODE; /*Setthesensorconfiguration*/ bmi160_set_sens_conf(&bmi160Dev); bmi160Dev.delay_ms(50); } else { printf("BMI160I2Cconnection[FAIL]. "); } }創(chuàng)建主要固件并進行測試
最后,我通過運行打印出加速數(shù)據(jù)的無限循環(huán)來測試固件。
voidmotionTask(void*arg) { (void)arg; I2C_1_Start(); sensorsDeviceInit(); structbmi160_sensor_dataacc; while(1) { bmi160_get_sensor_data(BMI160_ACCEL_ONLY,&acc,NULL,&bmi160Dev); printf("x=%4dy=%4dz=%4d ",acc.x,acc.y,acc.z,); vTaskDelay(200); } }現(xiàn)在你應該有這樣的:
最后整個節(jié)目一舉成名
#include"project.h" #include"FreeRTOS.h" #include"task.h" #include #include"bmi160.h" staticstructbmi160_devbmi160Dev; staticint8_tBMI160BurstWrite(uint8_tdev_addr,uint8_treg_addr,uint8_t*data,uint16_tlen) { Cy_SCB_I2C_MasterSendStart(I2C_1_HW,dev_addr,CY_SCB_I2C_WRITE_XFER,0,&I2C_1_context); Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,reg_addr,0,&I2C_1_context); for(inti=0;i
-
PSoC
+關(guān)注
關(guān)注
12文章
170瀏覽量
91763 -
BMI160
+關(guān)注
關(guān)注
1文章
7瀏覽量
7984
發(fā)布評論請先 登錄
相關(guān)推薦
評論