最近要用到FDC2214模塊,所以查了一下技術(shù)手冊學(xué)習(xí)了一下,F(xiàn)DC2214采用IIC通信,源碼平臺采用的是STM32F103系列并且用OLED顯示出電容值。FDC可用于測量非導(dǎo)電容器中的液位。由于其非常高的激發(fā)速率能力,它能夠測量肥皂水、油墨、肥皂和其他導(dǎo)電液體。它的工作原理是基于比率測量的。
以下是FDC部分源代碼:
- #include "fdc2214.h"
- #include "delay.h"
- #include "led.h"
- u32 Data_FDC;
- //FDC_I2C及讀寫操作**************************************************
- //FDC IIC 延時(shí)函數(shù)
- void FDC_IIC_Delay(void)
- {
- delay_us(2);
- }
- void FDC_GPIO_Init(void)
- {
-
- }
- //初始化IIC I/O口
- void FDC_IIC_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//先使能外設(shè)IO PORTC時(shí)鐘
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;//端口配置
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
- GPIO_Init(GPIOC, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化GPIO
-
- GPIO_SetBits(GPIOC,GPIO_Pin_4|GPIO_Pin_5); //PC.4,PC.5 輸出高
- }
- //產(chǎn)生IIC起始信號
- void FDC_IIC_Start(void)
- {
- FDC_SDA_OUT(); //sda線輸出
- FDC_IIC_SDA=1;
- FDC_IIC_SCL=1;
- FDC_IIC_Delay();
- FDC_IIC_SDA=0;//START:when CLK is high,DATA change form high to low
- FDC_IIC_Delay();
- FDC_IIC_SCL=0;//鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
- }
- //產(chǎn)生IIC停止信號
- void FDC_IIC_Stop(void)
- {
- FDC_SDA_OUT();//sda線輸出
- FDC_IIC_SCL=0;
- FDC_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
- FDC_IIC_Delay();
- FDC_IIC_SCL=1;
- FDC_IIC_SDA=1;//發(fā)送I2C總線結(jié)束信號
- FDC_IIC_Delay();
- }
- //等待應(yīng)答信號到來
- //返回值:1,接收應(yīng)答失敗
- // 0,接收應(yīng)答成功
- u8 FDC_IIC_Wait_Ack(void)
- {
- u8 ucErrTime=0;
- FDC_SDA_IN(); //SDA設(shè)置為輸入
- FDC_IIC_SDA=1;FDC_IIC_Delay();
- FDC_IIC_SCL=1;FDC_IIC_Delay();
- while(FDC_READ_SDA)
- {
- ucErrTime++;
- if(ucErrTime>250)
- {
- FDC_IIC_Stop();
- return 1;
- }
- }
- FDC_IIC_SCL=0;//時(shí)鐘輸出0
- return 0;
- }
- //產(chǎn)生ACK應(yīng)答
- void FDC_IIC_Ack(void)
- {
- FDC_IIC_SCL=0;
- FDC_SDA_OUT();
- FDC_IIC_SDA=0;
- FDC_IIC_Delay();
- FDC_IIC_SCL=1;
- FDC_IIC_Delay();
- FDC_IIC_SCL=0;
- }
- //不產(chǎn)生ACK應(yīng)答
- void FDC_IIC_NAck(void)
- {
- FDC_IIC_SCL=0;
- FDC_SDA_OUT();
- FDC_IIC_SDA=1;
- FDC_IIC_Delay();
- FDC_IIC_SCL=1;
- FDC_IIC_Delay();
- FDC_IIC_SCL=0;
- }
- //IIC發(fā)送一個(gè)字節(jié)
- //返回從機(jī)有無應(yīng)答
- //1,有應(yīng)答
- //0,無應(yīng)答
- void FDC_IIC_Send_Byte(u8 txd)
- {
- u8 t;
- FDC_SDA_OUT();
- FDC_IIC_SCL=0;//拉低時(shí)鐘開始數(shù)據(jù)傳輸
- for(t=0;t<8;t++)
- {
- FDC_IIC_SDA=(txd&0x80)>>7;
- txd<<=1;
- FDC_IIC_SCL=1;
- FDC_IIC_Delay();
- FDC_IIC_SCL=0;
- FDC_IIC_Delay();
- }
- }
- //讀1個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK
- u8 FDC_IIC_Read_Byte(unsigned char ack)
- {
- unsigned char i,receive=0;
- FDC_SDA_IN();//SDA設(shè)置為輸入
- for(i=0;i<8;i++ )
- {
- FDC_IIC_SCL=0;
- FDC_IIC_Delay();
- FDC_IIC_SCL=1;
- receive<<=1;
- if(FDC_READ_SDA)receive++;
- FDC_IIC_Delay();
- }
- if (!ack)
- FDC_IIC_NAck();//發(fā)送nACK
- else
- FDC_IIC_Ack(); //發(fā)送ACK
- return receive;
- }
- //FDC寄存器操作***********************************************************************
- /*FDC2214設(shè)置函數(shù)
- *IIC寫2個(gè)字節(jié)
- *reg:寄存器地址
- *data1:數(shù)據(jù)1
- *data2:數(shù)據(jù)2
- *返回值:0 正常
- * 其他 錯(cuò)誤代碼
- */
- u8 Set_FDC2214(u8 reg,u8 MSB,u8 LSB)
- {
- FDC_IIC_Start();
- FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|0);//發(fā)送器件地址+寫命令
- if(FDC_IIC_Wait_Ack()) //等待應(yīng)答
- {
- FDC_IIC_Stop();
- return 1;
- }
- FDC_IIC_Send_Byte(reg);//寫寄存器地址
- FDC_IIC_Wait_Ack(); //等待應(yīng)答
- FDC_IIC_Send_Byte(MSB); //發(fā)送數(shù)據(jù)1
- if(FDC_IIC_Wait_Ack()) //等待ACK
- {
- FDC_IIC_Stop();
- return 1;
- }
- FDC_IIC_Send_Byte(LSB); //發(fā)送數(shù)據(jù)2
- if(FDC_IIC_Wait_Ack()) //等待ACK
- {
- FDC_IIC_Stop();
- return 1;
- }
- FDC_IIC_Stop();
- return 0;
- }
- /*讀取FDC2214寄存器數(shù)據(jù)
- *IIC讀2個(gè)字節(jié)
- *reg:寄存器地址
- *返回值:讀到的數(shù)據(jù)
- */
- u16 FDC_Read(u8 reg)
- {
- u16 res;
- FDC_IIC_Start();
- FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|0);//發(fā)送器件地址+寫命令
- FDC_IIC_Wait_Ack(); //等待應(yīng)答
- FDC_IIC_Send_Byte(reg); //寫寄存器地址
- FDC_IIC_Wait_Ack(); //等待應(yīng)答
- FDC_IIC_Start();
- FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|1);//發(fā)送器件地址+讀命令
- FDC_IIC_Wait_Ack(); //等待應(yīng)答
- res=FDC_IIC_Read_Byte(1)<<8;//讀取數(shù)據(jù),發(fā)送ACK
-
- res|=FDC_IIC_Read_Byte(0);//讀取數(shù)據(jù),發(fā)送nACK
- FDC_IIC_Stop(); //產(chǎn)生一個(gè)停止條件
- return res;
- }
- /*得到通道x轉(zhuǎn)換后的數(shù)據(jù)
- *index:0 -> CH0
- * 1 -> CH1
- * 2 -> CH2
- * 3 -> CH3
- *返回值:讀到的數(shù)據(jù)
- */
- //u16 FCD2214_ReadCH(u8 index)
- //{
- // u16 result;
- // switch(index)
- // {
- // case 0:
- // result = FDC_Read(DATA_CH0)&0x0FFF;
- // result = (result<<4)|(FDC_Read(DATA_LSB_CH0)>>12);
- // break;
- // case 1:
- // result = FDC_Read(DATA_CH1)&0x0FFF;
- // result = (result<<4)|(FDC_Read(DATA_LSB_CH1)>>12);
- // break;
- // case 2:
- // result = FDC_Read(DATA_CH2)&0x0FFF;
- // result = (result<<4)|(FDC_Read(DATA_LSB_CH2)>>12);
- // break;
- // case 3:
- // result = FDC_Read(DATA_CH3)&0x0FFF;
- // result = (result<<4)|(FDC_Read(DATA_LSB_CH3)>>12);
- // break;
- // default:break;
- // }
- // return result;
- //}
- u32 FCD2214_ReadCH(u8 index)
- {
- u32 result;
- switch(index)
- {
- case 0:
- result = FDC_Read(DATA_CH0)&0x0FFF;
- result = (result<<16)|(FDC_Read(DATA_LSB_CH0));
- break;
- case 1:
- result = FDC_Read(DATA_CH1)&0x0FFF;
- result = (result<<16)|(FDC_Read(DATA_LSB_CH1));
- break;
- case 2:
- result = FDC_Read(DATA_CH2)&0x0FFF;
- result = (result<<16)|(FDC_Read(DATA_LSB_CH2));
- break;
- case 3:
- result = FDC_Read(DATA_CH3)&0x0FFF;
- result = (result<<16)|(FDC_Read(DATA_LSB_CH3));
- break;
- default:break;
- }
- result =result&0x0FFFFFFF;
- return result;
- }
- /*FDC2214初始化函數(shù)
- *返回值:0:初始化正常
- * 1:不正常
- */
- u8 FDC2214_Init(void)
- {
- u16 res;
- //FDC2214芯片IO口初始化
- FDC_GPIO_Init();
-
- //軟件IIC總線初始化
- FDC_IIC_Init();
-
- //檢測ID是否正確,再初始化寄存器
- res=FDC_Read(MANUFACTURER_ID);
- if(res==0x5449)
- {
- //設(shè)置Set_FDC2214寄存器
- Set_FDC2214(RCOUNT_CH0,0x34,0xFB);//參考計(jì)數(shù)轉(zhuǎn)換間隔時(shí)間(T=(RCOUNT_CH0*16)/Frefx)
- Set_FDC2214(RCOUNT_CH1,0x34,0xFB);
- Set_FDC2214(RCOUNT_CH2,0x34,0xFB);
- Set_FDC2214(RCOUNT_CH3,0x34,0xFB);
-
- Set_FDC2214(SETTLECOUNT_CH0,0x00,0x1B);//轉(zhuǎn)換之前的穩(wěn)定時(shí)間(T=(SETTLECOUNT_CHx*16)/Frefx)
- Set_FDC2214(SETTLECOUNT_CH1,0x00,0x1B);
- Set_FDC2214(SETTLECOUNT_CH2,0x00,0x1B);
- Set_FDC2214(SETTLECOUNT_CH3,0x00,0x1B);
-
- Set_FDC2214(CLOCK_DIVIDERS_C_CH0,0x20,0x02);//選擇在0.01MHz ~ 10MHz的傳感器頻率
- Set_FDC2214(CLOCK_DIVIDERS_C_CH1,0x20,0x02);//Frefx = Fclk = 43.4MHz/2(2分頻)
- Set_FDC2214(CLOCK_DIVIDERS_C_CH2,0x20,0x02);//CHx_REF_DIVIDER=2;CHx_FIN_SEL=2
- Set_FDC2214(CLOCK_DIVIDERS_C_CH3,0x20,0x02);
-
- Set_FDC2214(DRIVE_CURRENT_CH0,0x78,0x00);//0.146ma(傳感器時(shí)鐘建立+轉(zhuǎn)換時(shí)間的驅(qū)動(dòng)電流)
- Set_FDC2214(DRIVE_CURRENT_CH1,0x78,0x00);
- Set_FDC2214(DRIVE_CURRENT_CH2,0x78,0x00);
- Set_FDC2214(DRIVE_CURRENT_CH3,0x78,0x00);
-
- Set_FDC2214(ERROR_CONFIG,0x00,0x00);//全部禁止錯(cuò)誤匯報(bào)
-
- Set_FDC2214(MUX_CONFIG,0xC2,0x0D);//通道0,1,2 ,3;選擇10Mhz為超過振蕩槽振蕩頻率的最低設(shè)置,多通道,四通道
-
- Set_FDC2214(CONFIG,0x14,0x01);//激活模式,使用內(nèi)部振蕩器做參考頻率,INTB引腳會(huì)隨狀態(tài)寄存器更新被置位
- }
- else return 1;
-
- return 0;
- }
- /*測量線路電容
- *index:0:線路0
- * 1:線路1
- * 2:線路2
- * 3:線路3
- *返回值:線路總電容C
- */
- float Cap_Calculate(u8 index)
- {
- float Cap;
- Data_FDC = FCD2214_ReadCH(index);
- // Cap = 56645.763f/((float)Data_FDC);
- // return ((Cap*Cap)-33);
- Cap = 232021045.248/(Data_FDC);
- return (Cap*Cap);
- }
復(fù)制代碼
全部資料51hei下載地址:
FDC2214程序STM32OLED串口.rar
(362.77 KB, 下載次數(shù): 418)
2018-7-18 16:09 上傳
點(diǎn)擊文件名下載附件
|