我一直在研究一系列PSoC 6项目,以准备一些新视频并在Embedded World上使用。对于其中一个项目,我需要一个动作敏感的遥控器......并且我们很方便地将一台博世BMI160运动传感器放到了CY8CKIT-062-BLE开发套件随附的新CY8CKIT-028-EPD屏蔽罩上。
在本文中,我将向您展示如何使用PSoC 6制作完整的测试系统来与BMI160进行通话。步骤是:
-
克隆博世BMI160驱动程序库
-
创建一个新的PSoC 6项目并添加驱动程序库
-
为博世驱动程序创建HAL
-
创建主要固件并进行测试
克隆博世BMI160驱动程序库
当我开始这个时,我知道董事会有一个运动传感器,但我不知道是什么样的。我假设它是基于I2C的传感器,所以我连接了桥接控制面板并探测I2C总线。但是这就是它所说的:
那么......到底什么?然后,我看了看董事会,试图弄清楚发生了什么......低下,看看......我的电路板是在添加运动传感器之前完成的原型。这里是:
这里是一块带有传感器的电路板。
当我插入该板并使用Bridge Control Panel进行测试时,我会得到:
接下来我做的就是看原理图。OK,您可以看到惯性测量单元(IMU)是连接到I2C总线的BMI160。另一件很酷的事情是,devkit团队连接了两条中断线。这些线路通常用于IMU向PSoC 6发送信号(例如,用户可能开始移动)。
查看原理图后,下一步是查看BMI160数据表并尝试弄清楚如何与设备进行连接。通常这些设备有一堆寄存器,其位数字段的数量令人难以置信。这一直是这个过程中不好玩的部分。但是这次当我去博世网站上的BMI160设备页面时,有一个按钮显示“文档和驱动程序”,当您点击它时,会有一个链接到BMI160驱动程序的GitHub。得分了!
要做到这一点,你只需要“git clonegit@github.com:BoschSensortec / BMI160_driver.git”
使用博世BMI160驱动程序库创建新的PSoC 6项目
所以,让我们继续测试它。首先创建一个新的PSoC 63项目
使用空白示意图
给它一个名字
添加Retarget I / O和FreeRTOS(从构建设置菜单中)
添加一个UART和一个I2C主控
要使I2C成为主设备,您需要双击并将其更改为主设备
然后分配引脚
运行“构建 - >生成应用程序”来获得您需要的所有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项目的包含路径。(要进入此菜单,请右键单击该项目并选择“构建设置”)
将Bosch Driver文件添加到项目中
为博世驱动程序创建HAL
使用博世驱动器很简单。你所需要做的就是更新HAL。
-
提供写入I2C寄存器的功能
-
提供读取I2C寄存器的功能
-
提供延迟指定毫秒数的功能
-
创建一个结构来保存初始化信息和函数指针
该器件实现了赛普拉斯所称的“EZI2C”协议,该协议也称为I2C EEPROM协议。该器件被组织为一系列寄存器。每个寄存器都有一个从0-> 0xFF(单字节地址)的地址。要写入注册表,您需要
-
发送I2C启动
-
发送7位I2C地址
-
发送一个写入位(aka a 0)
-
发送要写入的寄存器地址(不要将I2C地址与内部BMI160地址混淆)
-
发送您想要写入的8位值
-
发送一个停止
EZI2C的一个很酷的事情是,它可以跟踪地址,并在每次写入时自动递增寄存器地址。这意味着您可以编写一个地址序列,而无需为每个地址执行完整的事务。
鉴于引入写函数很简单:
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为了阅读你做一个类似的交易来写。具体的步骤是:
发送I2C启动
发送7位I2c地址
发送一个WRITE位aka 0
发送您想要读取的寄存器地址
发送I2C重新启动
读一个字节
发送NAK
发送一个停止
读取事务与写入类似,您可以通过发送ACK继续读取连续字节。您读取的最后一个字节应该是NAK,以告诉远程设备您正在读取。鉴于代码也很简单。
//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我的读写功能都有一个错误。那个错误是?没有错误检查。我看到了一些间歇性的奇怪现象,其中I2C总线被锁定,最终需要重置才能修复。这可以通过检查I2C功能上的错误代码来防止。
既然我们有读写功能,我们可以设置我们的设备:要做到这一点:
设置一个类型为bmi160_dev的结构
初始化函数指针
初始化设备的设置
最后发送设置
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]. "); } }创建主要固件并进行测试
最后,我通过运行打印出加速数据的无限循环来测试固件。
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); } }现在你应该有这样的:
最后整个节目一举成名
#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
+关注
关注
12文章
170浏览量
91880 -
BMI160
+关注
关注
1文章
7浏览量
8005
发布评论请先 登录
相关推荐
评论