标题:
MC11S测试电容参考程序和资料 32单片机
[打印本页]
作者:
5111洋芋
时间:
2024-8-22 13:37
标题:
MC11S测试电容参考程序和资料 32单片机
主控芯片为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);
}
复制代码
51hei.png
(10.53 KB, 下载次数: 8)
下载附件
2024-8-23 00:04 上传
原理图: 无
仿真: 无
代码(仅供参考):
MC11S.7z
(4.46 MB, 下载次数: 2)
2024-8-23 00:06 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1