4839|11

379

帖子

3

TA的资源

一粒金砂(高级)

楼主
 

基于GD32F350的数字式电容表 [复制链接]

 
本帖最后由 wenyangzeng 于 2018-9-10 11:36 编辑

            基于GD32F350的数字式电容表


项目概述:
      GD32F350开发板使用了兆易最新推出的ARM Cortex-M4的32位通用微控制器GD32F350RB,这款芯片自带2路比较器,非常适合用来制作一款低成本的数字式电容表。

设计方案:
      图1是由比较器构成的RC自激振荡电路,R1、R2为比较器正端提供1/2偏压,R3是正反馈电阻,待测电容Cx与RT、CT决定了振荡器的输出频率,基本不受供电电压影响。比较器负输入端与输出端的波形见图2。当RT和CT固定不变时,比较器输出端PT1输出的方波频率与待测电容Cx的容量成反比。


                                         图1



                                       图2

      利用GD32F350RB片内自带的轨对轨比较器CMP0,只要外加少量阻容元件,就能构成图1的RC自激振荡电路。然后配置GD32F350的TIMER1每1秒中断1次,读取脉冲个数并计算就能得到待测电容Cx的值。这款低成本的数字电容表的测量范围(具有2位小数的3个自动切换的量程):

1.00pf  - 1999.99pf
2.00nf  - 999.99nf
1.00uf  - 10.00uf


方案实施

A、硬件资源:

      参阅GD32F350手册可知,GD32F350内置的通用比较器可连接的资源非常丰富,用户可以很灵活方便组成各种不同应用功能。本方案(见图3)使用图中红框的连接引脚实现图1自激振荡器功能。比较器的输出直接触发GD32F350内部的EXTI进行计数。



                        图3

      同时,为开发板配置了一片OLED显示屏用来显示测试结果,相关原理图见图4。使用洞洞板焊接了所需的外扩电路。


                                   图4

B、软件资源:

      软件流程很简单,见图5.

                             图5

C、中断资源:

1、ADC_CMP_IRQn
2、CMP0输出中断EXTI21
3、TIMER1_IRQn


D、开发环境:

1、  使用MDK5;
2、  下载GigaDevice.GD32F30x0_DFP.1.0.0.pack为MDK5添加驱动补丁。
3、 下载GD官方GD32F3x0_Firmware_Library_V1.0.0.rar固件库,直接利用GD32F3x0_Firmware_Library_V1.0.0\Template文件夹的演示工程修改添加代码。

     在gd_eval_led_init()函数中配置了LED4来监测1秒中断的工作状况,在官方gd32f3x0_eval.h定义的LED有误,请参考
https://bbs.eeworld.com.cn/thread-869871-1-1.html  进行修改。

E、主要代码

main()
  1. #include "gd32f3x0.h"
  2. #include <stdio.h>
  3. #include "gd32f3x0_eval.h"
  4. #include "oled.h"
  5. static void rcu_config(void);
  6. static void gpio_config(void);
  7. static void nvic_configuration(void);
  8. static void cmp_config(void);
  9. static void timer1_configuration(void);
  10. static void To_Buf(void);
  11. __IO uint32_t CAP_Value,CMP_Count=0x00;__IO uint32_t CAP;
  12. uint8_t Number_buf[12],CAP_OK=0;

  13. int main(void)
  14. {
  15.     SystemInit();
  16.     rcu_config();
  17.     gpio_config();
  18.     gd_eval_led_init(LED4);
  19.     OLED_Init();
  20.     OLED_Clear();
  21.     cmp_config();
  22.     timer1_configuration();
  23.     nvic_configuration();

  24.     LCD_Print(8, 0,"基于GD32F350的",TYPE16X16,TYPE8X16);
  25.     LCD_Print(24, 16,"数字电容表",TYPE16X16,TYPE8X16);        
  26.     CAP_OK=0x00;
  27.         
  28.     while (1)
  29.                 {
  30.                     while(CAP_OK==0x00);
  31.                      To_Buf();
  32.                       LCD_Print(16, 40,Number_buf,TYPE16X16,TYPE8X16);
  33.                       CAP_OK=0x00;
  34.                       CMP_Count=0;                        
  35.                 }
  36. }
复制代码



cmp_config()
  1. static void cmp_config(void)
  2. {
  3.     cmp_mode_init(CMP0, CMP_VERYLOWSPEED , CMP_PA5, CMP_HYSTERESIS_HIGH);
  4.     cmp_output_init(CMP0,CMP_OUTPUT_NONE , CMP_OUTPUT_POLARITY_NOINVERTED);//CMP_OUTPUT_TIMER2IC0
  5.     cmp_enable(CMP0);
  6. }
复制代码


gpio_config()

  1. static void gpio_config(void)
  2. {
  3.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1|GPIO_PIN_5);
  4.     gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_PULLUP, GPIO_PIN_1|GPIO_PIN_5);
  5. gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
  6.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
  7.     gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_6);
  8. gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15);
  9.     gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT , GPIO_PUPD_PULLUP, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15);
  10. }
复制代码



nvic_configuration()
  1. static void nvic_configuration(void)
  2. {
  3.     nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
  4.     nvic_irq_enable(TIMER1_IRQn, 1, 1);
  5.     nvic_irq_enable(ADC_CMP_IRQn, 0, 1);
  6.     exti_init(EXTI_21,EXTI_INTERRUPT,  EXTI_TRIG_RISING);
  7.     exti_interrupt_enable(EXTI_21);
  8. }
复制代码


timer1_configuration()
  1. void timer1_configuration(void)
  2. {  timer_oc_parameter_struct timer_ocintpara;
  3.     timer_parameter_struct timer_initpara;
  4.     timer_deinit(TIMER1);
  5.     timer_initpara.prescaler         = 5399;
  6.     timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
  7.     timer_initpara.counterdirection  = TIMER_COUNTER_UP;
  8.     timer_initpara.period            =1480;
  9.     timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
  10.     timer_initpara.repetitioncounter = 0;
  11.     timer_init(TIMER1,&timer_initpara);
  12.     timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
  13.     timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
  14.     timer_channel_output_config(TIMER1,TIMER_CH_0,&timer_ocintpara);
  15.     timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_0,740);
  16.     timer_channel_output_mode_config(TIMER1,TIMER_CH_0,TIMER_OC_MODE_TIMING);
  17.     timer_channel_output_shadow_config(TIMER1,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
  18.     timer_interrupt_enable(TIMER1,TIMER_INT_CH0);
  19.     timer_interrupt_flag_clear(TIMER1,TIMER_INT_CH0);
  20.     timer_enable(TIMER1);
  21. }
复制代码


ADC_CMP_IRQHandler()
  1. void ADC_CMP_IRQHandler(void)
  2. {
  3.     CMP_Count++;
  4.     EXTI_PD |=0X200000;
  5. }
复制代码


TIMER1_IRQHandler()
  1. void TIMER1_IRQHandler(void)
  2. {
  3.      if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_CH0))
  4.         {
  5.           timer_interrupt_flag_clear(TIMER1,TIMER_INT_CH0);
  6.           CAP_Value=CMP_Count;
  7.           gd_eval_led_toggle(LED4);
  8.           CAP_OK=0x01;
  9.           }
  10. }
复制代码


OLED驱动代码网上彼彼皆是,就不再重复贴出了。

运行结果见图6


                                       图6

视频












补充内容 (2018-11-3 20:26):
static void To_Buf(void)
{        uint8_t unit;
if(CAP_Value==0)CAP_Value=1;
       
                if((uint32_t)CAP_Value>14799)                                                                                        //1.00pf-1999.99pf
                        {
                                CAP=14800000000/CAP_Value;
                                CAP-=125300;
                                if(CAP&0X80000000)CAP=0X00;
                                unit=0;
                        }
                        else
                if((CAP_Value<14800)&&(CAP_Value>148))                //2.00nf-999.99nf
                        {
                                CAP=14800000/CAP_Value;
                                CAP-=148;
                                unit=1;
                        }
                        else       
                                if(CAP_Value>13)
                        {
                                CAP=14800/CAP_Value;                                                                                //1.00uf-10.00uf
                                unit=2;
                        }
       
        if(CAP<1000000)
                        Number_buf[0]=' ';
                        else
                        Number_buf[0]=(CAP%10000000/1000000)+0x30;
                if(CAP<100000)       
                        Number_buf[1]=' ';
                        else
                        Number_buf[1]=(CAP%1000000/100000)+0x30;  
                if(CAP<10000)       
                        Number_buf[2]=' ';
                        else
                        Number_buf[2]=(CAP%100000/10000)+0x30;
                if(CAP<1000)       
                        Number_buf[3]=' ';
                        else       
                        Number_buf[3]=(CAP%10000/1000)+0x30;
       
                if(CAP<100)       
                        Number_buf[4]=' ';
                        else               
                        Number_buf[4]=(CAP%1000/100)+0x30;
                        Number_buf[5]='.';                                
                       
                        Number_buf[6]=(CAP%100/10)+0x30;

                       
                        Number_buf[7]=(CAP%10)+0x30;
                        Number_buf[8]=' ';
                       
                        if(unit==0)
                        Number_buf[9]='p';
                        else
                        if(unit==1)
                        Number_buf[9]='n';
                        else
                        if(unit==2)
                        Number_buf[9]='u';
                        Number_buf[10]='f';
                        Number_buf[11]='\0';
}
此帖出自GD32 MCU论坛

最新回复

厉害  详情 回复 发表于 2018-11-4 18:13
点赞 关注(3)
 

回复
举报

5263

帖子

239

TA的资源

管理员

来自 2楼
 
附给评委补充材料:


经验分享
wenyangzeng
GD32F350开发板调试环境建立
经验分享
wenyangzeng
GD32F3x0固件库一个文件的修改


此帖出自GD32 MCU论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

gd32f3x0_eval.h的修改附件  详情 回复 发表于 2018-11-3 20:45
附件补充  详情 回复 发表于 2018-11-3 20:34
 
 
 

回复

578

帖子

0

TA的资源

纯净的硅(初级)

板凳
 
楼主强大,学习了
此帖出自GD32 MCU论坛

点评

谢谢楼上的支持  详情 回复 发表于 2018-9-10 07:13
 
个人签名刻苦学习,共同进步
 
 

回复

379

帖子

3

TA的资源

一粒金砂(高级)

4
 
迈尔风随 发表于 2018-9-9 23:37
楼主强大,学习了

谢谢楼上的支持
此帖出自GD32 MCU论坛
 
 
 

回复

1382

帖子

2

TA的资源

五彩晶圆(初级)

5
 
这个设计很简洁。用Timer测量,分辨率可以。 重复测量的稳定度怎样?
此帖出自GD32 MCU论坛

点评

主要就是定时器的精度和比较器自激振荡脉冲的抖动率。  详情 回复 发表于 2018-9-10 10:38
 
 
 

回复

379

帖子

3

TA的资源

一粒金砂(高级)

6
 
本帖最后由 wenyangzeng 于 2018-9-10 10:41 编辑
cruelfox 发表于 2018-9-10 10:12
这个设计很简洁。用Timer测量,分辨率可以。 重复测量的稳定度怎样?

主要就是定时器的定时精度和比较器自激振荡脉冲的抖动率。抖动率引起测量值小数位的波动。
此帖出自GD32 MCU论坛
 
 
 

回复

606

帖子

20

TA的资源

一粒金砂(高级)

7
 
项目源码 PCB没有提交呢?
此帖出自GD32 MCU论坛
 
 
 

回复

379

帖子

3

TA的资源

一粒金砂(高级)

8
 
nmg 发表于 2018-10-25 09:05
附给评委补充材料:

附件补充
cap.rar (12.92 MB, 下载次数: 37)


此帖出自GD32 MCU论坛
 
 
 

回复

379

帖子

3

TA的资源

一粒金砂(高级)

9
 
nmg 发表于 2018-10-25 09:05
附给评委补充材料:

gd32f3x0_eval.h的修改附件

gd32f3x0_eval.rar (1.01 KB, 下载次数: 7)


此帖出自GD32 MCU论坛
 
 
 

回复

5263

帖子

239

TA的资源

管理员

10
 
作者补充作品完整源码
cap.rar (12.92 MB, 下载次数: 61)
此帖出自GD32 MCU论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

750

帖子

3

TA的资源

版主

11
 
厉害
此帖出自GD32 MCU论坛

点评

版主过奖了,谢谢  详情 回复 发表于 2018-11-4 20:44
 
 
 

回复

379

帖子

3

TA的资源

一粒金砂(高级)

12
 

版主过奖了,谢谢
此帖出自GD32 MCU论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表