FDC2214电容传感器驱动程序

FDC2214.C

  1 #include "fdc2214.h"
  2 #include "delay.h"
  3 #include "led.h"
  4 
  5 u32 Data_FDC;
  6 void FDC_IIC_Delay(void)
  7 {
  8     delay_us(2);
  9 }
 10 
 11 void FDC_GPIO_Init(void)
 12 {
 13     
 14 }
 15 
 16 void FDC_IIC_Init(void)
 17 {                         
 18   GPIO_InitTypeDef  GPIO_InitStructure;
 19     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//先使能外设IO PORTC时钟 
 20         
 21   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;//端口配置
 22   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出
 23     //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 24   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //IO口速度为50MHz
 25   GPIO_Init(GPIOC, &GPIO_InitStructure);                        //根据设定参数初始化GPIO 
 26     
 27   GPIO_SetBits(GPIOC,GPIO_Pin_4|GPIO_Pin_5);                  //PC.4,PC.5 输出高    
 28 }
 29 
 30 //产生IIC起始信号
 31 void FDC_IIC_Start(void)
 32 {
 33     FDC_SDA_OUT();     //sda线输出
 34     FDC_IIC_SDA=1;            
 35     FDC_IIC_SCL=1;
 36     FDC_IIC_Delay();
 37      FDC_IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
 38     FDC_IIC_Delay();
 39     FDC_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
 40 }      
 41 //产生IIC停止信号
 42 void FDC_IIC_Stop(void)
 43 {
 44     FDC_SDA_OUT();//sda线输出
 45     FDC_IIC_SCL=0;
 46     FDC_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 47      FDC_IIC_Delay();
 48     FDC_IIC_SCL=1; 
 49     FDC_IIC_SDA=1;//发送I2C总线结束信号
 50     FDC_IIC_Delay();                                   
 51 }
 52 //等待应答信号到来
 53 //返回值:1,接收应答失败
 54 //        0,接收应答成功
 55 u8 FDC_IIC_Wait_Ack(void)
 56 {
 57     u8 ucErrTime=0;
 58     FDC_SDA_IN();      //SDA设置为输入  
 59     FDC_IIC_SDA=1;FDC_IIC_Delay();       
 60     FDC_IIC_SCL=1;FDC_IIC_Delay();     
 61     while(FDC_READ_SDA)
 62     {
 63         ucErrTime++;
 64         if(ucErrTime>250)
 65         {
 66             FDC_IIC_Stop();
 67             return 1;
 68         }
 69     }
 70     FDC_IIC_SCL=0;//时钟输出0        
 71     return 0;  
 72 }
 73 
 74 
 75 //产生ACK应答
 76 //void FDC_IIC_Ack(void)
 77 //{
 78 //    FDC_IIC_SCL=0;
 79 //    FDC_SDA_OUT();
 80 //    FDC_IIC_SDA=0;
 81 //    FDC_IIC_Delay();
 82 //    FDC_IIC_SCL=1;
 83 //    FDC_IIC_Delay();
 84 //    FDC_IIC_SCL=0;
 85 //}
 86 
 87 //debug
 88 void FDC_IIC_Ack(void)
 89 {
 90     FDC_IIC_SCL=0;
 91     FDC_IIC_SDA=0;
 92     FDC_IIC_Delay();
 93     FDC_IIC_SCL=1;
 94     FDC_IIC_Delay();
 95     FDC_IIC_SCL=0;
 96     FDC_IIC_Delay();
 97     FDC_IIC_SDA=1;
 98 }
 99 
100 
101 //不产生ACK应答            
102 void FDC_IIC_NAck(void)
103 {
104     FDC_IIC_SCL=0;
105     FDC_SDA_OUT();
106     FDC_IIC_SDA=1;
107     FDC_IIC_Delay();
108     FDC_IIC_SCL=1;
109     FDC_IIC_Delay();
110     FDC_IIC_SCL=0;
111 }                                          
112 //IIC发送一个字节
113 //返回从机有无应答
114 //1,有应答
115 //0,无应答              
116 void FDC_IIC_Send_Byte(u8 txd)
117 {                        
118   u8 t;   
119     FDC_SDA_OUT();         
120     FDC_IIC_SCL=0;//拉低时钟开始数据传输
121     for(t=0;t<8;t++)
122     {              
123         FDC_IIC_SDA=(txd&0x80)>>7;
124         txd<<=1;       
125             FDC_IIC_SCL=1;
126             FDC_IIC_Delay(); 
127             FDC_IIC_SCL=0;    
128             FDC_IIC_Delay();
129     }     
130 }         
131 //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
132 u8 FDC_IIC_Read_Byte(unsigned char ack)
133 {
134     unsigned char i,receive=0;
135     FDC_SDA_IN();//SDA设置为输入
136     for(i=0;i<8;i++ )
137     {
138         FDC_IIC_SCL=0; 
139         FDC_IIC_Delay();
140         FDC_IIC_SCL=1;
141         receive<<=1;
142         if(FDC_READ_SDA)receive++;   
143         FDC_IIC_Delay(); 
144     }                 
145     if (!ack)
146         FDC_IIC_NAck();//发送nACK
147     else
148         FDC_IIC_Ack(); //发送ACK   
149     return receive;
150 }
151 
152 u8 Set_FDC2214(u8 reg,u8 MSB,u8 LSB)                  
153 { 
154     FDC_IIC_Start(); 
155     FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|0);//发送器件地址+写命令    
156     if(FDC_IIC_Wait_Ack())    //等待应答
157     {
158         FDC_IIC_Stop();         
159         return 1;        
160     }
161     FDC_IIC_Send_Byte(reg);//写寄存器地址
162     FDC_IIC_Wait_Ack();         //等待应答 
163     FDC_IIC_Send_Byte(MSB);  //发送数据1
164     if(FDC_IIC_Wait_Ack())     //等待ACK
165     {
166         FDC_IIC_Stop();     
167         return 1;         
168     }         
169     FDC_IIC_Send_Byte(LSB);  //发送数据2
170     if(FDC_IIC_Wait_Ack())     //等待ACK
171     {
172         FDC_IIC_Stop();     
173         return 1;         
174     }    
175     FDC_IIC_Stop();     
176     return 0;
177 }
178 
179 u16 FDC_Read(u8 reg)
180 {
181     u16 res;
182    FDC_IIC_Start(); 
183     FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|0);//发送器件地址+写命令    
184     FDC_IIC_Wait_Ack();        //等待应答 
185     FDC_IIC_Send_Byte(reg);    //写寄存器地址
186     FDC_IIC_Wait_Ack();        //等待应答
187     FDC_IIC_Start();
188     FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|1);//发送器件地址+读命令    
189     FDC_IIC_Wait_Ack();        //等待应答 
190     res=FDC_IIC_Read_Byte(1)<<8;//读取数据,发送ACK
191     
192 //    FDC_IIC_Ack(); 
193     res|=FDC_IIC_Read_Byte(0);//读取数据,发送nACK
194     FDC_IIC_Stop();            //产生一个停止条件
195     return res;        
196 }
197 
198 u32 FCD2214_ReadCH(u8 index) 
199 {
200     u32 result;
201     switch(index)
202     {
203         case 0:
204           result = FDC_Read(DATA_CH0)&0x0FFF;
205           result = (result<<16)|(FDC_Read(DATA_LSB_CH0));
206             break;
207         case 1:
208             result = FDC_Read(DATA_CH1)&0x0FFF;
209           result = (result<<16)|(FDC_Read(DATA_LSB_CH1));
210             break;
211         case 2:
212             result = FDC_Read(DATA_CH2)&0x0FFF;
213           result = (result<<16)|(FDC_Read(DATA_LSB_CH2));
214             break;
215         case 3:
216             result = FDC_Read(DATA_CH3)&0x0FFF;
217           result = (result<<16)|(FDC_Read(DATA_LSB_CH3));
218             break;
219         default:break;
220     }
221     result =result&0x0FFFFFFF;
222     return result;
223 }
224 
225 /*FDC2214初始化函数
226  *返回值:0:初始化正常
227  *       1:不正常
228  */
229 u8 FDC2214_Init(void)
230 {
231     u16 res,ID_FDC2214;
232     FDC_GPIO_Init();
233     FDC_IIC_Init();
234     res=FDC_Read(MANUFACTURER_ID);//测试设备读取是否正常
235     ID_FDC2214 = FDC_Read(DEVICE_ID);
236     
237     printf("DEVICE_ID:0X%x\r\n",ID_FDC2214);
238     if(res==0x5449)
239     {
240         //设置Set_FDC2214寄存器
241         Set_FDC2214(RCOUNT_CH0,0x34,0xFB);//参考计数转换间隔时间(T=(RCOUNT_CH0*16)/Frefx)
242         Set_FDC2214(RCOUNT_CH1,0x34,0xFB);
243         Set_FDC2214(RCOUNT_CH2,0x34,0xFB);
244         Set_FDC2214(RCOUNT_CH3,0x34,0xFB);
245         
246         Set_FDC2214(SETTLECOUNT_CH0,0x00,0x1B);//转换之前的稳定时间(T=(SETTLECOUNT_CHx*16)/Frefx)
247         Set_FDC2214(SETTLECOUNT_CH1,0x00,0x1B);
248         Set_FDC2214(SETTLECOUNT_CH2,0x00,0x1B);
249         Set_FDC2214(SETTLECOUNT_CH3,0x00,0x1B);
250         
251         Set_FDC2214(CLOCK_DIVIDERS_C_CH0,0x20,0x02);//选择在0.01MHz ~ 10MHz的传感器频率
252         Set_FDC2214(CLOCK_DIVIDERS_C_CH1,0x20,0x02);//Frefx = Fclk = 43.4MHz/2(2分频)
253         Set_FDC2214(CLOCK_DIVIDERS_C_CH2,0x20,0x02);//CHx_REF_DIVIDER=2;CHx_FIN_SEL=2
254         Set_FDC2214(CLOCK_DIVIDERS_C_CH3,0x20,0x02);//CHx_REF_DIVIDER=2;CHx_FIN_SEL=2
255         
256         Set_FDC2214(DRIVE_CURRENT_CH0,0x78,0x00);//0.146ma(传感器时钟建立+转换时间的驱动电流)
257         Set_FDC2214(DRIVE_CURRENT_CH1,0x78,0x00);
258         Set_FDC2214(DRIVE_CURRENT_CH2,0x78,0x00);
259         Set_FDC2214(DRIVE_CURRENT_CH3,0x78,0x00);
260         
261         Set_FDC2214(ERROR_CONFIG,0x00,0x00);//全部禁止错误汇报
262         
263         Set_FDC2214(MUX_CONFIG,0xC2,0x0D);//通道0,1,2 ,3;选择10Mhz为超过振荡槽振荡频率的最低设置,多通道,四通道
264         
265         Set_FDC2214(CONFIG,0x14,0x01);//激活模式,使用内部振荡器做参考频率,INTB引脚会随状态寄存器更新被置位
266     }
267     else return 1;
268     
269     return 0;
270 }
271 
272 float Cap_Calculate(u8 chx)
273 {
274     float Cap;
275     Data_FDC = FCD2214_ReadCH(chx);
276     Cap = 232021045.248/(Data_FDC);
277     return (Cap*Cap);
278 }
View Code

FDC2214.H

 1 #ifndef __FDC2214_H
 2 #define __FDC2214_H
 3 #include "sys.h"
 4 
 5 //IO方向设置
 6 #define FDC_SDA_IN()  {GPIOC->CRL&=0XFF0FFFFF;GPIOC->CRL|=8<<4*5;}
 7 #define FDC_SDA_OUT() {GPIOC->CRL&=0XFF0FFFFF;GPIOC->CRL|=3<<4*5;}
 8 
 9 //IO操作函数     
10 #define FDC_IIC_SCL    PCout(4)     //SCL
11 #define FDC_IIC_SDA    PCout(5)   //输出SDA     
12 #define FDC_READ_SDA   PCin(5)         //输入SDA 
13 
14 /*FDC2214    iic从地址
15  *ADDR = L , I2C Address = 0x2A
16  *ADDR = H , I2C Address = 0x2B*/
17 #define FDC2214_ADDR 0x2A
18 
19 /*FDC2214各个寄存器地址*/
20 #define DATA_CH0 0x00                     //数据寄存器
21 #define DATA_LSB_CH0 0x01
22 #define DATA_CH1 0x02
23 #define DATA_LSB_CH1 0x03
24 #define DATA_CH2 0x04
25 #define DATA_LSB_CH2 0x05
26 #define DATA_CH3 0x06
27 #define DATA_LSB_CH3 0x07
28 #define RCOUNT_CH0 0x08    //
29 #define RCOUNT_CH1 0x09
30 #define RCOUNT_CH2 0x0A
31 #define RCOUNT_CH3 0x0B
32 //#define OFFSET_CH0 0x0C  //FDC2114
33 //#define OFFSET_CH1 0x0D
34 //#define OFFSET_CH2 0x0E
35 //#define OFFSET_CH3 0x0F
36 #define SETTLECOUNT_CH0 0x10
37 #define SETTLECOUNT_CH1 0x11
38 #define SETTLECOUNT_CH2 0x12
39 #define SETTLECOUNT_CH3 0x13
40 #define CLOCK_DIVIDERS_C_CH0 0x14       //时钟分频
41 #define CLOCK_DIVIDERS_C_CH1 0x15
42 #define CLOCK_DIVIDERS_C_CH2 0x16
43 #define CLOCK_DIVIDERS_C_CH3 0x17
44 #define STATUS 0x18                     //状态寄存器
45 #define ERROR_CONFIG 0x19                 //错误报告设置
46 #define CONFIG 0x1A  
47 #define MUX_CONFIG 0x1B
48 #define RESET_DEV 0x1C
49 #define DRIVE_CURRENT_CH0 0x1E          //电流驱动
50 #define DRIVE_CURRENT_CH1 0x1F
51 #define DRIVE_CURRENT_CH2 0x20
52 #define DRIVE_CURRENT_CH3 0x21
53 #define MANUFACTURER_ID 0x7E      //读取值:0x5449
54 #define DEVICE_ID 0x7F            //读取值:0x3055
55 
56 //extern u16 Data_FDC;
57 
58 //相关函数申明
59 u8 Set_FDC2214(u8 reg,u8 MSB,u8 LSB);
60 
61 u16 FDC_Read(u8 reg);
62 
63 //u16 FCD2214_ReadCH(u8 index);
64 u32 FCD2214_ReadCH(u8 index);
65 u8 FDC2214_Init(void);
66 
67 float Cap_Calculate(u8 chx);
68 
69 #endif
View Code

main.c

 1 #include "sys.h"
 2 #include "delay.h"
 3 #include "usart.h"
 4 #include "led.h"
 5 #include "oled.h"
 6 #include "fdc2214.h"
 7 
 8 
 9 void Sys_Init(void);
10 
11 float res0,res1,res2,res3;
12 float temp0,temp1,temp2,temp3;
13 
14 int main(void)
15 {
16   Sys_Init();
17     while(1)
18     {
19         res0 = Cap_Calculate(0);//采集数据(原始数据)
20       res1 = Cap_Calculate(1);
21       res2 = Cap_Calculate(2);
22       res3 = Cap_Calculate(3);
23         
24         res0 = res0-temp0;//电容接口空载减掉初始值
25         res1 = res1-temp1;
26         res2 = res2-temp2;
27         res3 = res3-temp3;
28                     
29         OLED_P6x8Str(0,1,"CH0:",0);Oled_Printf_Float(22,1,res0,0);        
30         OLED_P6x8Str(0,3,"CH1:",0);Oled_Printf_Float(22,3,res1,0);        
31         OLED_P6x8Str(0,5,"CH2:",0);Oled_Printf_Float(22,5,res2,0);        
32         OLED_P6x8Str(0,7,"CH3:",0);Oled_Printf_Float(22,7,res3,0);
33         
34         printf("CH0:%3.3f CH1:%3.3f CH2:%3.3f CH3:%3.3f\r\n",res0,res1,res2,res3);
35         
36         led=~led;
37         
38         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
39     }
40 }
41 
42 void Sys_Init(void)
43 {
44     delay_init();     
45     NVIC_Configuration();
46     uart_init(115200);     //串口波特率115200
47     LED_Init();
48     OLED_Init();
49     printf("OLED OK\r\n");
50     OLED_P6x8Str(82,3,"Float",0);
51     OLED_P6x8Str(67,5,"Technology",0);
52     while(FDC2214_Init());
53     led=0;
54     delay_ms(100);
55     temp0 = Cap_Calculate(0);//读取初始值
56     temp1 = Cap_Calculate(1);
57     temp2 = Cap_Calculate(2);
58     temp3 = Cap_Calculate(3);
59 }
View Code

 

posted @ 2018-07-24 14:48  憨八龟  阅读(1508)  评论(0编辑  收藏  举报