在线时间169 小时
UID3338155
ROHM金币80
注册时间2018-5-4
该用户从未签到
高级会员
- 最后登录
- 2024-3-25
|
本帖最后由 andeyqi 于 2021-6-8 15:28 编辑
https://rohm.eefocus.com/module/forum/forum.php?mod=viewthread&tid=621872&page=1&extra=#pid2388753
如上帖子已经对rtt的i2c框架进行了分析理解,在上述的基础上将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;
- }
- }
复制代码 ③.读取数据
- void KX224_get_rawval(unsigned char *data)
- {
- write_cmd(bus,KX224_XOUT_L);
- red_reg(bus,6,data);
- }
- void KX224_get_val(rt_uint8_t *data)
- {
- rt_uint8_t val[6] = {0};
- rt_uint16_t acc[3] = {0};
- KX224_get_rawval(val);
- acc[0] = ((signed short)val[1] << 8) | (val[0]);
- acc[1] = ((signed short)val[3] << 8) | (val[2]);
- acc[2] = ((signed short)val[5] << 8) | (val[4]);
- // Convert LSB to g
- data[0] = acc[0] / _g_sens;
- data[1] = acc[1] / _g_sens;
- data[2] = acc[2] / _g_sens;
- rt_kprintf("acc x [%d] y [%d] z [%d]\n",acc[0],acc[1],acc[2]);
- }
复制代码
下载运行后发现能够获得数据了,数据的准确性后续在进行研究。
程序如下:
applications.zip
(2.63 KB, 下载次数: 4)
|
|