找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2296|回复: 1
收起左侧

FDC2214模块PCB加stm32单片机驱动源码(已测试)

[复制链接]
ID:547792 发表于 2022-2-10 16:58 | 显示全部楼层 |阅读模式
FDC2214模块,有TI的测试版修改而来。有stm32驱动和FDC源码和pcb文件
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件) 1.PNG 2.PNG

单片机源程序如下:
  1. #include "delay.h"
  2. #include "sys.h"
  3. #include "stdio.h"
  4. #include "usart.h"
  5. #include "timer.h"
  6. #include "FDC2214.h"

  7. void FDC2214_GetData(void);
  8. u32 ch0,ch1,ch2,ch3;

  9. int main(void)
  10. {        
  11.         delay_init();//延时函数初始化        
  12.     uart_init(921600);//串口初始化   
  13.     TIM1_36Mhz_Init();//stm32定时器1输出一个36mhz方波,作为fdc2214的时钟。如果板载了40mhz的晶振,这个就不需要了。
  14.    
  15.     IIC_Init();
  16.     FDC2214_Init();
  17.         while(1)
  18.         {
  19.         FDC2214_GetData();
  20.         printf("\r\nCH0~3(%d , %d , %d , %d)",ch0,ch1,ch2,ch3);
  21.                 delay_ms(500);         //延时300ms
  22.         }
  23. }




  24. void FDC2214_GetData(void)
  25. {
  26.     FDC2214_GetChannelData(FDC2214_Channel_0, &ch0);  
  27.     FDC2214_GetChannelData(FDC2214_Channel_1, &ch1);
  28.     FDC2214_GetChannelData(FDC2214_Channel_2, &ch2);
  29.     FDC2214_GetChannelData(FDC2214_Channel_3, &ch3);
  30. }
复制代码
  1. #include "FDC2214.h"

  2. #define PI 3.14159265358979323846
  3. #define ClockFrequency   36000000 //时钟频率

  4. uint8_t CHx_FIN_SEL[4];
  5. double fREFx[4];


  6. /*!
  7. *  @brief      IIC写FDC2214
  8. *  @param      Slve_Addr     器件地址
  9. *  @param      reg           寄存器
  10. *  @param      data          数据
  11. *  @since      v1.0
  12. *  Sample usage:       FDC2214_Write16(FDC2214_Addr, FDC2214_CONFIG, 0xFFFF);
  13. */
  14. void FDC2214_Write16(uint8_t Slve_Addr, uint8_t reg, uint16_t data)
  15. {
  16.     u8 dat;
  17.     IIC_Start();
  18.    
  19.     IIC_Send_Byte(Slve_Addr << 1);
  20.     IIC_Wait_Ack();
  21.    
  22.     IIC_Send_Byte(reg);
  23.     IIC_Wait_Ack();
  24.    
  25.     dat=(data >> 8);
  26.     IIC_Send_Byte(dat);
  27.     IIC_Wait_Ack();
  28.    
  29.     dat=data & 0xFF;
  30.     IIC_Send_Byte(dat);
  31.     IIC_Wait_Ack();
  32.    
  33.     IIC_Stop();
  34. }

  35. /*!
  36. *  @brief      IIC读FDC2214
  37. *  @param      Slve_Addr     器件地址
  38. *  @param      reg           寄存器
  39. *  @return     寄存器值
  40. *  @since      v1.0
  41. *  Sample usage:       FDC2214_Read16(FDC2214_Addr, FDC2214_CONFIG);
  42. */
  43. uint16_t FDC2214_Read16(uint8_t Slve_Addr, uint8_t reg)
  44. {
  45.     uint16_t temp;

  46.     IIC_Start();
  47.     IIC_Send_Byte(Slve_Addr << 1);
  48.     IIC_Wait_Ack();
  49.     IIC_Send_Byte(reg);
  50.     IIC_Wait_Ack();
  51.     IIC_Start();
  52.     IIC_Send_Byte((Slve_Addr << 1) | 0x01);
  53.     IIC_Wait_Ack();
  54.     temp = (uint16_t)(IIC_Read_Byte(1) << 8);
  55.     temp |= IIC_Read_Byte(0);
  56.     IIC_Stop();
  57.    
  58.     return temp;
  59. }

  60. /*!
  61. *  @brief      读取FDC2214一个通道的转换值
  62. *  @param      channel     通道
  63. *  @param      *data       读取的数据
  64. *  @return     0:失败;1:成功
  65. *  @since      v1.0
  66. *  Sample usage:       FDC2214_GetChannelData(FDC2214_Channel_0, &CH0_DATA);
  67. */
  68. uint8_t FDC2214_GetChannelData(FDC2214_channel_t channel, uint32_t *data)
  69. {
  70.     int16_t timeout = 100;
  71.     uint8_t dateReg_H;
  72.     uint8_t dateReg_L;
  73.     uint8_t bitUnreadConv;
  74.     uint16_t status;
  75.     uint32_t dataRead;

  76.     switch(channel)
  77.     {
  78.         case FDC2214_Channel_0:
  79.             dateReg_H = FDC2214_DATA_CH0;
  80.             dateReg_L = FDC2214_DATA_LSB_CH0;
  81.             bitUnreadConv = 0x0008;
  82.         break;

  83.         case FDC2214_Channel_1:
  84.             dateReg_H = FDC2214_DATA_CH1;
  85.             dateReg_L = FDC2214_DATA_LSB_CH1;
  86.             bitUnreadConv = 0x0004;
  87.         break;

  88.         case FDC2214_Channel_2:
  89.             dateReg_H = FDC2214_DATA_CH2;
  90.             dateReg_L = FDC2214_DATA_LSB_CH2;
  91.             bitUnreadConv = 0x0002;
  92.         break;

  93.         case FDC2214_Channel_3:
  94.             dateReg_H = FDC2214_DATA_CH3;
  95.             dateReg_L = FDC2214_DATA_LSB_CH3;
  96.             bitUnreadConv = 0x0001;
  97.         break;
  98.     }

  99.     status = FDC2214_Read16(FDC2214_Addr, FDC2214_STATUS);//读取状态寄存器的值
  100.     while(timeout && !(status & bitUnreadConv))//检查是否有未读数据
  101.     {
  102.         status = FDC2214_Read16(FDC2214_Addr, FDC2214_STATUS);
  103.         timeout--;
  104.     }
  105.     if(timeout)
  106.     {
  107.         dataRead = (uint32_t)(FDC2214_Read16(FDC2214_Addr, dateReg_H) << 16);
  108.         dataRead |= FDC2214_Read16(FDC2214_Addr, dateReg_L);
  109.         *data = dataRead;
  110.         return 1;
  111.     }
  112.     else
  113.     {
  114.         //超时
  115.       
  116.         return 0;
  117.     }
  118. }

  119. /*!
  120. *  @brief      设置FDC2214一个通道的转换时间,转换时间(tCx)=(CHx_RCOUNT?16) / fREFx。
  121. *  @param      channel     通道
  122. *  @param      rcount      CHx_RCOUNT
  123. *  @since      v1.0
  124. *  Sample usage:       FDC2214_SetRcount(FDC2214_Channel_0, 0x0FFF);
  125. */
  126. void FDC2214_SetRcount(FDC2214_channel_t channel, uint16_t rcount)
  127. {
  128.     if(rcount <= 0x00FF) return;

  129.     switch(channel)
  130.     {
  131.         case FDC2214_Channel_0:
  132.             FDC2214_Write16(FDC2214_Addr, FDC2214_RCOUNT_CH0, rcount);
  133.         break;

  134.         case FDC2214_Channel_1:
  135.             FDC2214_Write16(FDC2214_Addr, FDC2214_RCOUNT_CH1, rcount);
  136.         break;

  137.         case FDC2214_Channel_2:
  138.             FDC2214_Write16(FDC2214_Addr, FDC2214_RCOUNT_CH2, rcount);
  139.         break;

  140.         case FDC2214_Channel_3:
  141.             FDC2214_Write16(FDC2214_Addr, FDC2214_RCOUNT_CH3, rcount);
  142.         break;
  143.     }
  144. }

  145. /*!
  146. *  @brief      设置FDC2214一个通道的建立时间,使LC传感器可以在通道x开始转换之前稳定下来,建立时间(tSx) = (CHx_SETTLECOUNT?16) ÷ fREFx。
  147.                 CHx_SETTLECOUNT = 0x00, 0x01时(tSx) = 32 ÷ fREFx。
  148. *  @param      channel     通道
  149. *  @param      count       CHx_SETTLECOUNT
  150. *  @since      v1.0
  151. *  @note       CHx_SETTLECOUNT > Vpk × fREFx × C × π^2 / (32 × IDRIVEX)
  152. *  Sample usage:       FDC2214_SetSettleCount(FDC2214_Channel_0, 0x00FF);
  153. */
  154. void FDC2214_SetSettleCount(FDC2214_channel_t channel, uint16_t count)
  155. {
  156.     switch(channel)
  157.     {
  158.         case FDC2214_Channel_0:
  159.             FDC2214_Write16(FDC2214_Addr, FDC2214_SETTLECOUNT_CH0, count);
  160.         break;

  161.         case FDC2214_Channel_1:
  162.             FDC2214_Write16(FDC2214_Addr, FDC2214_SETTLECOUNT_CH1, count);
  163.         break;

  164.         case FDC2214_Channel_2:
  165.             FDC2214_Write16(FDC2214_Addr, FDC2214_SETTLECOUNT_CH2, count);
  166.         break;

  167.         case FDC2214_Channel_3:
  168.             FDC2214_Write16(FDC2214_Addr, FDC2214_SETTLECOUNT_CH3, count);
  169.         break;
  170.     }
  171. }

  172. /*!
  173. *  @brief      设置FDC2214一个通道的的时钟频率,
  174.                 差分传感器配置:
  175.                 0x01 -- 传感器频率0.01MHz和8.75MHz
  176.                 0x02 -- 传感器频率5MHz和10MHz
  177.                 单端传感器配置:
  178.                 0x01 -- 传感器频率0.01MHz和10MHz
  179. *  @param      channel               通道
  180. *  @param      frequency_select      时钟选择
  181. *  @param      divider               分频器,fREFx = fCLK / CHx_FREF_DIVIDER,
  182. *  @note       fREFx is > 4 × fSENSOR(外部LC振荡器频率)
  183. *  @since      v1.0
  184. *  Sample usage:       FDC2214_SetChannelClock(FDC2214_Channel_0, 0x01, 0xFF);
  185. */
  186. void FDC2214_SetChannelClock(FDC2214_channel_t channel, uint8_t frequency_select, uint16_t divider)
  187. {
  188.     uint16_t temp = 0;

  189.     temp = (uint16_t)(frequency_select << 12) | (divider & 0x03FF);

  190.     CHx_FIN_SEL[channel] = frequency_select;//记录时钟选择
  191.     fREFx[channel] = (double)ClockFrequency / divider;//记录时钟频率

  192.     switch(channel)
  193.     {
  194.         case FDC2214_Channel_0:
  195.             FDC2214_Write16(FDC2214_Addr, FDC2214_CLOCK_DIVIDERS_CH0, temp);
  196.         break;

  197.         case FDC2214_Channel_1:
  198.             FDC2214_Write16(FDC2214_Addr, FDC2214_CLOCK_DIVIDERS_CH1, temp);
  199.         break;

  200.         case FDC2214_Channel_2:
  201.             FDC2214_Write16(FDC2214_Addr, FDC2214_CLOCK_DIVIDERS_CH2, temp);
  202.         break;

  203.         case FDC2214_Channel_3:
  204.             FDC2214_Write16(FDC2214_Addr, FDC2214_CLOCK_DIVIDERS_CH3, temp);
  205.         break;
  206.     }
  207. }

  208. /*!
  209. *  @brief      配置INTB引脚中断功能
  210. *  @param      mode      1:开中断;0:关中断
  211. *  @since      v1.0
  212. *  Sample usage:       FDC2214_SetDriveCurrent(FDC2214_Channel_0, FDC2214_Drive_Current_0_025);
  213. */
  214. void FDC2214_SetINTB(uint8_t mode)
  215. {
  216.     uint16_t temp = 0;

  217.     temp = FDC2214_Read16(FDC2214_Addr, FDC2214_CONFIG);
  218.     temp &= 0xFF7F;
  219.     if(mode)
  220.         temp |= 0x0080;
  221.     FDC2214_Write16(FDC2214_Addr, FDC2214_CONFIG, temp);

  222.     temp = FDC2214_Read16(FDC2214_Addr, FDC2214_ERROR_CONFIG);
  223.     temp &= 0xFFFE;
  224.     if(mode)
  225.         temp |= 0x0001;
  226.     FDC2214_Write16(FDC2214_Addr, FDC2214_ERROR_CONFIG, temp);
  227. }

  228. /*!
  229. *  @brief      激活FDC2214的一个通道,单通道模式
  230. *  @param      channel     通道
  231. *  @since      v1.0
  232. *  Sample usage:       FDC2214_SetActiveChannel(FDC2214_Channel_0);
  233. */
  234. void FDC2214_SetActiveChannel(FDC2214_channel_t channel)
  235. {
  236.     uint16_t temp = 0;
  237.     temp = FDC2214_Read16(FDC2214_Addr, FDC2214_CONFIG);
  238.     temp &= 0x3FFF;
  239.     temp |= (uint16_t)(channel << 14);

  240.     FDC2214_Write16(FDC2214_Addr, FDC2214_CONFIG, temp);
  241. }

  242. /*!
  243. *  @brief      设置FDC2214的工作模式:正常、睡眠。
  244. *  @param      mode     0:正常工作;1:睡激活模式选择。眠
  245. *  @since      v1.0
  246. *  Sample usage:       FDC2214_SetSleepMode(0);
  247. */
  248. void FDC2214_SetSleepMode(uint8_t mode)
  249. {
  250.     uint16_t temp = 0;
  251.     temp = FDC2214_Read16(FDC2214_Addr, FDC2214_CONFIG);
  252.     temp &= 0xDFFF;
  253.     if(mode)temp |= 0x2000;

  254.     FDC2214_Write16(FDC2214_Addr, FDC2214_CONFIG, temp);
  255. }

  256. /*!
  257. *  @brief      FDC2214激活模式选择。
  258. *  @param      mode     0:全电流激活模式;1:低功率激活模式
  259. *  @since      v1.0
  260. *  Sample usage:       FDC2214_SetCurrentMode(1);
  261. */
  262. void FDC2214_SetCurrentMode(uint8_t mode)
  263. {
  264.     uint16_t temp = 0;
  265.     temp = FDC2214_Read16(FDC2214_Addr, FDC2214_CONFIG);
  266.     temp &= 0xF7FF;
  267.     if(mode)
  268.         temp |= 0x800;

  269.     FDC2214_Write16(FDC2214_Addr, FDC2214_CONFIG, temp);
  270. }

  271. /*!
  272. *  @brief      设置FDC2214时钟源
  273. *  @param      src     0:内部时钟源;1:外部时钟源
  274. *  @since      v1.0
  275. *  Sample usage:       FDC2214_SetClockSource(1);
  276. */
  277. void FDC2214_SetClockSource(uint8_t src)
  278. {
  279.     uint16_t temp = 0;
  280.     temp = FDC2214_Read16(FDC2214_Addr, FDC2214_CONFIG);
  281.     temp &= 0xFDFF;
  282.     if(src)
  283.         temp |= 0x200;

  284.     FDC2214_Write16(FDC2214_Addr, FDC2214_CONFIG, temp);
  285. }

  286. /*!
  287. *  @brief      高电流传感器驱动,只适用于单通道模式。
  288. *  @param      mode     0:正常(最大1.5mA);1:高电流传感器驱动(>1.5mA)
  289. *  @since      v1.0
  290. *  Sample usage:       FDC2214_SetHighCurrentMode(0);
  291. */
  292. void FDC2214_SetHighCurrentMode(uint8_t mode)
  293. {
  294.     uint16_t temp = 0;
  295.     temp = FDC2214_Read16(FDC2214_Addr, FDC2214_CONFIG);
  296.     temp &= 0xFFBF;
  297.     if(mode)
  298.         temp |= 0x40;

  299.     FDC2214_Write16(FDC2214_Addr, FDC2214_CONFIG, temp);
  300. }

  301. /*!
  302. *  @brief      设置FDC2214的MUX CONFIG寄存器
  303. *  @param      autoscan      自动扫描模式 0:关闭,1:打开
  304. *  @param      channels      自动扫描通道
  305. *  @param      bandwidth     数字滤波器带宽,大于外部LC振荡器频率
  306. *  @since      v1.0
  307. *  Sample usage:       FDC2214_SetMUX_CONFIG(1, FDC2214_Channel_Sequence_0_1_2, FDC2214_Bandwidth_10M);
  308. */
  309. void FDC2214_SetMUX_CONFIG(uint8_t autoscan, FDC2214_channel_sequence_t channels, FDC2214_filter_bandwidth_t bandwidth)
  310. {
  311.     uint16_t temp = 0;

  312.     if(autoscan)
  313.     {
  314.         temp = (uint16_t)(autoscan << 15) | (channels << 13) | 0x0208 | bandwidth;
  315.     }
  316.     else
  317.     {
  318.         temp = 0x0208 | bandwidth;
  319.     }

  320.     FDC2214_Write16(FDC2214_Addr, FDC2214_MUX_CONFIG, temp);
  321. }

  322. /*!
  323. *  @brief      传感器复位
  324. *  @since      v1.0
  325. *  Sample usage:       FDC2214_Reset();
  326. */
  327. void FDC2214_Reset(void)
  328. {
  329.     FDC2214_Write16(FDC2214_Addr, FDC2214_RESET_DEV, 0x8000);
  330. }

  331. /*!
  332. *  @brief      设置FDC2214的一个通道传感器驱动电流,确保振荡幅度在1.2V和1.8V之间。
  333. *  @param      channel      通道
  334. *  @param      current      电流大小
  335. *  @since      v1.0
  336. *  Sample usage:       FDC2214_SetDriveCurrent(FDC2214_Channel_0, FDC2214_Drive_Current_0_025);
  337. */
  338. void FDC2214_SetDriveCurrent(FDC2214_channel_t channel, FDC2214_drive_current_t current)
  339. {
  340.     uint16_t temp = 0;
  341.     temp = (uint16_t)(current << 11);

  342.     switch(channel)
  343.     {
  344.         case FDC2214_Channel_0:
  345.             FDC2214_Write16(FDC2214_Addr, FDC2214_DRIVE_CURRENT_CH0, temp);
  346.         break;

  347.         case FDC2214_Channel_1:
  348.             FDC2214_Write16(FDC2214_Addr, FDC2214_DRIVE_CURRENT_CH1, temp);
  349.         break;

  350.         case FDC2214_Channel_2:
  351.             FDC2214_Write16(FDC2214_Addr, FDC2214_DRIVE_CURRENT_CH2, temp);
  352.         break;

  353.         case FDC2214_Channel_3:
  354.             FDC2214_Write16(FDC2214_Addr, FDC2214_DRIVE_CURRENT_CH3, temp);
  355.         break;
  356.     }
  357. }

  358. /*!
  359. *  @brief      计算频率
  360. *  @param      channel      通道
  361. *  @param      datax        读取的转换值
  362. *  @return     频率,单位Hz
  363. *  @since      v1.0
  364. *  Sample usage:       FDC2214_CalculateFrequency(FDC2214_Channel_0, 0xFF);
  365. */
  366. double FDC2214_CalculateFrequency(FDC2214_channel_t channel, uint32_t datax)
  367. {
  368.     double frequency = 0.0;

  369.     frequency = (double)(CHx_FIN_SEL[channel] * fREFx[channel] * datax) / 268435456.0;//2^28

  370.     return frequency;
  371. }

  372. /*!
  373. *  @brief      计算外部电容大小
  374. *  @param      frequency      频率大小,单位Hz
  375. *  @param      inductance     板载电感大小,单位uH
  376. *  @param      capacitance    板载电容大小,单位pF
  377. *  @return     外部电容大小,单位pF
  378. *  @since      v1.0
  379. *  Sample usage:       FDC2214_CalculateCapacitance(FDC2214_Channel_0, 6000000, 18, 33);
  380. */
  381. double FDC2214_CalculateCapacitance(double frequency, float inductance, float capacitance)
  382. {
  383.     double cap = 0.0;

  384.     cap = (double)(1.0 / (inductance * (2 * PI * frequency) * (2 * PI * frequency)));

  385.     return cap;
  386. }

  387. /*!
  388. *  @brief      FDC2214初始化函数
  389. *  @return     1:成功;0:失败
  390. *  @since      v1.0
  391. *  Sample usage:       FDC2214_Init();
  392. */
  393. uint8_t FDC2214_Init(void)
  394. {
  395.     uint16_t deviceID = 0;
  396.     deviceID = FDC2214_Read16(FDC2214_Addr, FDC2214_DEVICE_ID);//读器件ID
  397.     if(deviceID == FDC2214_ID)
  398.     {
  399.         printf("\r\nFDC2214 ID:%d",deviceID);
  400.         FDC2214_Reset();
  401.         
  402.    
  403.         FDC2214_SetRcount(FDC2214_Channel_0, 5000);//2000us 转换周期
  404.         FDC2214_SetRcount(FDC2214_Channel_1, 5000);//2000us 转换周期
  405.         FDC2214_SetRcount(FDC2214_Channel_2, 5000);//2000us 转换周期
  406.         FDC2214_SetRcount(FDC2214_Channel_3, 5000);//2000us 转换周期
  407.         FDC2214_SetSettleCount(FDC2214_Channel_0, 200);//200 cycles 等待时间
  408.         FDC2214_SetSettleCount(FDC2214_Channel_1, 200);//200 cycles 等待时间
  409.         FDC2214_SetSettleCount(FDC2214_Channel_2, 200);//200 cycles 等待时间
  410.         FDC2214_SetSettleCount(FDC2214_Channel_3, 200);//200 cycles 等待时间
  411.         FDC2214_SetChannelClock(FDC2214_Channel_0, 2, 1);//设置时钟分频,1分频,40MHz
  412.         FDC2214_SetChannelClock(FDC2214_Channel_1, 2, 1);//设置时钟分频,1分频,40MHz
  413.         FDC2214_SetChannelClock(FDC2214_Channel_2, 2, 1);//设置时钟分频,1分频,40MHz
  414.         FDC2214_SetChannelClock(FDC2214_Channel_3, 2, 1);//设置时钟分频,1分频,40MHz
  415.         
  416.         FDC2214_SetINTB(0);//关闭INTB中断
  417.         //FDC2214_SetActiveChannel(FDC2214_Channel_0);//开启通道0
  418.         FDC2214_SetCurrentMode(0);//全电流激活模式
  419.         FDC2214_SetClockSource(1);//外部时钟源
  420.         FDC2214_SetHighCurrentMode(0);//正常电流传感器驱动
  421.         
  422.         FDC2214_SetMUX_CONFIG(1, FDC2214_Channel_Sequence_0_1_2_3, FDC2214_Bandwidth_10M);//打开自动扫描,10MHz带宽
  423.         
  424.         FDC2214_SetDriveCurrent(FDC2214_Channel_0, FDC2214_Drive_Current_0_081);//通道0驱动电流0.081mA
  425.         FDC2214_SetDriveCurrent(FDC2214_Channel_1, FDC2214_Drive_Current_0_081);//通道1驱动电流0.081mA
  426.         FDC2214_SetDriveCurrent(FDC2214_Channel_2, FDC2214_Drive_Current_0_081);//通道2驱动电流0.081mA
  427.         FDC2214_SetDriveCurrent(FDC2214_Channel_3, FDC2214_Drive_Current_0_081);//通道3驱动电流0.081mA
  428.         
  429.         
  430.         FDC2214_SetSleepMode(0);//退出睡眠状态,开始工作
  431.         delay_ms(100);
  432.         
  433.         return 1;
  434.     }
  435.     else
  436.     {
  437.         printf("\r\nFDC2214 Init Failed!!");
  438.     }

  439.     return 0;
  440. }
复制代码


51hei.png
原理图PCB+Keil代码下载:
FDC2214.rar (8.61 MB, 下载次数: 44)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:449771 发表于 2023-8-26 14:54 | 显示全部楼层
哥 我读取的电容值为什么为0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表