標(biāo)題:
MC11S測試電容參考程序和資料 32單片機(jī)
[打印本頁]
作者:
5111洋芋
時(shí)間:
2024-8-22 13:37
標(biāo)題:
MC11S測試電容參考程序和資料 32單片機(jī)
主控芯片為mm32,已經(jīng)過測試,1000pf電容測試效果,誤差在1%。程序調(diào)試中,僅供參考
#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時(shí)鐘、計(jì)數(shù)時(shí)間
* @param timer 要設(shè)置的時(shí)鐘
*@arg REF_SEL_In_CLK = 0x00 //選擇內(nèi)部時(shí)鐘
*@arg REF_SEL_Ex_CLK = 0x80 //選擇外部時(shí)鐘
* @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 配置驅(qū)動電流
* @param I:驅(qū)動電流
*@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:驅(qū)動電流
*@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報(bào)警觸發(fā)門限和解除門限
* @param TH:設(shè)置單通道報(bào)警觸發(fā)門限
* @param TL:設(shè)置單通道報(bào)警清除門限
* @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("設(shè)定報(bào)警解除位:%.2f 0x%2x 報(bào)警位:%.2f 0x%2x 回讀TRL:%.2f 回讀TRH: %.2f\r\n",TL,tl,TH,th,fTRL,fTRH);
}
/**
* @brief 設(shè)置MC11通道Fin和Fref分頻系數(shù)
* @param fref_div設(shè)置通道的參考時(shí)鐘分頻比
*@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設(shè)置通道的參考時(shí)鐘分頻比
*@arg 00000000 - 11111111:對應(yīng)數(shù)值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 設(shè)置MC11通道
* @param ch:通道選擇寄存器CHX_EN(邏輯地址0x20)bit7-bit6的內(nèi)容,可配置為:
*@arg CH_DISABLE = 0x00 //通道 0、1 關(guān)閉
*@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 測量讀取負(fù)溫度系數(shù)
* @param 無
* @retval 無
*/
int MC11_MeasureVbe(void)
{
float vbe;
vbe = GetAdcAverage(10);
printf(" Vbe:%.1f mv ",vbe*1000);
}
/**
* @brief 計(jì)算修正值
* @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)
{
/*當(dāng)前轉(zhuǎn)換時(shí)間10ms 轉(zhuǎn)換時(shí)間=建立時(shí)間+計(jì)數(shù)時(shí)間+延時(shí)*/
uint8_t scnt=0x3c;//建立時(shí)間=scnt*16/Fref
uint16_t rcnt=0x5dc0;//計(jì)數(shù)時(shí)間=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);//配置建立時(shí)間和計(jì)數(shù)時(shí)間
MC11_SetChannel(CH_ENABLE);//開啟雙通道
MC11_I2C_Transmit(I2C_ADDR[1],FIN_DIV,FIN_DIV_32);//采樣時(shí)鐘分頻和振蕩頻率分頻
MC11_I2C_Transmit(I2C_ADDR[1],0x25,DRIVE_I_04mA);//驅(qū)動電流設(shè)置
MC11_ReadReg(); //讀取相關(guān)的所有寄存器配置
}
/**
* @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);//振蕩信號分頻系數(shù)
MC11_I2C_Receive(I2C_ADDR[1],FREF_DIV,&FREF0_DIV);//采樣時(shí)鐘分頻系數(shù)
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);//通道頻率計(jì)算公式
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);
}
復(fù)制代碼
51hei.png
(10.53 KB, 下載次數(shù): 8)
下載附件
2024-8-23 00:04 上傳
原理圖: 無
仿真: 無
代碼(僅供參考):
MC11S.7z
(4.46 MB, 下載次數(shù): 2)
2024-8-23 00:06 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1