EDABOSS电子论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 555|回复: 0

[资料共享] 基于Arduino驱动FDC2214程序(测试通过)

[复制链接]

5

主题

0

回帖

26

E币

技术员

Rank: 2

积分
10
发表于 2019-12-4 17:27:44 | 显示全部楼层 |阅读模式
  1. /**************************************************************************/
  2. /*!
  3.     @file     NelsonsLog_FDC2214.cpp
  4.     @author   dlsc

  5. */
  6. /**************************************************************************/

  7. #include "Arduino.h"
  8. #include <Wire.h>
  9. #include "FDC2214.h"

  10. FDC2214::FDC2214(uint8_t i2caddr) {
  11.         _i2caddr = i2caddr;
  12.     //_i2caddr = FDC2214_I2C_ADDRESS;
  13. }

  14. // Checking for chip ID, if OK, calls chip init
  15. boolean FDC2214::begin(uint8_t chanMask, uint8_t autoscanSeq, uint8_t deglitchValue) {
  16.     Wire.begin();

  17.     int devId = read16FDC(FDC2214_DEVICE_ID);
  18.     if (devId != 0x3054) {
  19.         if (devId != 0x3055) {
  20.             //two valid device ids for FDC2214 0x3054 and 0x3055
  21.             return false;
  22.         }
  23.     }

  24.     loadSettings(chanMask, autoscanSeq, deglitchValue);
  25. //    setGain();

  26.     return true;
  27. }


  28. //Internal routine to do actual chip init
  29. void FDC2214::loadSettings(uint8_t chanMask, uint8_t autoscanSeq, uint8_t deglitchValue) {

  30.         //Configuration register
  31.         //        Active channel Select: b00 = ch0; b01 = ch1; b10 = ch2; b11 = ch3;
  32.         //  |Sleep Mode: 0 - device active; 1 - device in sleep;
  33.         //  ||Reserved, reserved, set to 1
  34.         //  |||Sensor Activation Mode: 0 - drive sensor with full current. 1 - drive sensor with current set by DRIVE_CURRENT_CHn
  35.         //  ||||Reserved, set to 1
  36.         //  |||||Reference clock: 0 - use internal; 1 - use external clock
  37.         //  ||||||Reserved, set to 0
  38.         //  |||||||Disable interrupt. 0 - interrupt output on INTB pin; 1 - no interrupt output
  39.         //  ||||||||High current sensor mode: 0 - 1.5mA max. 1 - > 1.5mA, not available if Autoscan is enabled
  40.         //  |||||||||     Reserved, set to 000001
  41.         //  |||||||||     |
  42.         // CCS1A1R0IH000000 -> 0001 1110 1000 0001 -> 0x1E81
  43.         write16FDC(FDC2214_CONFIG, 0x1E81);  //set config

  44.         //If channel 1 selected, init it..
  45.         if (chanMask & 0x01) {

  46.                 //settle count maximized, slow application
  47.                 write16FDC(FDC2214_SETTLECOUNT_CH0, 0x64);

  48.                 //rcount maximized for highest accuracy
  49.                 write16FDC(FDC2214_RCOUNT_CH0, 0xFFFF);

  50.                 //no offset
  51.                 write16FDC(FDC2214_OFFSET_CH0, 0x0000);
  52.                
  53.                 // Set clock dividers
  54.                 //  Reserved
  55.                 //  | Sensor Frequency Select. b01 = /1 = sensor freq 0.01 to 8.75MHz; b10 = /2 = sensor freq 0.01 to 10 or 5 to 10 MHz
  56.                 //  | | Reserved
  57.                 //  | | |         Reference divider. Must be > 1. fref = fclk / this register`
  58.                 //  | | |         |
  59.                 // 00FF00RRRRRRRRRR -> 0010000000000001 -> 0x2001
  60.                 write16FDC(FDC2214_CLOCK_DIVIDERS_CH0, 0x2001);
  61.                 //set drive register
  62.                 write16FDC(FDC2214_DRIVE_CH0, 0xF800);
  63.         }
  64.         // Init chan2, if selected by channel init mask
  65.         if (chanMask & 0x02) {
  66.                 write16FDC(FDC2214_SETTLECOUNT_CH1, 0x64);
  67.                 write16FDC(FDC2214_RCOUNT_CH1, 0xFFFF);
  68.                 write16FDC(FDC2214_OFFSET_CH1, 0x0000);
  69.                 write16FDC(FDC2214_CLOCK_DIVIDERS_CH1, 0x2001);
  70.                 write16FDC(FDC2214_DRIVE_CH1, 0xF800);        
  71.         }        
  72.         if (chanMask & 0x04) {
  73.                 write16FDC(FDC2214_SETTLECOUNT_CH1, 0x64);
  74.                 write16FDC(FDC2214_RCOUNT_CH1, 0xFFFF);
  75.                 write16FDC(FDC2214_OFFSET_CH1, 0x0000);
  76.                 write16FDC(FDC2214_CLOCK_DIVIDERS_CH1, 0x2001);
  77.                 write16FDC(FDC2214_DRIVE_CH1, 0xF800);        
  78.         }        
  79.         if (chanMask & 0x08) {
  80.                 write16FDC(FDC2214_SETTLECOUNT_CH1, 0x64);
  81.                 write16FDC(FDC2214_RCOUNT_CH1, 0xFFFF);
  82.                 write16FDC(FDC2214_OFFSET_CH1, 0x0000);
  83.                 write16FDC(FDC2214_CLOCK_DIVIDERS_CH1, 0x2001);
  84.                 write16FDC(FDC2214_DRIVE_CH1, 0xF800);        
  85.         }        
  86.         // Autoscan: 0 = single channel, selected by CONFIG.ACTIVE_CHAN
  87.         // | Autoscan sequence. b00 for chan 1-2, b01 for chan 1-2-3, b02 for chan 1-2-3-4
  88.         // | |         Reserved - must be b0001000001
  89.         // | |         |  Deglitch frequency. b001 for 1 MHz, b100 for 3.3 MHz, b101 for 10 Mhz, b111 for 33 MHz
  90.         // | |         |  |
  91.     // ARR0001000001DDD -> b0000 0010 0000 1000 -> h0208
  92.         uint16_t muxVal = 0x0208 | ((uint16_t)autoscanSeq << 13) | deglitchValue;
  93.         //
  94.     write16FDC(FDC2214_MUX_CONFIG, muxVal);  //set mux config for channels
  95. }

  96. ///**************************************************************************/
  97. ///*!
  98. //    @brief  Given a reading calculates the sensor frequency
  99. //*/
  100. ///**************************************************************************/
  101. //long long NelsonsLog_FDC2214::calculateFsensor(unsigned long reading){
  102. ////    Serial.println("reading: "+ String(reading));
  103. //    //fsensor = (CH_FIN_SEL * fref * data) / 2 ^ 28
  104. //    //should be mega hz so can truncate to long long
  105. //    Serial.println("FDC reading: " + String(reading));
  106. //    unsigned long long temp;
  107. //    temp = 1 * 40000000 * reading;
  108. //    temp = temp / (2^28);
  109. ////    Serial.println("frequency: " + String((long)temp));
  110. //    return temp;
  111. //}

  112. ///**************************************************************************/
  113. ///*!
  114. //    @brief  Given sensor frequency calculates capacitance
  115. //*/
  116. ///**************************************************************************/
  117. //double NelsonsLog_FDC2214::calculateCapacitance(long long fsensor){
  118. //    //differential configuration
  119. //    //c sensor = 1                            - (Cboard + Cparacitic)
  120. //    //             / (L * (2*pi * fsensor)^2)
  121. //
  122. //    double pi = 3.14159265359;
  123. //    double L = 18; //uH
  124. //    double Cboard = 33; //pf
  125. //    double Cparacitic = 3; //pf
  126. //
  127. //    double temp = 2 * pi * fsensor;
  128. //    temp = temp * temp;
  129. //
  130. //    temp = temp / 1000000; //uH
  131. //    temp *= L;
  132. //
  133. ////    Serial.println("capacitance: " + String(temp));
  134. //    return temp;
  135. //
  136. //}



  137. // Gets 28bit reading for FDC2212 and FDC2214
  138. // Takes in channel number, gives out the formatted 28 bit reading.
  139. unsigned long FDC2214::getReading28(uint8_t channel) {
  140.     int timeout = 100;
  141.     unsigned long reading = 0;
  142.     long long fsensor = 0;
  143.     int status = read16FDC(FDC2214_STATUS);
  144.     uint8_t addressMSB;
  145.         uint8_t addressLSB;
  146.         uint8_t bitUnreadConv;
  147.         switch (channel){
  148.                 case (0):
  149.                         addressMSB = FDC2214_DATA_CH0_MSB;
  150.                         addressLSB = FDC2214_DATA_CH0_LSB;
  151.                         bitUnreadConv = FDC2214_CH0_UNREADCONV;
  152.                 break;
  153.                 case (1):
  154.                         addressMSB = FDC2214_DATA_CH1_MSB;
  155.                         addressLSB = FDC2214_DATA_CH1_LSB;
  156.                         bitUnreadConv = FDC2214_CH1_UNREADCONV;
  157.                 break;
  158.                 case (2):
  159.                         addressMSB = FDC2214_DATA_CH1_MSB;
  160.                         addressLSB = FDC2214_DATA_CH1_LSB;
  161.                         bitUnreadConv = FDC2214_CH1_UNREADCONV;
  162.                 break;
  163.                 case (3):
  164.                         addressMSB = FDC2214_DATA_CH1_MSB;
  165.                         addressLSB = FDC2214_DATA_CH1_LSB;
  166.                         bitUnreadConv = FDC2214_CH1_UNREADCONV;
  167.                 break;
  168.                 default: return 0;
  169.         }
  170.         
  171.         while (timeout && !(status & FDC2214_CH0_UNREADCONV)) {
  172.         status = read16FDC(FDC2214_STATUS);
  173.         timeout--;
  174.     }
  175.     if (timeout == 100) {
  176. // #####################################################################################################
  177. // There was this weird double read, as "first readout could be stale" in Nelsons file.
  178. // I have not confirmed the existence of this silicon bug.
  179. // I suspect that it might be due to crappy breadboard or rats nest wiring or lack of signal integrity for other reason
  180. //
  181. // On the other hand, I have done far too little testing to be sure, so I am leaving that bit in for now.
  182. //        
  183. // #####################################################################################################
  184.                 //could be stale grab another //could it really it? ?????
  185.         //read the 28 bit result
  186.         reading = (uint32_t)(read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA) << 16;
  187.         reading |= read16FDC(addressLSB);
  188.         while (timeout && !(status & FDC2214_CH0_UNREADCONV)) {
  189.             status = read16FDC(FDC2214_STATUS);
  190.             timeout--;
  191.         }
  192.     }
  193.     if (timeout) {
  194.         //read the 28 bit result
  195.         reading = (uint32_t)(read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA) << 16;
  196.         reading |= read16FDC(addressLSB);
  197.         return reading;
  198.     } else {
  199.                 // Could not get data, chip readynes flag timeout
  200.         return 0;
  201.     }
  202. }

  203. // Gets 16bit reading for FDC2112 and FDC2114
  204. // Takes in channel number, gives out the formatted 28 bit reading.
  205. unsigned long FDC2214::getReading16(uint8_t channel) {
  206.     int timeout = 100;
  207.     unsigned long reading = 0;
  208.     long long fsensor = 0;
  209.     int status = read16FDC(FDC2214_STATUS);
  210.     uint8_t addressMSB;
  211.         uint8_t bitUnreadConv;
  212.         switch (channel){
  213.                 case (0):
  214.                         addressMSB = FDC2214_DATA_CH0_MSB;
  215.                         bitUnreadConv = FDC2214_CH0_UNREADCONV;
  216.                 break;
  217.                 case (1):
  218.                         addressMSB = FDC2214_DATA_CH1_MSB;
  219.                         bitUnreadConv = FDC2214_CH1_UNREADCONV;
  220.                 break;
  221.                 case (2):
  222.                         addressMSB = FDC2214_DATA_CH1_MSB;
  223.                         bitUnreadConv = FDC2214_CH1_UNREADCONV;
  224.                 break;
  225.                 case (3):
  226.                         addressMSB = FDC2214_DATA_CH1_MSB;
  227.                         bitUnreadConv = FDC2214_CH1_UNREADCONV;
  228.                 break;
  229.                 default: return 0;
  230.         }
  231.         
  232.         while (timeout && !(status & FDC2214_CH0_UNREADCONV)) {
  233.         status = read16FDC(FDC2214_STATUS);
  234.         timeout--;
  235.     }
  236.     if (timeout == 100) {
  237. // #####################################################################################################
  238. // There was this weird double read, as "first readout could be stale" in Nelsons file.
  239. // I have not confirmed the existence of this silicon bug.
  240. // I suspect that it might be due to crappy breadboard or rats nest wiring or lack of signal integrity for other reason
  241. //
  242. // On the other hand, I have done far too little testing to be sure, so I am leaving that bit in for now.
  243. //        
  244. // #####################################################################################################
  245.                 //could be stale grab another //could it really it? ?????
  246.         //read the 28 bit result
  247.         reading = (uint32_t)(read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA) << 16;
  248.         while (timeout && !(status & FDC2214_CH0_UNREADCONV)) {
  249.             status = read16FDC(FDC2214_STATUS);
  250.             timeout--;
  251.         }
  252.     }
  253.     if (timeout) {
  254.         //read the 16 bit result
  255.         reading = (uint32_t)(read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA) << 16;
  256.         return reading;
  257.     } else {
  258.                 // Could not get data, chip readynes flag timeout
  259.                 return 0;
  260.     }
  261. }

  262. ///**************************************************************************/
  263. ///*!
  264. //    @brief  Takes a reading and calculates capacitance from it
  265. //*/
  266. ///**************************************************************************/
  267. //double NelsonsLog_FDC2214::readCapacitance() {
  268. //    int timeout = 100;
  269. //    unsigned long reading = 0;
  270. //    long long fsensor = 0;
  271. //    int status = read16FDC(FDC2214_STATUS_REGADDR);
  272. //    while (timeout && !(status & FDC2214_CH0_UNREADCONV)) {
  273. ////        Serial.println("status: " + String(status));
  274. //        status = read16FDC(FDC2214_STATUS_REGADDR);
  275. //        timeout--;
  276. //    }
  277. //    if (timeout) {
  278. //        //read the 28 bit result
  279. //        reading = read16FDC(FDC2214_DATA_CH0_REGADDR) << 16;
  280. //        reading |= read16FDC(FDC2214_DATA_LSB_CH0_REGADDR);
  281. //        fsensor = calculateFsensor(reading);
  282. //        return calculateCapacitance(fsensor);
  283. //    } else {
  284. //        //error not reading
  285. //        Serial.println("error reading fdc");
  286. //        return 0;
  287. //    }
  288. //}


  289. /**************************************************************************/
  290. /*!
  291.     @brief  Scans various gain settings until the amplitude flag is cleared.
  292.             WARNING: Changing the gain setting will generally have an impact on the
  293.             reading.
  294. */
  295. /**************************************************************************/
  296. //void NelsonsLog_FDC2214::setGain(void) {
  297. //    //todo
  298. //}
  299. /**************************************************************************/
  300. /*!
  301.     @brief  I2C low level interfacing
  302. */
  303. /**************************************************************************/


  304. // Read 1 byte from the FDC at 'address'
  305. uint8_t FDC2214::read8FDC(uint16_t address) {
  306.     uint8_t data;
  307.     Wire.beginTransmission(_i2caddr);
  308.     Wire.write(address >> 8);
  309.     Wire.write(address);
  310.     Wire.endTransmission(false);
  311.     Wire.requestFrom(_i2caddr, (uint8_t) 1);
  312.     uint8_t r = Wire.read();
  313.     return r;
  314. }

  315. // Read 2 byte from the FDC at 'address'
  316. uint32_t FDC2214::read32FDC(uint16_t address) {
  317.     uint32_t retVal = 0;
  318.         uint8_t data;

  319.     Wire.beginTransmission(_i2caddr);
  320. //    Wire.write(address >> 8);
  321.     Wire.write(address);
  322.     Wire.endTransmission(false);

  323.     Wire.requestFrom(_i2caddr, (uint8_t) 2);
  324.     while (!Wire.available());
  325.     data = Wire.read();
  326.     retVal |= (uint32_t)data << 24;
  327.     while (!Wire.available());
  328.     data = Wire.read();
  329.     retVal |= (uint32_t)data << 16;
  330.     while (!Wire.available());
  331.     data = Wire.read();
  332.     retVal |= (uint32_t)data << 8;
  333.     while (!Wire.available());
  334.     data = Wire.read();
  335.     retVal |= data;
  336.     return retVal;
  337. }

  338. // Read 2 byte from the FDC at 'address'
  339. uint16_t FDC2214::read16FDC(uint16_t address) {
  340.     uint16_t data;

  341.     Wire.beginTransmission(_i2caddr);
  342. //    Wire.write(address >> 8);
  343.     Wire.write(address);
  344.     Wire.endTransmission(false); //restart

  345.     Wire.requestFrom(_i2caddr, (uint8_t) 2);
  346.     while (!Wire.available());
  347.     data = Wire.read();
  348.     data <<= 8;
  349.     while (!Wire.available());
  350.     data |= Wire.read();
  351.     Wire.endTransmission(true); //end
  352.     return data;
  353. }

  354. // write 1 byte to FDC
  355. void FDC2214::write8FDC(uint16_t address, uint8_t data) {
  356.     Wire.beginTransmission(_i2caddr);
  357.     Wire.write(address >> 8);
  358.     Wire.write(address);
  359.     Wire.write(data);
  360.     Wire.endTransmission();
  361. }

  362. // write 2 bytes to FDC  
  363. void FDC2214::write16FDC(uint16_t address, uint16_t data) {
  364.     Wire.beginTransmission(_i2caddr);
  365.     Wire.write(address & 0xFF);
  366.     Wire.write(data >> 8);
  367.     Wire.write(data);
  368.     Wire.endTransmission();
  369. }
复制代码


基于Arduino驱动FDC2214程序(测试通过).rar

83.63 KB, 下载次数: 0, 下载积分: E币 -5 元

积分规则
回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|EDABOSS电子论坛

GMT+8, 2024-4-26 01:55 , Processed in 0.044893 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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