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 }
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
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 }