如何使用PSoC 6制作完整的测试系统来与BMI160进行通话

我一直在研究一系列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找到正确的位置)
#includeproject.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); } } 现在你应该有这样的:
最后整个节目一举成名
#includeproject.h #includefreertos.h #includetask.h #include #includebmi160.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 亿华通如何冲破燃料电池发展困境
成套购买成品质消费趋势:高端套系家电“璀璨”获上万忠粉
微软与小米、有人基金会达成合作 共同助力残障人士成就不凡
人脸识别市场虽然处于一个刚起步的阶段,但未来前景可期
峰会回顾第12期 | Wasm软件生态系统安全分析
如何使用PSoC 6制作完整的测试系统来与BMI160进行通话
植保无人机出现动力饱和的原因有哪些,该如何避免和解决
道尔芬智能在“创响江苏”扬州分赛中喜获二等奖并成功晋级省赛
5G车联网谁更具有行业优势
探索物联网HMI的端口转发和NAT功能
三阶高通滤波器具有合成电感器
首批7家湖北实验室集中揭牌
基于Python实现随机森林算法
混合动力车用锂离子电容器的开发
台积电4nm工艺2022年大规模量产_3nm工艺也在开发中
新华三已正式将大互联战略升级为数字化联接战略
东风汽车首款量产车明日正式首发:增程动力系统、续航可达860km
压摆率与大信号带宽(满功率带宽)的关系
FCA3000/3100系列计时器的功能特点及应用
Freescale的夜视,智能前灯控制和车道保持系统设计