主控芯片为mm32,已经过测试,1000pf电容测试效果,误差在1%。程序调试中,仅供参考
- #include "delay.h"
- #include "command.h"
- #include "Vbe.h"
- #include "math.h"
- #include "i2c_master.h"
- #include "MC11S.h"
- #define CLKIN 2.4
- #define PI 3.14159
- int MC11_WriteReg(uint8_t temp)
- {
- u8 data;
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- Delay_ms(10);
- if((temp=0x0C)||(temp=0x0D)||(temp=0x10)||(temp=0x15)||(temp=0x16)||(temp>=0x1D && temp<=0x1F)
- ||(temp>=0x21 && temp<=0x22)||(temp=0x25)||(temp==0x33))
- {
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,REF_SEL_In_CLK|INTB_EN_EN|INTB_MODE_ALERT|CR_1S|OS_SD_Stop_Trans);
- Delay_ms(20);
- MC11_I2C_Transmit(I2C_ADDR[1],temp,temp&0xff);
- Delay_ms(20);
- MC11_I2C_Receive(I2C_ADDR[1],temp,&data);
- printf("\r\nRegAddr:%02X Data:%02X",temp,data);
- if(temp==0x21)
- {
- MC11_I2C_Transmit(I2C_ADDR[1],4,0);
- MC11_I2C_Transmit(I2C_ADDR[1],5,0);
- MC11_I2C_Transmit(I2C_ADDR[1],6,0);
- MC11_I2C_Transmit(I2C_ADDR[1],7,0);
- }
- }
- else printf("\nThis register cannot be written to");
- }
- int MC11_ReadReg(void)
- {
- u8 data=0;
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- Delay_ms(10);
- for(u8 i=4;i<8;i++)
- {
- MC11_I2C_Receive(I2C_ADDR[1],i,&data);
- printf("\r\nRegAddr:%02X Data:%02X",i,data);
- }
-
- for(u8 i=0x0C;i<0x0E;i++)
- {
- MC11_I2C_Receive(I2C_ADDR[1],i,&data);
- printf("\r\nRegAddr:%02X Data:%02X",i,data);
- }
-
- MC11_I2C_Receive(I2C_ADDR[1],0x10,&data);
- printf("\r\nRegAddr:10 Data:%02X",data);
-
-
- for(u8 i=0x15;i<0x17;i++)
- {
- MC11_I2C_Receive(I2C_ADDR[1],i,&data);
- printf("\r\nRegAddr:%02X Data:%02X",i,data);
- }
- MC11_I2C_Receive(I2C_ADDR[1],0x18,&data);
- printf("\r\nRegAddr:18 Data:%02X",data);
-
- for(u8 i=0x1D;i<0x20;i++)
- {
- MC11_I2C_Receive(I2C_ADDR[1],i,&data);
- printf("\r\nRegAddr:%02X Data:%02X",i,data);
- }
-
- for(u8 i=0x21;i<0x23;i++)
- {
- MC11_I2C_Receive(I2C_ADDR[1],i,&data);
- printf("\r\nRegAddr:%02X Data:%02X",i,data);
- }
-
- MC11_I2C_Receive(I2C_ADDR[1],0x25,&data);
- printf("\r\nRegAddr:25 Data:%02X",data);
-
- MC11_I2C_Receive(I2C_ADDR[1],0x33,&data);
- printf("\r\nRegAddr:33 Data:%02X",data);
-
- MC11_I2C_Receive(I2C_ADDR[1],0x7E,&data);
- printf("\r\nRegAddr:7E Data:%02X",data);
-
- MC11_I2C_Receive(I2C_ADDR[1],0x7F,&data);
- printf("\r\nRegAddr:7F Data:%02X",data);
- }
- /**
- * @brief 配置MC11时钟、计数时间
- * @param timer 要设置的时钟
- *@arg REF_SEL_In_CLK = 0x00 //选择内部时钟
- *@arg REF_SEL_Ex_CLK = 0x80 //选择外部时钟
- * @retval 无
- */
- void MC11_SetTimer(uint8_t timer,uint8_t scnt,uint16_t rcnt)
- {
- uint8_t cfg;
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- MC11_I2C_Receive(I2C_ADDR[1],CFG,&cfg);
- cfg=cfg&(~REF_SEL_Ex_CLK);
- cfg=cfg|timer;
-
- MC11_I2C_Transmit(I2C_ADDR[1],SCNT,0x0F);
- MC11_I2C_Transmit(I2C_ADDR[1],RCNT_MSB,rcnt>>8&0xFF);
- MC11_I2C_Transmit(I2C_ADDR[1],RCNT_LSB,rcnt&0xFF);
- }
- /**
- * @brief 配置驱动电流
- * @param I:驱动电流
- *@arg DRIVE_I_02mA 0x00:0.2mA
- *@arg DRIVE_I_04mA 0x10:0.4mA
- *@arg DRIVE_I_08mA 0x20:0.8mA
- *@arg DRIVE_I_16mA 0x30:1.6mA
- *@arg DRIVE_I_24mA 0x40:2.4mA
- *@arg DRIVE_I_32mA 0x50:3.2mA
- *@arg DRIVE_I_32mA1 0x60:3.2mA
- *@arg DRIVE_I_32mA2 0x70:3.2mA
- * @brief 配置电压
- * @param V:驱动电流
- *@arg VDD_SEL 0xFE:VDD
- *@arg VDD_SEL_L 0x01:适用于 2.0V<VDD<2.5V 的情况--低电压
- *@arg VDD_SEL_H 0x00:VDD 电压适配选择:0:适用于 2.5V<VDD<5.5V 的情况--高电压
- * @retval 无
- */
- int MC11_SetDrive_I(uint8_t I,uint8_t V)
- {
- u8 DRIVE_I=0,DRIVE_I2=0,data;float i1, i2;
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- Delay_ms(10);
- if(I==DRIVE_I_02mA) i1 = 0.2;
- else if(I==DRIVE_I_04mA) i1 = 0.4;
- else if(I==DRIVE_I_08mA) i1 = 0.8;
- else if(I==DRIVE_I_16mA) i1 = 1.6;
- else if(I==DRIVE_I_24mA) i1 = 2.4 ;
- else if(I==DRIVE_I_32mA) i1 = 3.2;
- else if(I==DRIVE_I_32mA1) i1 = 3.2 ;
- else if(I==DRIVE_I_32mA2) i1 = 3.2;
- else i1 = 3.2;
- printf("\r\nSet Drive_I:%.1f mA VDD_SEL:%.1f mA",i1,i2);
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,REF_SEL_In_CLK|INTB_EN_EN|INTB_MODE_ALERT|CR_1S|OS_SD_Stop_Trans);
- Delay_ms(20);
- MC11_I2C_Transmit(I2C_ADDR[1],DRIVE_I,I|V);
- MC11_I2C_Receive(I2C_ADDR[1],DRIVE_I,&data);
- // printf("\r\nRegAddr:%02X Data:%02X",i,data);
- }
- /**
- * @brief 配置MC11报警触发门限和解除门限
- * @param TH:设置单通道报警触发门限
- * @param TL:设置单通道报警清除门限
- * @retval 无
- */
- int MC11_SetAlert(float TH,float TL)
- {
- u8 data[2],th,tl;float fTRL=0,fTRH=0;
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- Delay_ms(10);
- printf("\r\nSet TH:%f TL:%f",TH,TL);
- if(TH>255)TH=255;
- if(TL>255)TL=255;
-
- tl=(int)(TL*64);
- th=(int)(TH*64);
- MC11_I2C_Transmit(I2C_ADDR[1],TR_L,tl);
- MC11_I2C_Transmit(I2C_ADDR[1],TR_H,th);
-
- MC11_I2C_Receive(I2C_ADDR[1],TR_L,&data[0]);
- MC11_I2C_Receive(I2C_ADDR[1],TR_H,&data[1]);
- fTRL=data[0]*1.0f/64.0f;
- fTRH=data[1]*1.0f/64.0f;
- printf("设定报警解除位:%.2f 0x%2x 报警位:%.2f 0x%2x 回读TRL:%.2f 回读TRH: %.2f\r\n",TL,tl,TH,th,fTRL,fTRH);
- }
- /**
- * @brief 设置MC11通道Fin和Fref分频系数
- * @param fref_div设置通道的参考时钟分频比
- *@arg FIN_DIV_0 :不分频
- *@arg FIN_DIV_2 :2 分频
- *@arg FIN_DIV_4 :4 分频
- *@arg FIN_DIV_8 :8 分频
- *@arg FIN_DIV_16 :16 分频
- *@arg FIN_DIV_32 :32 分频
- *@arg FIN_DIV_64 :64 分频
- *@arg FIN_DIV_128 :128 分频
- *@arg FIN_DIV_256 :256 分频
- * @param fref_div设置通道的参考时钟分频比
- *@arg 00000000 - 11111111:对应数值1到256(fREF1 = fCLK / (FREF_DIV + 1))
- * @retval 无
- */
- int MC11_SetFreDiv(uint8_t fin_div,uint8_t fref_div)
- {
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- Delay_ms(10);
- if(fin_div==0 || fin_div==16 || fin_div==32 || fin_div==48 || fin_div==64 || fin_div==80|| fin_div==96 || fin_div==112 || fin_div==128)
- {
- MC11_I2C_Transmit(I2C_ADDR[1],FIN_DIV,fin_div);
- Delay_ms(20);
- MC11_I2C_Transmit(I2C_ADDR[1],FREF_DIV,fref_div);
- printf("\r\nSet Fin0_Div:0x%X Set Fref0_Div:%d ",fin_div,fref_div);
- }
- else printf("\r\nSet Fin0_Div or Set Fref0_Div format error");
- }
-
- /**
- * @brief 设置MC11通道
- * @param ch:通道选择寄存器CHX_EN(逻辑地址0x20)bit7-bit6的内容,可配置为:
- *@arg CH_DISABLE = 0x00 //通道 0、1 关闭
- *@arg CH0_ENABLE = 0x40 //通道 0 开启
- *@arg CH1_ENABLE = 0x80 //通道 1 开启
- *@arg CH_ENABLE = 0xC0 //通道 0、1 开启
- * @retval 无
- */
- int MC11_SetChannel(uint8_t ch)
- {
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- Delay_ms(10);
- MC11_I2C_Transmit(I2C_ADDR[1],CHX_EN,ch);
- Delay_ms(20);
- }
- /**
- * @brief 测量读取负温度系数
- * @param 无
- * @retval 无
- */
- int MC11_MeasureVbe(void)
- {
- float vbe;
- vbe = GetAdcAverage(10);
- printf(" Vbe:%.1f mv ",vbe*1000);
- }
- /**
- * @brief 计算修正值
- * @param DATA:DATA1和DATA0的比值
- * @param Coef:修正值
- * @retval Coef:修正值
- */
- float DA10[11] = {0.529,0.623,0.717,0.812,0.906,1.000,1.094,1.187,1.281,1.373,1.466};
- float Coef_fix[11]={0.946,0.963,0.976,0.985,0.993,1.000,1.005,1.011,1.015,1.019,1.023};
- float DA1_DA0(float DATA,float *Coef)
- {
- float k,b;
- // printf("\nDATAin:%.3f ",DATA);
- for(int i=0;i<11;i++)
- {
- if(DATA<DA10[0])
- {
- DATA=DA10[0];
- }
- else if(DATA>DA10[10])
- {
- DATA=DA10[10];
- }
-
- if(DATA<DA10[i])
- {
- // printf(" DATA:%.3f ",DATA);
- k=(Coef_fix[i]-Coef_fix[i-1])/(DA10[i]-DA10[i-1]);
- b=Coef_fix[i]-k*DA10[i];
- *Coef=k*DATA+b;
- // printf("Coef:%.3f ",*Coef);
- break;
- }
- else if(DATA==DA10[i])
- {
- // printf("\nDATA:%.3f ",DATA);
- *Coef=Coef_fix[i];
- // printf("Coef:%.3f ",*Coef);
- break;
- }
- }
-
- return *Coef;
- }
- void MC11S_init(void)
- {
-
- /*当前转换时间10ms 转换时间=建立时间+计数时间+延时*/
- uint8_t scnt=0x3c;//建立时间=scnt*16/Fref
- uint16_t rcnt=0x5dc0;//计数时间=rcnt/Fref
- MC11_I2C_Transmit(I2C_ADDR[1],0x22,0x7A);
- Delay_ms(10);
-
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);//停止测量
- MC11_SetTimer(REF_SEL_In_CLK, scnt, rcnt);//配置建立时间和计数时间
- MC11_SetChannel(CH_ENABLE);//开启双通道
- MC11_I2C_Transmit(I2C_ADDR[1],FIN_DIV,FIN_DIV_32);//采样时钟分频和振荡频率分频
- MC11_I2C_Transmit(I2C_ADDR[1],0x25,DRIVE_I_04mA);//驱动电流设置
- MC11_ReadReg(); //读取相关的所有寄存器配置
- }
- /**
- * @brief 测量读取电容
- * @param 无
- * @retval 无
- */
- #define Cap 22//通道1接10pf参考电容,如此处为其他值,请修改
- int MC11_MeasureCap(void)
- {
- u8 FIN,FREF,data_msb,data_lsb;
- u16 Data0,Data1;
- float C,Coef,DATA;
- u8 FIN0_DIV,FREF0_DIV,RCNTM,RCNTL;
- u16 REV_RCNT;
- u8 sta=0,ack,get_ch=0xc0;
- u32 timeout=20000;
- float F1,F2;
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
- MC11_I2C_Transmit(I2C_ADDR[1],STATUS,0);
- ack = MC11_I2C_Receive(I2C_ADDR[1],CHX_EN,&get_ch);
-
- MC11_I2C_Transmit(I2C_ADDR[1],CFG,REF_SEL_In_CLK|INTB_EN_DIS|INTB_MODE_ALERT|CR_025S|OS_SD_Single_Trans);//单次测量模式
- __measure:
- MC11_I2C_Receive(I2C_ADDR[1],STATUS,&sta);
- timeout--;
- if(!((sta&0x30)==(get_ch>>6)<<4) && timeout>0) goto __measure;
-
- MC11_I2C_Receive(I2C_ADDR[1],DATA_CH0_MSB,&data_msb);//读取通道0振荡值高位
- MC11_I2C_Receive(I2C_ADDR[1],DATA_CH0_LSB,&data_lsb);//读取通道0振荡值低位
- MC11_I2C_Receive(I2C_ADDR[1],FIN_DIV,&FIN0_DIV);//振荡信号分频系数
- MC11_I2C_Receive(I2C_ADDR[1],FREF_DIV,&FREF0_DIV);//采样时钟分频系数
-
- MC11_I2C_Receive(I2C_ADDR[1],RCNT_MSB,&RCNTM);
- MC11_I2C_Receive(I2C_ADDR[1],RCNT_LSB,&RCNTL);
- REV_RCNT=RCNTM<<8|RCNTL;
-
- Data0=(data_msb<<8)|data_lsb;
- F1 = (float)((data_msb<<8|data_lsb)*pow(2,(FIN0_DIV>>4))*2.4/REV_RCNT);//通道频率计算公式
- printf("F1:%.3f ",F1);
-
- // printf("\nData0:%x ",Data0);
- MC11_I2C_Receive(I2C_ADDR[1],DATA_CH1_MSB,&data_msb);
- MC11_I2C_Receive(I2C_ADDR[1],DATA_CH1_LSB,&data_lsb);
- Data1=(data_msb<<8)|data_lsb;
-
- F2 = (float)((data_msb<<8|data_lsb)*pow(2,(FIN0_DIV>>4))*2.4/REV_RCNT);
- // printf(" Data1:%x ",Data1);
- printf("F2:%.3f ",F2);
-
- DA1_DA0((F2/F1),&Coef);
- C=F2/F1*Cap*Coef-10;
- DATA=Data1/Data0;
- printf(" C:%.3f pf \r\n",C);
- }
复制代码
原理图: 无
仿真: 无
代码(仅供参考):
MC11S.7z
(4.46 MB, 下载次数: 1)
|