本文基于rtt的iic驱动框架来实现加速度传感器数据的读取测试,废话不多说开启正文。
1.编译RT-thread加入I2c框架相关代码本实验使用的是官方代码中已经值支持bsp(\rt-thread\bsp\stm32\stm32l476-st-nucleo),默认的配置是没有组入软件IIC的软件框架。使用RTT 的ENV 工具很容易就可以将IIC软件框架代码组入系统,组入方法如下,在BSP目录下使用env工具,输入menuconfig。
配置路径如下:
即可开启I2C,并配置SCL,SDA对应的引脚ID即可。配置完成后,运行SCONS即可发现相关的IIC代码文件已经参与编译了,我的配置如下。
2.适配加速度传感器,按照上一篇IIC驱动框架的理解,使用的时只要使用rt_i2c_bus_device_find查找对应的I2C设备,试验配置的名称为“i2c1”,找到相应的设备后调用rt_i2c_transfer 函数即可操作i2c总线的读和写操作了,所有的基于I2C总线的操作驱动框架已经集成,只需要用户实现芯片相关的配置即可而不用关心IIC协议的具体细节。适配过程中遇到两个问题。
①i2c的地址问题,发送结合接收时地址设置为芯片手册对应的7bit地址值即可,开始的时候读和写操做设置的地址为实际的8位地址,总是应答NACK,跟了下代码发现底层代码会根据读写操做自动设定地址,自己的操作存粹是多此一举。
②因硬件上未配置总线上拉电阻,造作总线的时候总是失败,默认的IO配置的开漏输出是没有配置内部上拉的,所以总是失败,配置成内部上拉后总线就可以正常通信了。
3.相关的测试代码如下:
①初始化KX224
- static rt_uint32_t _g_sens;
- struct rt_i2c_bus_device* bus = NULL;
- static void kx224_init(void)
- {
- rt_uint8_t deviceid = 0,reg = 0,gsel = 0;
-
- bus = rt_i2c_bus_device_find("i2c1");
- if(!bus)
- {
- rt_kprintf("can't find i2c device\n");
- return;
- }
- write_cmd(bus,KX224_WHO_AM_I);
- red_reg(bus,1,&deviceid);
- if(deviceid != KX224_WAI_VAL)
- {
- rt_kprintf("can't find device\n");
- return;
- }
- write_reg(bus,KX224_CNTL1,KX224_CNTL1_VAL);
- write_reg(bus,KX224_ODCNTL,KX224_ODCNTL_VAL);
- write_cmd(bus,KX224_CNTL1);
- red_reg(bus,1,®);
- gsel = reg & KX224_CNTL1_GSELMASK;
- rt_kprintf("reg is 0x%02x gsel is 0x%02x\n",reg,gsel);
- reg |= KX224_CNTL1_PC1;
- write_reg(bus,KX224_CNTL1, reg);
- switch(gsel) {
- case KX224_CNTL1_GSEL_8G :
- // (Equivalent counts) / (Range) = (32768 / 8)
- _g_sens = 4096;
- break;
- case KX224_CNTL1_GSEL_16G :
- // (Equivalent counts) / (Range) = (32768 / 16)
- _g_sens = 2048;
- break;
- case KX224_CNTL1_GSEL_32G :
- // (Equivalent counts) / (Range) = (32768 / 32)
- _g_sens = 1024;
- break;
- default:
- break;
- }
- rt_kprintf("_g_sens is <%d>\n",_g_sens);
- }
复制代码
②i2c总线的读写操
- static rt_err_t write_reg(struct rt_i2c_bus_device *bus,rt_uint8_t reg,rt_uint8_t data)
- {
- struct rt_i2c_msg msgs;
- rt_uint8_t buff[2];
- rt_size_t size = 0;
-
- buff[0] = reg;
- buff[1] = data;
- msgs.addr = KX224_DEVICE_ADDRESS_1E;
- msgs.flags = RT_I2C_WR;
- msgs.buf = buff;
- msgs.len = 2;
- if( rt_i2c_transfer(bus, &msgs, 1))
- {
- return RT_EOK;
- }
- else
- {
- return -RT_ERROR;
- }
- }
- static rt_err_t write_cmd(struct rt_i2c_bus_device *bus,rt_uint8_t reg)
- {
- struct rt_i2c_msg msgs;
- rt_uint8_t buff[2];
- rt_size_t size = 0;
-
- buff[0] = reg;
- msgs.addr = KX224_DEVICE_ADDRESS_1E;
- msgs.flags = RT_I2C_WR;
- msgs.buf = buff;
- msgs.len = 1;
- if(rt_i2c_transfer(bus, &msgs, 1))
- {
- return RT_EOK;
- }
- else
- {
- return -RT_ERROR;
- }
- }
- static rt_err_t red_reg(struct rt_i2c_bus_device *bus,rt_uint8_t len,rt_uint8_t * buf)
- {
- struct rt_i2c_msg msgs;
- rt_size_t size = 0;
-
- msgs.addr = KX224_DEVICE_ADDRESS_1E;
- msgs.flags = RT_I2C_RD;
- msgs.buf = buf;
- msgs.len = len;
- if(rt_i2c_transfer(bus, &msgs, 1))
- {
- return RT_EOK;
- }
- else
- {
- return -RT_ERROR;
- }
- }
复制代码
下载运行后发现能够获得数据了,数据的准确性后续在进行研究。
|
金币追加的速度啊