找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 265|回复: 0
收起左侧

MC11S测试电容参考程序和资料 32单片机

[复制链接]
ID:643659 发表于 2024-8-22 13:37 | 显示全部楼层 |阅读模式
主控芯片为mm32,已经过测试,1000pf电容测试效果,误差在1%。程序调试中,仅供参考

  1. #include "delay.h"
  2. #include "command.h"
  3. #include "Vbe.h"
  4. #include "math.h"
  5. #include "i2c_master.h"
  6. #include "MC11S.h"
  7. #define CLKIN 2.4
  8. #define PI 3.14159



  9. int MC11_WriteReg(uint8_t temp)
  10. {
  11.         u8 data;

  12.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  13.         Delay_ms(10);
  14.         if((temp=0x0C)||(temp=0x0D)||(temp=0x10)||(temp=0x15)||(temp=0x16)||(temp>=0x1D && temp<=0x1F)
  15.                 ||(temp>=0x21 && temp<=0x22)||(temp=0x25)||(temp==0x33))
  16.         {
  17.                 MC11_I2C_Transmit(I2C_ADDR[1],CFG,REF_SEL_In_CLK|INTB_EN_EN|INTB_MODE_ALERT|CR_1S|OS_SD_Stop_Trans);
  18.                 Delay_ms(20);
  19.                 MC11_I2C_Transmit(I2C_ADDR[1],temp,temp&0xff);
  20.                 Delay_ms(20);
  21.                 MC11_I2C_Receive(I2C_ADDR[1],temp,&data);
  22.                 printf("\r\nRegAddr:%02X  Data:%02X",temp,data);
  23.                 if(temp==0x21)
  24.                 {
  25.                         MC11_I2C_Transmit(I2C_ADDR[1],4,0);
  26.                         MC11_I2C_Transmit(I2C_ADDR[1],5,0);
  27.                         MC11_I2C_Transmit(I2C_ADDR[1],6,0);
  28.                         MC11_I2C_Transmit(I2C_ADDR[1],7,0);
  29.                 }
  30.         }
  31.         else printf("\nThis register cannot be written to");
  32. }


  33. int MC11_ReadReg(void)
  34. {
  35.         u8 data=0;
  36.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  37.         Delay_ms(10);
  38.         for(u8 i=4;i<8;i++)
  39.         {
  40.                 MC11_I2C_Receive(I2C_ADDR[1],i,&data);
  41.                 printf("\r\nRegAddr:%02X  Data:%02X",i,data);
  42.         }
  43.         
  44.         for(u8 i=0x0C;i<0x0E;i++)
  45.         {
  46.                 MC11_I2C_Receive(I2C_ADDR[1],i,&data);
  47.                 printf("\r\nRegAddr:%02X  Data:%02X",i,data);
  48.         }
  49.         
  50.         MC11_I2C_Receive(I2C_ADDR[1],0x10,&data);
  51.         printf("\r\nRegAddr:10  Data:%02X",data);
  52.         
  53.         
  54.         for(u8 i=0x15;i<0x17;i++)
  55.         {
  56.                 MC11_I2C_Receive(I2C_ADDR[1],i,&data);
  57.                 printf("\r\nRegAddr:%02X  Data:%02X",i,data);
  58.         }

  59.         MC11_I2C_Receive(I2C_ADDR[1],0x18,&data);
  60.         printf("\r\nRegAddr:18  Data:%02X",data);
  61.         
  62.         for(u8 i=0x1D;i<0x20;i++)
  63.         {
  64.                 MC11_I2C_Receive(I2C_ADDR[1],i,&data);
  65.                 printf("\r\nRegAddr:%02X  Data:%02X",i,data);
  66.         }
  67.         
  68.         for(u8 i=0x21;i<0x23;i++)
  69.         {
  70.                 MC11_I2C_Receive(I2C_ADDR[1],i,&data);
  71.                 printf("\r\nRegAddr:%02X  Data:%02X",i,data);
  72.         }
  73.         
  74.         MC11_I2C_Receive(I2C_ADDR[1],0x25,&data);
  75.         printf("\r\nRegAddr:25  Data:%02X",data);
  76.         
  77.         MC11_I2C_Receive(I2C_ADDR[1],0x33,&data);
  78.         printf("\r\nRegAddr:33  Data:%02X",data);
  79.         
  80.         MC11_I2C_Receive(I2C_ADDR[1],0x7E,&data);
  81.         printf("\r\nRegAddr:7E  Data:%02X",data);
  82.         
  83.         MC11_I2C_Receive(I2C_ADDR[1],0x7F,&data);
  84.         printf("\r\nRegAddr:7F  Data:%02X",data);
  85. }


  86. /**
  87.   * @brief  配置MC11时钟、计数时间
  88.   * @param  timer 要设置的时钟
  89. *@arg   REF_SEL_In_CLK  = 0x00  //选择内部时钟
  90. *@arg   REF_SEL_Ex_CLK  = 0x80  //选择外部时钟
  91.   * @retval 无
  92. */
  93. void MC11_SetTimer(uint8_t timer,uint8_t scnt,uint16_t rcnt)
  94. {        
  95.         uint8_t cfg;
  96.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  97.         MC11_I2C_Receive(I2C_ADDR[1],CFG,&cfg);
  98.   cfg=cfg&(~REF_SEL_Ex_CLK);
  99.   cfg=cfg|timer;
  100.         
  101.         MC11_I2C_Transmit(I2C_ADDR[1],SCNT,0x0F);
  102.         MC11_I2C_Transmit(I2C_ADDR[1],RCNT_MSB,rcnt>>8&0xFF);
  103.         MC11_I2C_Transmit(I2C_ADDR[1],RCNT_LSB,rcnt&0xFF);
  104. }

  105. /**
  106.   * @brief  配置驱动电流
  107.   * @param  I:驱动电流
  108. *@arg DRIVE_I_02mA              0x00:0.2mA
  109. *@arg DRIVE_I_04mA              0x10:0.4mA
  110. *@arg DRIVE_I_08mA              0x20:0.8mA
  111. *@arg DRIVE_I_16mA              0x30:1.6mA
  112. *@arg DRIVE_I_24mA              0x40:2.4mA
  113. *@arg DRIVE_I_32mA              0x50:3.2mA
  114. *@arg DRIVE_I_32mA1             0x60:3.2mA
  115. *@arg DRIVE_I_32mA2             0x70:3.2mA
  116.   * @brief  配置电压
  117.   * @param  V:驱动电流
  118. *@arg VDD_SEL                   0xFE:VDD
  119. *@arg VDD_SEL_L                 0x01:适用于 2.0V<VDD<2.5V 的情况--低电压
  120. *@arg VDD_SEL_H                 0x00:VDD 电压适配选择:0:适用于 2.5V<VDD<5.5V 的情况--高电压
  121.   * @retval 无
  122. */
  123. int MC11_SetDrive_I(uint8_t I,uint8_t V)
  124. {
  125.         u8 DRIVE_I=0,DRIVE_I2=0,data;float i1, i2;
  126.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  127.         Delay_ms(10);
  128.         if(I==DRIVE_I_02mA)       i1 = 0.2;
  129.         else if(I==DRIVE_I_04mA)  i1 = 0.4;
  130.         else if(I==DRIVE_I_08mA)  i1 = 0.8;
  131.         else if(I==DRIVE_I_16mA)  i1 = 1.6;
  132.         else if(I==DRIVE_I_24mA)  i1 = 2.4 ;
  133.         else if(I==DRIVE_I_32mA)  i1 = 3.2;
  134.         else if(I==DRIVE_I_32mA1) i1 = 3.2 ;
  135.         else if(I==DRIVE_I_32mA2) i1 = 3.2;
  136.         else i1 = 3.2;

  137.         printf("\r\nSet Drive_I:%.1f mA VDD_SEL:%.1f mA",i1,i2);
  138.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,REF_SEL_In_CLK|INTB_EN_EN|INTB_MODE_ALERT|CR_1S|OS_SD_Stop_Trans);
  139.         Delay_ms(20);
  140.         MC11_I2C_Transmit(I2C_ADDR[1],DRIVE_I,I|V);

  141.         MC11_I2C_Receive(I2C_ADDR[1],DRIVE_I,&data);
  142. //                printf("\r\nRegAddr:%02X  Data:%02X",i,data);

  143. }

  144. /**
  145.   * @brief  配置MC11报警触发门限和解除门限
  146.   * @param  TH:设置单通道报警触发门限
  147.   * @param  TL:设置单通道报警清除门限
  148.   * @retval 无
  149. */

  150. int MC11_SetAlert(float TH,float TL)
  151. {
  152.         u8 data[2],th,tl;float fTRL=0,fTRH=0;
  153.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  154.         Delay_ms(10);
  155.         printf("\r\nSet TH:%f TL:%f",TH,TL);
  156.         if(TH>255)TH=255;
  157.         if(TL>255)TL=255;
  158.         
  159.         tl=(int)(TL*64);
  160.         th=(int)(TH*64);
  161.         MC11_I2C_Transmit(I2C_ADDR[1],TR_L,tl);
  162.         MC11_I2C_Transmit(I2C_ADDR[1],TR_H,th);
  163.         
  164.         MC11_I2C_Receive(I2C_ADDR[1],TR_L,&data[0]);
  165.         MC11_I2C_Receive(I2C_ADDR[1],TR_H,&data[1]);
  166.         fTRL=data[0]*1.0f/64.0f;
  167.         fTRH=data[1]*1.0f/64.0f;
  168.         printf("设定报警解除位:%.2f 0x%2x 报警位:%.2f 0x%2x 回读TRL:%.2f 回读TRH: %.2f\r\n",TL,tl,TH,th,fTRL,fTRH);        

  169. }

  170. /**
  171. * @brief  设置MC11通道Fin和Fref分频系数
  172. * @param  fref_div设置通道的参考时钟分频比
  173. *@arg FIN_DIV_0    :不分频
  174. *@arg FIN_DIV_2    :2 分频
  175. *@arg FIN_DIV_4    :4 分频
  176. *@arg FIN_DIV_8    :8 分频
  177. *@arg FIN_DIV_16   :16 分频
  178. *@arg FIN_DIV_32   :32 分频
  179. *@arg FIN_DIV_64   :64 分频
  180. *@arg FIN_DIV_128  :128 分频        
  181. *@arg FIN_DIV_256  :256 分频
  182. * @param  fref_div设置通道的参考时钟分频比
  183. *@arg 00000000 - 11111111:对应数值1到256(fREF1 = fCLK / (FREF_DIV + 1))
  184. * @retval 无
  185. */
  186. int MC11_SetFreDiv(uint8_t fin_div,uint8_t fref_div)
  187. {
  188.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  189.         Delay_ms(10);

  190.         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)
  191.         {
  192.                 MC11_I2C_Transmit(I2C_ADDR[1],FIN_DIV,fin_div);
  193.                 Delay_ms(20);
  194.                 MC11_I2C_Transmit(I2C_ADDR[1],FREF_DIV,fref_div);
  195.                 printf("\r\nSet Fin0_Div:0x%X Set Fref0_Div:%d ",fin_div,fref_div);
  196.         }
  197.         else printf("\r\nSet Fin0_Div or Set Fref0_Div format error");
  198. }


  199. /**
  200.   * @brief  设置MC11通道
  201.   * @param  ch:通道选择寄存器CHX_EN(逻辑地址0x20)bit7-bit6的内容,可配置为:
  202. *@arg  CH_DISABLE              = 0x00  //通道 0、1 关闭
  203. *@arg  CH0_ENABLE              = 0x40  //通道 0 开启
  204. *@arg  CH1_ENABLE              = 0x80  //通道 1 开启
  205. *@arg  CH_ENABLE               = 0xC0  //通道 0、1 开启
  206.   * @retval 无
  207. */
  208. int MC11_SetChannel(uint8_t ch)
  209. {
  210.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  211.         Delay_ms(10);

  212.         MC11_I2C_Transmit(I2C_ADDR[1],CHX_EN,ch);        
  213.         Delay_ms(20);
  214. }

  215. /**
  216.   * @brief  测量读取负温度系数
  217.   * @param  无
  218.   * @retval 无
  219. */
  220. int MC11_MeasureVbe(void)
  221. {
  222.         float vbe;
  223.         vbe = GetAdcAverage(10);
  224.         printf("  Vbe:%.1f mv ",vbe*1000);
  225. }

  226. /**
  227.   * @brief  计算修正值
  228.   * @param  DATA:DATA1和DATA0的比值
  229.   * @param  Coef:修正值
  230.   * @retval Coef:修正值
  231. */
  232. 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};
  233. 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};

  234. float DA1_DA0(float DATA,float *Coef)
  235. {
  236.         float k,b;
  237. //        printf("\nDATAin:%.3f ",DATA);
  238.         for(int i=0;i<11;i++)
  239.         {
  240.                 if(DATA<DA10[0])
  241.                 {
  242.                   DATA=DA10[0];
  243.                 }
  244.                 else if(DATA>DA10[10])
  245.                 {
  246.                   DATA=DA10[10];
  247.                 }               
  248.                
  249.           if(DATA<DA10[i])
  250.                 {
  251. //                        printf(" DATA:%.3f ",DATA);
  252.                         k=(Coef_fix[i]-Coef_fix[i-1])/(DA10[i]-DA10[i-1]);
  253.                         b=Coef_fix[i]-k*DA10[i];
  254.                         *Coef=k*DATA+b;
  255. //                        printf("Coef:%.3f ",*Coef);
  256.                         break;
  257.                 }
  258.                 else if(DATA==DA10[i])
  259.                 {
  260. //                  printf("\nDATA:%.3f ",DATA);
  261.                         *Coef=Coef_fix[i];
  262. //                        printf("Coef:%.3f ",*Coef);
  263.                         break;
  264.                 }
  265.         }
  266.         
  267.         return *Coef;
  268. }


  269. void MC11S_init(void)
  270. {
  271.         
  272.   /*当前转换时间10ms   转换时间=建立时间+计数时间+延时*/
  273.         uint8_t scnt=0x3c;//建立时间=scnt*16/Fref
  274.         uint16_t rcnt=0x5dc0;//计数时间=rcnt/Fref
  275.         MC11_I2C_Transmit(I2C_ADDR[1],0x22,0x7A);
  276.     Delay_ms(10);
  277.         
  278.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);//停止测量
  279.         MC11_SetTimer(REF_SEL_In_CLK, scnt, rcnt);//配置建立时间和计数时间
  280.     MC11_SetChannel(CH_ENABLE);//开启双通道
  281.         MC11_I2C_Transmit(I2C_ADDR[1],FIN_DIV,FIN_DIV_32);//采样时钟分频和振荡频率分频
  282.     MC11_I2C_Transmit(I2C_ADDR[1],0x25,DRIVE_I_04mA);//驱动电流设置
  283.     MC11_ReadReg();        //读取相关的所有寄存器配置

  284. }

  285. /**
  286.   * @brief  测量读取电容
  287.   * @param  无
  288.   * @retval 无
  289. */
  290. #define Cap      22//通道1接10pf参考电容,如此处为其他值,请修改
  291. int MC11_MeasureCap(void)
  292. {
  293.         u8 FIN,FREF,data_msb,data_lsb;
  294.         u16 Data0,Data1;
  295.         float C,Coef,DATA;
  296.         u8 FIN0_DIV,FREF0_DIV,RCNTM,RCNTL;
  297.         u16 REV_RCNT;
  298.         u8 sta=0,ack,get_ch=0xc0;
  299.         u32 timeout=20000;
  300.         float F1,F2;

  301.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,OS_SD_Stop_Trans);
  302.         MC11_I2C_Transmit(I2C_ADDR[1],STATUS,0);
  303.         ack = MC11_I2C_Receive(I2C_ADDR[1],CHX_EN,&get_ch);
  304.         
  305.         MC11_I2C_Transmit(I2C_ADDR[1],CFG,REF_SEL_In_CLK|INTB_EN_DIS|INTB_MODE_ALERT|CR_025S|OS_SD_Single_Trans);//单次测量模式

  306.         __measure:
  307.         MC11_I2C_Receive(I2C_ADDR[1],STATUS,&sta);

  308.         timeout--;
  309.         if(!((sta&0x30)==(get_ch>>6)<<4) && timeout>0) goto __measure;
  310.         
  311.         MC11_I2C_Receive(I2C_ADDR[1],DATA_CH0_MSB,&data_msb);//读取通道0振荡值高位
  312.         MC11_I2C_Receive(I2C_ADDR[1],DATA_CH0_LSB,&data_lsb);//读取通道0振荡值低位
  313.         MC11_I2C_Receive(I2C_ADDR[1],FIN_DIV,&FIN0_DIV);//振荡信号分频系数
  314.         MC11_I2C_Receive(I2C_ADDR[1],FREF_DIV,&FREF0_DIV);//采样时钟分频系数
  315.         
  316.         MC11_I2C_Receive(I2C_ADDR[1],RCNT_MSB,&RCNTM);
  317.         MC11_I2C_Receive(I2C_ADDR[1],RCNT_LSB,&RCNTL);
  318.         REV_RCNT=RCNTM<<8|RCNTL;
  319.         
  320.         Data0=(data_msb<<8)|data_lsb;
  321.         F1 = (float)((data_msb<<8|data_lsb)*pow(2,(FIN0_DIV>>4))*2.4/REV_RCNT);//通道频率计算公式
  322.         printf("F1:%.3f  ",F1);
  323.         
  324. //        printf("\nData0:%x  ",Data0);
  325.         MC11_I2C_Receive(I2C_ADDR[1],DATA_CH1_MSB,&data_msb);
  326.         MC11_I2C_Receive(I2C_ADDR[1],DATA_CH1_LSB,&data_lsb);        
  327.   Data1=(data_msb<<8)|data_lsb;        
  328.   
  329.     F2 = (float)((data_msb<<8|data_lsb)*pow(2,(FIN0_DIV>>4))*2.4/REV_RCNT);
  330. //        printf("  Data1:%x  ",Data1);
  331.         printf("F2:%.3f ",F2);
  332.         
  333.         DA1_DA0((F2/F1),&Coef);
  334.         C=F2/F1*Cap*Coef-10;
  335.         DATA=Data1/Data0;
  336.         printf("   C:%.3f pf \r\n",C);
  337. }
复制代码
51hei.png

原理图: 无
仿真: 无
代码(仅供参考): MC11S.7z (4.46 MB, 下载次数: 1)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表