请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【年中粉丝节】STM32L476开发板-基于rtthread读取加速度传感器KX224数据

[复制链接]
andey 发布时间:2021-6-8 15:38
本文基于rtt的iic驱动框架来实现加速度传感器数据的读取测试,废话不多说开启正文。

1.编译RT-thread加入I2c框架相关代码本实验使用的是官方代码中已经值支持bsp(\rt-thread\bsp\stm32\stm32l476-st-nucleo),默认的配置是没有组入软件IIC的软件框架。使用RTT 的ENV 工具很容易就可以将IIC软件框架代码组入系统,组入方法如下,在BSP目录下使用env工具,输入menuconfig。

menuconfig.png


配置路径如下:



i2c1.png


即可开启I2C,并配置SCL,SDA对应的引脚ID即可。配置完成后,运行SCONS即可发现相关的IIC代码文件已经参与编译了,我的配置如下。

config.png


2.适配加速度传感器,按照上一篇IIC驱动框架的理解,使用的时只要使用rt_i2c_bus_device_find查找对应的I2C设备,试验配置的名称为“i2c1”,找到相应的设备后调用rt_i2c_transfer 函数即可操作i2c总线的读和写操作了,所有的基于I2C总线的操作驱动框架已经集成,只需要用户实现芯片相关的配置即可而不用关心IIC协议的具体细节。适配过程中遇到两个问题。
①i2c的地址问题,发送结合接收时地址设置为芯片手册对应的7bit地址值即可,开始的时候读和写操做设置的地址为实际的8位地址,总是应答NACK,跟了下代码发现底层代码会根据读写操做自动设定地址,自己的操作存粹是多此一举。
②因硬件上未配置总线上拉电阻,造作总线的时候总是失败,默认的IO配置的开漏输出是没有配置内部上拉的,所以总是失败,配置成内部上拉后总线就可以正常通信了。



iicSHIXU.png


iictime.png

3.相关的测试代码如下:
①初始化KX224

  1. static rt_uint32_t _g_sens;
  2. struct rt_i2c_bus_device* bus = NULL;

  3. static void kx224_init(void)
  4. {
  5.         rt_uint8_t deviceid = 0,reg = 0,gsel = 0;
  6.         
  7.     bus = rt_i2c_bus_device_find("i2c1");
  8.         if(!bus)
  9.         {
  10.                 rt_kprintf("can't find i2c device\n");
  11.                 return;
  12.         }
  13.         write_cmd(bus,KX224_WHO_AM_I);
  14.         red_reg(bus,1,&deviceid);
  15.         if(deviceid != KX224_WAI_VAL)
  16.         {
  17.                 rt_kprintf("can't find device\n");
  18.                 return;
  19.         }
  20.           write_reg(bus,KX224_CNTL1,KX224_CNTL1_VAL);
  21.         write_reg(bus,KX224_ODCNTL,KX224_ODCNTL_VAL);
  22.         write_cmd(bus,KX224_CNTL1);
  23.         red_reg(bus,1,®);
  24.         gsel = reg & KX224_CNTL1_GSELMASK;
  25.         rt_kprintf("reg is 0x%02x gsel is 0x%02x\n",reg,gsel);
  26.         reg |= KX224_CNTL1_PC1;
  27.         write_reg(bus,KX224_CNTL1, reg);
  28.         switch(gsel) {
  29.     case KX224_CNTL1_GSEL_8G :
  30.       // (Equivalent counts) / (Range) = (32768 / 8)
  31.       _g_sens = 4096;
  32.     break;

  33.     case KX224_CNTL1_GSEL_16G :
  34.       // (Equivalent counts) / (Range) = (32768 / 16)
  35.       _g_sens = 2048;
  36.     break;

  37.     case KX224_CNTL1_GSEL_32G :
  38.       // (Equivalent counts) / (Range) = (32768 / 32)
  39.       _g_sens = 1024;
  40.     break;

  41.     default:
  42.     break;
  43.   }
  44.   rt_kprintf("_g_sens is <%d>\n",_g_sens);        
  45. }
复制代码


②i2c总线的读写操

  1. static rt_err_t write_reg(struct rt_i2c_bus_device *bus,rt_uint8_t reg,rt_uint8_t data)
  2. {
  3.         struct rt_i2c_msg msgs;
  4.         rt_uint8_t buff[2];
  5.         rt_size_t size = 0;
  6.         
  7.         buff[0] = reg;
  8.         buff[1] = data;

  9.         msgs.addr = KX224_DEVICE_ADDRESS_1E;
  10.         msgs.flags = RT_I2C_WR;
  11.         msgs.buf = buff;
  12.         msgs.len = 2;

  13.         if( rt_i2c_transfer(bus, &msgs, 1))
  14.         {
  15.                 return RT_EOK;
  16.         }
  17.         else
  18.         {
  19.                 return -RT_ERROR;
  20.         }
  21. }

  22. static rt_err_t write_cmd(struct rt_i2c_bus_device *bus,rt_uint8_t reg)
  23. {
  24.         struct rt_i2c_msg msgs;
  25.         rt_uint8_t buff[2];
  26.         rt_size_t size = 0;
  27.         
  28.         buff[0] = reg;

  29.         msgs.addr = KX224_DEVICE_ADDRESS_1E;
  30.         msgs.flags = RT_I2C_WR;
  31.         msgs.buf = buff;
  32.         msgs.len = 1;

  33.         if(rt_i2c_transfer(bus, &msgs, 1))
  34.         {
  35.                 return RT_EOK;
  36.         }
  37.         else
  38.         {
  39.                 return -RT_ERROR;
  40.         }
  41. }


  42. static rt_err_t red_reg(struct rt_i2c_bus_device *bus,rt_uint8_t len,rt_uint8_t * buf)
  43. {
  44.         struct rt_i2c_msg msgs;
  45.         rt_size_t size = 0;
  46.         
  47.         msgs.addr = KX224_DEVICE_ADDRESS_1E;
  48.         msgs.flags = RT_I2C_RD;
  49.         msgs.buf = buf;
  50.         msgs.len = len;

  51.         if(rt_i2c_transfer(bus, &msgs, 1))
  52.         {
  53.                 return RT_EOK;
  54.         }
  55.         else
  56.         {
  57.                 return -RT_ERROR;
  58.         }
  59. }
复制代码


下载运行后发现能够获得数据了,数据的准确性后续在进行研究。



board_iic.jpg


acc.png



收藏 评论2 发布时间:2021-6-8 15:38

举报

2个回答
STMCU-管管 回答时间:2021-6-8 17:43:05
感谢分享,金币已增加
andey 回答时间:2021-6-9 16:04:29
STMCU-管管 发表于 2021-6-8 17:43
感谢分享,金币已增加

金币追加的速度啊
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版