当前位置:   article > 正文

传感器_芯片级传感器和功能芯片的使用和编程思路_文字描述传感器软件程序设计的思路

文字描述传感器软件程序设计的思路

芯片级的传感器(如ICM-26090)和某些功能芯片(如DAC芯片:DAC81404),在编程使用时,往往会陷入一种迷茫的境地,有点恐惧。因为往往它的参考手册长的更一本书一样。主要原因时很多芯片为了兼容各种应用场景,拥有很多我们不需要的冗余功能。

其实这些芯片用起来不难,一般来讲我们的主控芯片都可以通过SPI/I2C等通信接口,去配置这些芯片,读写芯片里的寄存器。 只要按照正确合适的方式,配置好芯片内部的某些寄存器,就能正常操作了。这与直接操作主控芯片的寄存器只是多了一个操作的方式。 主控芯片的寄存器,可以直接读写。 而传感器芯片和功能芯片需用用SPI/I2C等通信方式去操作芯片的寄存器。 下面介绍通用的一种编程思路。

1、第一步

用传感器芯片或功能芯片的型号去网上下载它的参考手册。下到手册后,先看看它的功能介绍,特性介绍,了解这个芯片是干什么的,有什么特性。下面拿ICM-26090来举例说明。

 

 然后通篇拉通了浏览一遍,看看主芯片控制它是用什么通信方式,通信协议是怎样的。

 

本例中的芯片可以使用I2C和SPI两种通信方式,通信协议也找到了,如上图所示。

最后就是找到芯片需要操作的寄存器。

不必细读,找到了,你的第一步就完成了。

2、第二步

2.1、读设备ID

第二步主要完成一个通信测试,比如你用的SPI通信方式,协议你也知道了。编程的第一步就是先试试能不能通信。所以要进行通信测试,有个很妙的东西,就是基本上这些功能芯片都有一个可以读的东西(设备ID什么的)。

比如ICM-20690芯片里面有个WHO_AM_I寄存器

 比如DAC81404芯片里,有个DEVICEID寄存器

所以你通信的第一步,就是把设备ID读出来。

2.2、测试写入功能

如果你设备ID读对了,那你就可以测试写入了。根据通信协议,把(寄存器地址+写指令)+写的数据,写入某一个可读可写的寄存器(R/W), 写了之后,你又可以再读回来,看是否是你刚刚写入的数据。因为你在上一步已经通过读设备ID验证了读的功能,所以现在就是测试写功能。 写功能如果出了问题,可以看看通信协议和时序等相关内容。【我遇到的用SPI通信的芯片,你要写入数据时,你的(寄存器地址+写指令)+写的数据都是连续发送的,不能说写一个字节读一个字节,再写一个字节读一个字节,用这种断断续续的操作】 ,再不行,借助示波器看看你的输出信号。

2.3、封装芯片读写操作的函数

当你读写都没问题了,你就可以把读/写芯片的操作函数封装起来。 以便于进一步的使用。

如:

  1. void SPI_A_READ(unsigned char addr, unsigned char * Rxdata){
  2. spi_cs_A_Enable;
  3. HAL_SPI_Transmit(&hspi1,&addr,1,100);
  4. HAL_SPI_Receive(&hspi1,Rxdata,1,100);
  5. spi_cs_A_Disable;
  6. }
  7. void SPI_A_WRITE(unsigned char addr, unsigned char Txdata){
  8. unsigned char Rxdata=0x00;
  9. spi_cs_A_Enable;
  10. HAL_SPI_Transmit(&hspi1,&addr,1,100);
  11. HAL_SPI_Transmit(&hspi1,&Txdata,1,100); // 经测试,地址字节和数据字节必须连续发送。 否则无法正常写入
  12. // 接不接收都可以,接收的数据是无用的,但稳妥起见,还是接一下吧
  13. HAL_SPI_Receive(&hspi1,&Rxdata,1,100);
  14. HAL_SPI_Receive(&hspi1,&Rxdata,1,100);
  15. spi_cs_A_Disable;
  16. }

3、第三步

第三步,是最后一步,也是最难的一步。就是配置芯片寄存器。这个没有什么捷径,这是避无可避的。

但我认为最有效的办法,就是把每一个需配置的寄存器(有些寄存器是只读的,那就不用配置,有些寄存器是与配置无关的,比如记录传感器最终的测量输出的寄存器)都配置一遍,穷举所有可配置的寄存器。

我一般就是把每一个寄存器的地址,全部都用宏定义先抄下来。

然后写一个config函数,比如ICM-20690芯片,就叫icm20690_config函数。

把每个需要配置的寄存器,挨个配置一遍。配置的时候,就读一读这个寄存器是啥意思。

穷举所有可配置的寄存器,劳资全部给他配置一遍,最稳妥。 很多芯片看着吓人,寄存器数量很多的,但其实很多都是冗余的,别虚。

如:

  1. void icm20690_config(void){
  2. // register: SMPLRT_DIV
  3. // This register is only effective when FCHOICE_B register bits are 2’b00, and (0 < DLPF_CFG < 7).
  4. // register: CONFIG
  5. // FIFO_MODE - 0
  6. // EXT_SYNC_SET - 0
  7. // DLPF_CFG - 0 250Hz 0.97ms 8KhZ FCHOICE_B(0 0)
  8. SPI_A_WRITE(CONFIG_ADDR_W,0x00);
  9. // register: GYRO_CONFIG
  10. // XG_ST YG_ST ZG_ST 0
  11. // FS_SEL 0 250dps
  12. // FCHOICE_B (2'b00)
  13. SPI_A_WRITE(GYRO_CONFIG_ADDR_W,0x00);
  14. // register: ACCEL_CONFIG
  15. // XA_ST YA_ST ZA_ST 0
  16. // AFS_SEL 00 ±2g
  17. // AFS_SEL_OIS 00 ±2g
  18. SPI_A_WRITE(ACCEL_CONFIG_ADDR_W,0x00);
  19. // register: ACCEL_CONFIG2
  20. // FIFO_SIZE 00 128byte
  21. // DEC2_CFG 3 32x averaging filter
  22. // ACCEL_FCHOICE_B 0
  23. // A_DLPF_CFG 7 420Hz 1.38ms 1Hz
  24. SPI_A_WRITE(ACCEL_CONFIG_2_ADDR_W,0x37);
  25. // register: LP_MODE_CONFIG
  26. // GYRO_CYCLE 0 low-power gyroscope mode is disable
  27. // GYRO_AVGCFG 111b = 7H 128x averaging filter
  28. SPI_A_WRITE(LP_MODE_CONFIG_ADDR_W,0x70);
  29. // register: FIFO_EN
  30. // TEMP_OUT 1 GYRO_XOUT 1 GYRO_YOUT 1 GYRO_ZOUT 1 ACCEL_XYZ_OUT 1
  31. SPI_A_WRITE(FIFO_EN_ADDR_W,0xF8);
  32. // register: ODR_DELAY_EN
  33. // ODR_DELAY_EN 0 Function is disabled.
  34. SPI_A_WRITE(ODR_DELAY_EN_ADDR_W,0x00);
  35. // register:INT_ENABLE
  36. SPI_A_WRITE(INT_ENABLE_ADDR_W,0x00);
  37. // register:FIFO_WM_TH
  38. SPI_A_WRITE(FIFO_WM_TH_ADDR_W,0x00); // If zero then watermark interrupt is disabled.
  39. // register:PWR_MGMT_1 2
  40. SPI_A_WRITE(PWR_MGMT_1_ADDR_W,0x00);
  41. SPI_A_WRITE(PWR_MGMT_2_ADDR_W,0x00);
  42. }

4、第四步

第四步,其实不说都知道,就是测试你的配置起作用了没有,比如传感器芯片,你就把传感器输出读出来。动动你的设备,看看传感器输出有没有? 对不对? 美滋滋啊。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/633158
推荐阅读
相关标签
  

闽ICP备14008679号