主控芯片為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ù)時間
- * @param timer 要設置的時鐘
- *@arg REF_SEL_In_CLK = 0x00 //選擇內(nèi)部時鐘
- *@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 配置驅(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報警觸發(fā)門限和解除門限
- * @param TH:設置單通道報警觸發(fā)門限
- * @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分頻系數(shù)
- * @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:對應數(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 設置MC11通道
- * @param ch:通道選擇寄存器CHX_EN(邏輯地址0x20)bit7-bit6的內(nèi)容,可配置為:
- *@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 測量讀取負溫度系數(shù)
- * @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)
- {
-
- /*當前轉(zhuǎn)換時間10ms 轉(zhuǎn)換時間=建立時間+計數(shù)時間+延時*/
- uint8_t scnt=0x3c;//建立時間=scnt*16/Fref
- uint16_t rcnt=0x5dc0;//計數(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ù)時間
- 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);//驅(qū)動電流設置
- 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);//振蕩信號分頻系數(shù)
- MC11_I2C_Receive(I2C_ADDR[1],FREF_DIV,&FREF0_DIV);//采樣時鐘分頻系數(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);//通道頻率計算公式
- 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, 下載次數(shù): 8)
下載附件
2024-8-23 00:04 上傳
原理圖: 無
仿真: 無
代碼(僅供參考):
MC11S.7z
(4.46 MB, 下載次數(shù): 2)
2024-8-23 00:06 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|