4回答

1收藏

GD32方案分享⑦:移植LDC1000电感传感器

GD32 GD32 6462 人阅读 | 4 人回复 | 2017-05-27

电感式传感是一种无接触、无磁体的传感技术,可精确测量金属或导电目标的位置、运动或成分,也可用于检测弹簧的压缩、拉伸或扭曲。在模拟半导体行业拥有近 20 年经验的德州仪器 (TI)传感器信号路径产品线经理Jon Baldwin向记者展示了LDC1000的优越性能,无论低成本 PCB 线迹或金属,亦或是人体传感,LDC1000都能 迅速传感并显示精确的结果。现有的传感器,如低成本的OHMIC开关传感器在灰尘等恶劣环境下不可靠,FSR压力传感器分辨率有限、不适合遥感、成本稍 高,高端一些的超成波传感器不适合短距离传感,电容式传感器灵敏度高可针对被选择物的选择性不高,HALL传感器存在精度问题、需要磁体和校准,光学传感 器在恶劣环境下不可靠,这些传感器都或多或少存在这样和那样的缺点,而TI此次推出的电感数字转换器颠覆了现有传感器的现状,在分辨率、精度、灵敏度、灵 活性等方面均优于传统的传感器类型,能给设计师带来更多的设计灵感。同时,Jon表示,由于LDC技术的优势明显,非常适合工厂流水线上的运动状态的传感 检测,在工业机器人及智能工厂等工业领域将发挥良好作用。
LDC 技术的主要优势:
? 更高的分辨率:可通过 16 位共振阻抗及 24 位电感值,在位置传感应用中实现亚微米级分辨率;
? 更高的可靠性:提供非接触传感技术避免受油污尘土等非导电污染物的影响,可延长设备使用寿命;
? 更高的灵活性:允许传感器远离电子产品安放,处于 PCB 无法安放的位置;
? 更低的系统成本:采用低成本传感器及传导目标,无需磁体;
? 无限可能性:支持压缩的金属薄片或导电油墨目标,可为创造性创新系统设计带来无限可能;
? 更低的系统功耗:标准工作时功耗不足 8.5mW,待机模式下功耗不足 1.25mW。
打算利用GD32做一个金属巡线小车,所以就上手来调一下这个传感器,模拟SPI,挺好移植的。


放入U盘 电感值有比较大的变化

  1. #include "include.h"

  2. extern int LDC_val;

  3. int main(void)
  4. {
  5.     systick_config();
  6.        
  7.           UART_Init(Debug_UART,115200);
  8.     LED_Init();          
  9.           LDC1000_Init();
  10.           while(1)
  11.          {
  12.                           LED_Troggle();
  13.                     LDC_val=LDC_Read_Avr()/10;//采样滤波
  14.                     printf("当前通道值:%d\r\n",LDC_val);
  15.     }
  16. }
复制代码

  1. #include "LDC1000.h"

  2. #define NN  20

  3. uint8 orgVal[12]={0};

  4. uint8 RPMAX =0x07;
  5. uint8 RPMIN =0x2f;
  6. uint8 RFREQ =0xA9;
  7. uint8 rpi_max=10;
  8. uint8 proximtyData[2]={0};
  9. unsigned long proximtyDataTEMP=0,proximtyDataMAX,proximtyDataMIN,proximtyDataSUM,proximtyDataAVE,proximtyDataAVE_LAS;
  10. unsigned long value_buf[NN],new_value_buf[NN];
  11. int LDC_val=0;


  12. void LDC1000_Init(void)
  13. {
  14.         while(orgVal[1]!=RPMAX||orgVal[2]!=RPMIN||orgVal[3]!=RFREQ)//一旦在此循环说明初始化不成功
  15.         {  
  16.                 LDC_SPI_init();   
  17.                 Delay_us(3000);
  18.                 LDC_Singal_SPI_Write(LDC1000_CMD_RPMAX,       RPMAX);
  19.                 LDC_Singal_SPI_Write(LDC1000_CMD_RPMIN,       RPMIN);//0x14
  20.                 LDC_Singal_SPI_Write(LDC1000_CMD_SENSORFREQ,  RFREQ);//谐振频率计算
  21.                 LDC_Singal_SPI_Write(LDC1000_CMD_LDCCONFIG,   0x17);  
  22.                 LDC_Singal_SPI_Write(LDC1000_CMD_CLKCONFIG,   0x00);//配置LDC1000的输出速率
  23.                 LDC_Singal_SPI_Write(LDC1000_CMD_THRESHILSB,  0x50);  
  24.                 LDC_Singal_SPI_Write(LDC1000_CMD_THRESHIMSB,  0x14);
  25.                 LDC_Singal_SPI_Write(LDC1000_CMD_THRESLOLSB,  0xC0);
  26.                 LDC_Singal_SPI_Write(LDC1000_CMD_THRESLOMSB,  0x12);
  27.                 LDC_Singal_SPI_Write(LDC1000_CMD_INTCONFIG,   0x02);
  28.                 LDC_Singal_SPI_Write(LDC1000_CMD_PWRCONFIG,   0x01);
  29.                 LDC_SPI_Read_Buf(LDC1000_CMD_REVID,&orgVal[0],12);  //orgVal[]对应上面写入的值说明初始化正常
  30.         }
  31. }

  32. int LDC_Read_Avr(void)
  33. {
  34.         char rpi=0;  //取rpi次平均值   
  35.         for (rpi=0;rpi<rpi_max;rpi++)
  36.         {
  37.                 LDC_SPI_Read_Buf(LDC1000_CMD_PROXLSB,&proximtyData[0],2);  
  38.                 proximtyDataTEMP = ((unsigned char)proximtyData[1]<<8) + proximtyData [0];
  39.                 proximtyDataSUM += proximtyDataTEMP;
  40.                 if (proximtyDataTEMP < proximtyDataMIN) //在100个proximtyDataTEMP中取最大,最小
  41.                 proximtyDataMIN = proximtyDataTEMP;
  42.                 if (proximtyDataTEMP > proximtyDataMAX)
  43.                 proximtyDataMAX = proximtyDataTEMP;
  44.         }
  45.         proximtyDataAVE = proximtyDataSUM /rpi_max;
  46.         proximtyDataSUM=0;
  47.         proximtyDataAVE_LAS=proximtyDataAVE;
  48.         return   proximtyDataAVE;
  49. }

  50. long int filter()
  51. {
  52.         char count,i,j,count1;
  53.         char count2=0;

  54.         long int temp;
  55.         long int sum=0;
  56.        
  57.         for(count=0;count<NN;count++)
  58.         {
  59.                 value_buf[count] = LDC_Read_Avr();
  60.         }
  61.        
  62.         for(count1=0;count1<NN;count1++)
  63.         {  
  64.                 if(value_buf[count1]<32768)
  65.                 {
  66.                         new_value_buf[count2]=value_buf[count1];
  67.                         count2++;
  68.                 }  
  69.         }
  70.        
  71.         for (j=0;j<count2-1;j++)
  72.         {
  73.                 for (i=0;i<count2-j;i++)
  74.                 {
  75.                         if ( new_value_buf[i]>new_value_buf[i+1] )
  76.                         {
  77.                                 temp = new_value_buf[i];
  78.                                 new_value_buf[i] = new_value_buf[i+1];
  79.                                 new_value_buf[i+1] = temp;
  80.                         }
  81.                 }
  82.         }
  83.         for(count=1;count<count2-1;count++)
  84.         {
  85.                 sum += new_value_buf[count];
  86.         }
  87.         return (long int)(sum/(count2-2));
  88. }

  89. void LDC_SPI_init(void)
  90. {   
  91.         GPIO_Init(LDC1000_PORT,MISO_Pin,Input);
  92.         GPIO_Init(LDC1000_PORT,SCK_Pin, PP_Output_L);       
  93.         GPIO_Init(LDC1000_PORT,MOSI_Pin,PP_Output_H);   
  94.         GPIO_Init(LDC1000_PORT,CSN_Pin, PP_Output_H);      
  95. }

  96. uint8 LDC_SPI_RW(uint8 rwdata)
  97. {   
  98.         uint8 spi_rw_i=0;       
  99.   uint8 temp=0;
  100.   for(spi_rw_i=0;spi_rw_i<8;spi_rw_i++)
  101. {
  102.               if(rwdata & 0x80)
  103.                                 { MOSI_H;}
  104.                      else  
  105.         { MOSI_L;}
  106.                      rwdata<<=1;                          
  107.         temp<<=1;
  108.                     SCK_H;            
  109.                      if(MISO) temp|=1;
  110.                      SCK_L;                       
  111.   }
  112.   return(temp);                                       
  113. }


  114. uint8 LDC_Singal_SPI_Read(uint8 reg)
  115. {
  116.         uint8 rdata;
  117.        
  118.         CSN_L;               
  119.    
  120.   Delay_us(2);   
  121.   
  122.   reg=reg|0x80;        
  123.         LDC_SPI_RW(reg);     
  124.         __asm("nop");
  125.         __asm("nop");
  126.         __asm("nop");
  127.         __asm("nop");
  128.         __asm("nop");
  129.         __asm("nop");
  130.         __asm("nop");
  131.         __asm("nop");
  132.         __asm("nop");
  133.         __asm("nop");
  134.         __asm("nop");
  135.         __asm("nop");
  136.         __asm("nop");
  137.         __asm("nop");
  138.         __asm("nop");
  139.         __asm("nop");
  140.         __asm("nop");
  141.         __asm("nop");
  142.         __asm("nop");
  143.         __asm("nop");
  144.         __asm("nop");
  145.          
  146.         rdata = LDC_SPI_RW(NULL);   
  147.       
  148.   Delay_us(1700);
  149.         CSN_H;               
  150.        
  151.         return rdata;        
  152. }

  153. void LDC_Singal_SPI_Write(uint8 reg,uint8 wdata)
  154. {
  155.        
  156.         CSN_L;               
  157.   Delay_us(2);
  158.   reg=reg&~0x80;
  159.         LDC_SPI_RW(reg);            
  160.         __asm("nop");
  161.         __asm("nop");
  162.         __asm("nop");
  163.         __asm("nop");
  164.         __asm("nop");
  165.         __asm("nop");
  166.         __asm("nop");
  167.         __asm("nop");
  168.         __asm("nop");
  169.         __asm("nop");
  170.         __asm("nop");
  171.         __asm("nop");
  172.         __asm("nop");
  173.         __asm("nop");
  174.         __asm("nop");
  175.         __asm("nop");
  176.         __asm("nop");
  177.         __asm("nop");
  178.         __asm("nop");
  179.         __asm("nop");
  180.         __asm("nop");
  181.         
  182.         LDC_SPI_RW(wdata);   
  183.   Delay_us(1700);
  184.         CSN_H;                     
  185. }

  186. void LDC_SPI_Read_Buf(uint8 reg, uint8 *pBuf, uint8 len)
  187. {
  188.         uint8 spi_rw_i;
  189.        
  190.         CSN_L;                          
  191.       
  192.   reg=reg|0x80;            
  193.         LDC_SPI_RW(reg);                      
  194.        
  195.         for(spi_rw_i=0;spi_rw_i<len;spi_rw_i++)
  196.         {  
  197.                 pBuf[spi_rw_i] = LDC_SPI_RW(NULL);   
  198.         }
  199.         CSN_H;      
  200. }
复制代码

  1. #ifndef _LDC1000_H_
  2. #define _LDC1000_H_

  3. #include "gpio.h"
  4. #include "systick.h"

  5. #define LDC1000_PORT GPIOD

  6. #define MISO_Pin  GPIO_PIN_3
  7. #define MOSI_Pin  GPIO_PIN_4
  8. #define CSN_Pin   GPIO_PIN_5
  9. #define SCK_Pin   GPIO_PIN_6

  10. #define MISO    gpio_input_bit_get(LDC1000_PORT, MISO_Pin)

  11. #define MOSI_H  GPIO_BOP(LDC1000_PORT)=MOSI_Pin;
  12. #define MOSI_L  GPIO_BC(LDC1000_PORT)=MOSI_Pin;

  13. #define CSN_H   GPIO_BOP(LDC1000_PORT)=CSN_Pin;
  14. #define CSN_L   GPIO_BC(LDC1000_PORT)=CSN_Pin;

  15. #define SCK_H   GPIO_BOP(LDC1000_PORT)=SCK_Pin;
  16. #define SCK_L   GPIO_BC(LDC1000_PORT)=SCK_Pin;

  17. void LDC1000_Init(void);
  18. int LDC_Read_Avr(void);
  19. long int Filter(void);

  20. void LDC_SPI_init(void);
  21. uint8 LDC_SPI_RW(uint8 rwdata);
  22. uint8 LDC_Singal_SPI_Read(uint8 reg);
  23. void LDC_Singal_SPI_Write(uint8 reg,uint8 wdata);
  24. void LDC_SPI_Read_Buf(uint8 reg, uint8 *pBuf, uint8 len);


  25. //LDC1000指令
  26. #define LDC1000_CMD_REVID      0x00
  27. #define LDC1000_CMD_RPMAX             0x01
  28. #define LDC1000_CMD_RPMIN             0x02
  29. #define LDC1000_CMD_SENSORFREQ         0x03//谐振频率
  30. #define LDC1000_CMD_LDCCONFIG         0x04
  31. #define LDC1000_CMD_CLKCONFIG         0x05
  32. #define LDC1000_CMD_THRESHILSB         0x06
  33. #define LDC1000_CMD_THRESHIMSB         0x07
  34. #define LDC1000_CMD_THRESLOLSB         0x08
  35. #define LDC1000_CMD_THRESLOMSB         0x09
  36. #define LDC1000_CMD_INTCONFIG         0x0A
  37. #define LDC1000_CMD_PWRCONFIG         0x0B
  38. #define LDC1000_CMD_STATUS            0x20
  39. #define LDC1000_CMD_PROXLSB           0x21
  40. #define LDC1000_CMD_PROXMSB           0x22
  41. #define LDC1000_CMD_FREQCTRLSB        0x23
  42. #define LDC1000_CMD_FREQCTRMID        0x24
  43. #define LDC1000_CMD_FREQCTRMSB        0x25

  44. //LDC1000寄存器
  45. #define LDC1000_BIT_AMPLITUDE    0x18
  46. #define LDC1000_BIT_RESPTIME     0x07
  47. #define LDC1000_BIT_CLKSEL       0x02
  48. #define LDC1000_BIT_CLKPD        0x01
  49. #define LDC1000_BIT_INTMODE      0x07
  50. #define LDC1000_BIT_PWRMODE      0x01
  51. #define LDC1000_BIT_STATUSOSC    0x80
  52. #define LDC1000_BIT_STATUSDRDYB  0x40
  53. #define LDC1000_BIT_STATUSWAKEUP 0x20
  54. #define LDC1000_BIT_STATUSCOMP   0x10

  55. #endif

  56. /*----------------------------end of LDC1000.h-------------------------------*/
复制代码
附件:
myGD32 - 副本.rar (7.24 MB, 下载次数: 9)

分享到:
回复

使用道具 举报

回答|共 4 个

倒序浏览

沙发

jwdxu2009

发表于 2017-5-28 16:09:40 | 只看该作者

参考和学习
板凳

suoma

发表于 2017-5-29 11:03:50 | 只看该作者

这个传感器多少钱?有购买链接吗?
地板

何昌昕

发表于 2017-5-29 15:20:27 | 只看该作者

suoma 发表于 2017-5-29 11:03
这个传感器多少钱?有购买链接吗?

https://item.taobao.com/item.htm?spm=a1z10.3-c.w4002-12409390230.10.P0zpen&id=526022465507
建议自己制作 TI的LDC1000才20块钱一片 买模块太亏 我这个也是收的二手的 花了60 一点也不值
5#

suoma

发表于 2017-5-30 08:53:10 | 只看该作者

何昌昕 发表于 2017-5-29 15:20
https://item.taobao.com/item.htm?spm=a1z10.3-c.w4002-12409390230.10.P0zpen&id=526022465507
建议自 ...

好的,谢谢
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条