zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ");
    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
  • 相关阅读:
    Spring MVC与JAX-RS比较与分析
    JDK历史版本下载
    第六篇:为多态基类声明虚析构函数
    第五篇:明确拒绝不想编译器自动生成的拷贝构造函数和赋值运算符重载函数
    第四篇:了解 C++ 默默编写并调用的函数
    第三篇:确保对象在被使用前的初始化
    poj 2125(最小割)
    hdu 4704(费马小定理)
    hdu 4705(树形DP)
    poj 3469(网络流模版)
  • 原文地址:https://www.cnblogs.com/duanjinjie/p/9359904.html
Copyright © 2011-2022 走看看