一、基本原理

对于Source-Free RC电路,其电容放电的特性可以描述为:

其中V0是电容的初始电压,t是放电时间,R是串接的电阻阻值,C是电容值,v(t)是t时刻电容上的电压。因此,若已知V0、R、以及t1时刻的电压Vt1,便可求得C:

二、如何控制和测量

如上图所示,大致步骤为:1)由GPIO通过电阻R给电容C充电至Vcc;2)该GPIO输出0,电容C通过R进行放电,同时Timer开始计时、CA+开启;3)当电容电压放电至参考电压(此处是0.25Vcc)时,比较器CA+输出端出现电平变化;4)中断程序捕获这一变化,并利用Timer的capture mode获得该时刻的时间,最后通过以上方程计算电容值。

上图中R推荐采用1%精度的电阻,以提高测试精度。

三、状态转换图

四、测试代码

main.c程序:

  1 // C meter 2015.9.26
  2 //
  3 // P1.5(TA0.0) --[||||]----------- P1.4(CA3)
  4 //             R=10kOhm     |
  5 //                       -----
  6 //                   cap -----
  7 //                         |
  8 //                        GND
  9 //  http://zlbg.cnblogs.com
 10 /////
 11
 12 #include "io430.h"
 13
 14 #define LED1 BIT0 // P1.0, red led
 15 #define LED2 BIT6 // P1.6, green led
 16
 17 #define VMEAS BIT4 // P1.4(CA4) for voltage measurement of the cap
 18 #define VCTRL BIT5 // P1.5(TA0.0) for voltage control
 19 #define PUSH2 BIT3 // P1.3, button
 20
 21 #define RXD BIT1 //P1.1
 22 #define TXD BIT2 //P1.2
 23
 24 #define READY 0
 25 #define CHARGING 1
 26 #define DISCHARGING 2
 27 #define FINISH_DC 3
 28
 29 #define R_SERIES 10000 //10kOhm
 30 #define LN4 1.3863
 31
 32 //functions for C meter
 33 void P1Init(void);
 34 void TA0Init(void);
 35 void CAInit(void);
 36   37 void setReadyStatus(void);
 38
 39 //functions for printf()
 40 void sendByte(unsigned char);
 41 void printf(char *, ...);
 42 void initUART(void);
 43
 44 char state = READY;
 45 unsigned char overflowsCharging = 0;
 46 unsigned char overflowsDischarging = 0;
 47 unsigned char i = 0;
 48 float capacitance = 0; // unit: nF
 49
 50 void main(void)
 51 {
 52     // Stop watchdog timer to prevent time out reset
 53     WDTCTL = WDTPW + WDTHOLD;
 54
 55     // DCO setup
 56     BCSCTL1 = CALBC1_1MHZ; //running at 1Mhz
 57     DCOCTL = CALDCO_1MHZ;
 58
 59     // P1 setup
 60     P1Init();
 61
 62     // Timer0 setup
 63     TA0Init();
 64
 65     // CA setup
 66     CAInit();
 67
 68     // UART setup
 69     initUART();
 70
 71     setReadyStatus();
 72
 73     __enable_interrupt();
 74
 75     // enter LP mode
 76     LPM0;
 77
 78 }
 79
 80
 81 void P1Init(void)
 82 {
 83     P1OUT = 0;
 84
 85     // set P1.3 (PUSH2) as input with pullup
 86     P1OUT |= PUSH2;
 87     P1REN |= PUSH2;
 88
 89     // set P1.0, P1.6, P1.5 as output
 90     P1DIR |= LED1 + LED2 + VCTRL;
 91
 92     // enable P1.3 interrupt
 93     P1IES |= PUSH2; // high -> low transition
 94     P1IFG &= ~PUSH2; // clear the flag
 95     P1IE |= PUSH2;
 96 }
 97
 98 void TA0Init(void)
 99 {
100     // use SMCLK (1MHz), no div, clear, halt
101     TA0CTL = TASSEL_2 + ID_0 + MC_0 + TACLR;
102
103     // TA0CCTL0: compare mode, enable interrupt
104     TA0CCTL0 = CCIE;
105
106     // TA0CCTL1: capture mode, no capture, CCI1B(CAOUT) input, syn capture
107     // interrupt enabled
108     TA0CCTL1 = CCIS_1 + SCS + CAP + CCIE;
109 }
110
111 void CAInit(void)
112 {
113     //0.25 Vcc ref on V+, halt
114     CACTL1 = CAREF_1 + CAIES;
115     // input CA4 (P1.4), remove the jumper) on V-, filter on
116     CACTL2 = P2CA3 + CAF;
117 }
118
119 void setReadyStatus(void)
120 {
121     state = READY;
122     // light led2 and turn off led1 to indicate ready
123     P1OUT &= ~LED1;
124     P1OUT |= LED2;
125
126     //stop and clear timer, stop T0_A1 capture & CA+
127     TA0CTL = TASSEL_2 + ID_0 + MC_0 + TACLR;
128     TA0CCTL1 &= ~CM_3;
129     CACTL1 &= ~CAON;
130
131     overflowsCharging = 0;
132 }
133
134 void initUART(void) {
135         //config P1.1 RXD, P1.2 TXD
136         P1SEL |= TXD + RXD;
137         P1SEL2 |= TXD + RXD;
138
139         //reset UCA0, to be configured
140         UCA0CTL1 = UCSWRST;
141         //config
142         UCA0CTL1 |= UCSSEL_2; //SMCLK
143         UCA0BR0 = 104;
144         UCA0BR1 = 0;//1MHz baut rate = 9600 8-N-1
145         UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1
146         //make UCA0 out of reset
147         UCA0CTL1 &= ~UCSWRST;
148 }
149
150
151 void sendByte(unsigned char byte )
152 {
153     while (!(IFG2&UCA0TXIFG));            // USCI_A0 TX buffer ready?
154     UCA0TXBUF = byte;                // TX -> RXed character
155 }
156
157 #pragma vector = PORT1_VECTOR
158 __interrupt void P1_ISR(void)
159 {
160     if((P1IFG & PUSH2) == PUSH2)
161     {
162         P1IFG &= ~PUSH2; //clear the flag
163         switch(state)
164         {
165         case READY:
166             state = CHARGING;
167             // light LED1 and turn off LED2, indicate a busy status
168             P1OUT |= LED1;
169             P1OUT &= ~LED2;
170             //start timer, continuous mode
171             TACTL |= MC_2;
172             //start charging
173             P1OUT |= VCTRL;
174             break;
175         default:
176             break;
177         }
178
179     }
180     else
181     {
182         P1IFG = 0;
183     }
184 }
185
186 #pragma vector = TIMER0_A0_VECTOR
187 __interrupt void CCR0_ISR(void)
188 {
189     switch(state)
190     {
191     case CHARGING:
192         if (++overflowsCharging == 50) // wait 6.5535*50 = 3.28s
193         {
194             state = DISCHARGING;
195             CACTL1 |= CAON; // turn on CA+
196             TA0CCTL1 |= CM_1; // start TA1 capture on rising edge
197             P1OUT &= ~VCTRL; // start discharging
198             overflowsDischarging = 0;
199         }
200         break;
201     case DISCHARGING:
202         overflowsDischarging++;
203     default:
204         break;
205
206     }
207
208 }
209
210 #pragma vector = TIMER0_A1_VECTOR
211 __interrupt void CCR1_ISR(void)
212 {
213     TA0CTL &= ~MC_3; //stop timer
214     TA0CCTL1 &= ~CCIFG; // clear flag
215     switch(state)
216     {
217     case DISCHARGING:
218         state = FINISH_DC;
219         capacitance = (overflowsDischarging*65536 + TA0CCR1)*1000 / (R_SERIES*LN4); //nF
220         //send result to PC
221         printf("Capatitance:  %n", (long unsigned)capacitance);
222         printf(" nF\r\n");
223
224         setReadyStatus();
225         break;
226     default:
227         break;
228     }
229 }

printf.c程序:为将电容结果通过UART输出至PC显示,以下这段程序实现了printf()函数,代码来自于NJC's MSP430 LaunchPad Blog博客和oPossum的代码。

  1 /******************************************************************************
  2  *                          Reusable MSP430 printf()
  3  *
  4  * Description: This printf function was written by oPossum and originally
  5  *              posted on the 43oh.com forums. For more information on this
  6  *              code, please see the link below.
  7  *
  8  *              http://www.43oh.com/forum/viewtopic.php?f=10&t=1732
  9  *
 10  *              A big thanks to oPossum for sharing such great code!
 11  *
 12  * Author:  oPossum
 13  * Source:  http://www.43oh.com/forum/viewtopic.php?f=10&t=1732
 14  * Date:    10-17-11
 15  *
 16  * Note: This comment section was written by Nicholas J. Conn on 06-07-2012
 17  *       for use on NJC's MSP430 LaunchPad Blog.
 18  ******************************************************************************/
 19
 20 #include "stdarg.h"
 21
 22 void putc(unsigned);
 23 void puts(char *);
 24
 25 static const unsigned long dv[] = {
 26 //  4294967296      // 32 bit unsigned max
 27         1000000000,// +0
 28         100000000, // +1
 29         10000000, // +2
 30         1000000, // +3
 31         100000, // +4
 32 //       65535      // 16 bit unsigned max
 33         10000, // +5
 34         1000, // +6
 35         100, // +7
 36         10, // +8
 37         1, // +9
 38         };
 39
 40 static void xtoa(unsigned long x, const unsigned long *dp) {
 41     char c;
 42     unsigned long d;
 43     if (x) {
 44         while (x < *dp)
 45             ++dp;
 46         do {
 47             d = *dp++;
 48             c = '0';
 49             while (x >= d)
 50                 ++c, x -= d;
 51             putc(c);
 52         } while (!(d & 1));
 53     } else
 54         putc('0');
 55 }
 56
 57 static void puth(unsigned n) {
 58     static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
 59             '9', 'A', 'B', 'C', 'D', 'E', 'F' };
 60     putc(hex[n & 15]);
 61 }
 62
 63 void printf(char *format, ...)
 64 {
 65     char c;
 66     int i;
 67     long n;
 68
 69     va_list a;
 70     va_start(a, format);
 71     while(c = *format++) {
 72         if(c == '%') {
 73             switch(c = *format++) {
 74                 case 's': // String
 75                     puts(va_arg(a, char*));
 76                     break;
 77                 case 'c':// Char
 78                     putc(va_arg(a, char));
 79                 break;
 80                 case 'i':// 16 bit Integer
 81                 case 'u':// 16 bit Unsigned
 82                     i = va_arg(a, int);
 83                     if(c == 'i' && i < 0) i = -i, putc('-');
 84                     xtoa((unsigned)i, dv + 5);
 85                 break;
 86                 case 'l':// 32 bit Long
 87                 case 'n':// 32 bit uNsigned loNg
 88                     n = va_arg(a, long);
 89                     if(c == 'l' && n < 0) n = -n, putc('-');
 90                     xtoa((unsigned long)n, dv);
 91                 break;
 92                 case 'x':// 16 bit heXadecimal
 93                     i = va_arg(a, int);
 94                     puth(i >> 12);
 95                     puth(i >> 8);
 96                     puth(i >> 4);
 97                     puth(i);
 98                 break;
 99                 case 0: return;
100                 default: goto bad_fmt;
101             }
102         } else
103             bad_fmt: putc(c);
104     }
105     va_end(a);
106 }
107
108 /******************************************************************************
109  *                        MSP430G2553 printf() Tests
110  *
111  * Description: A modified version of the test code for testing oPossum's
112  *              tiny printf() function. More information on the printf()
113  *              function can be found at the following link.
114  *
115  *              http://www.43oh.com/forum/viewtopic.php?f=10&t=1732
116  *
117  *              This specific code tests the printf() function using
118  *              the hardware UART on the MSP430G2553 with a baud rate
119  *              of 9600. Once the character 't' is received, the test
120  *              sequence is started.
121  *
122  *              This code was originally created for "NJC's MSP430
123  *              LaunchPad Blog".
124  *
125  * Author:  Nicholas J. Conn - http://msp430launchpad.com
126  * Email:   webmaster at msp430launchpad.com
127  * Date:    06-07-12
128  ******************************************************************************/
129
130 void sendByte(unsigned char);
131
132 /**
133  * puts() is used by printf() to display or send a string.. This function
134  *     determines where printf prints to. For this case it sends a string
135  *     out over UART, another option could be to display the string on an
136  *     LCD display.
137  **/
138 void puts(char *s) {
139     char c;
140
141     // Loops through each character in string 's'
142     while (c = *s++) {
143         sendByte(c);
144     }
145 }
146 /**
147  * puts() is used by printf() to display or send a character. This function
148  *     determines where printf prints to. For this case it sends a character
149  *     out over UART.
150  **/
151 void putc(unsigned b) {
152     sendByte(b);
153 }
154
155 /**
156  * Sends a single byte out through UART
157  **/

View Code

五、测试结果

串口工具推荐使用Realterm,选择MSP430 Launchpad对应的串口号,串口波特率设为9600、8-N-1。电路连接好后,按下S2键开始测量,测量完成后,在Realterm上可以显示测量结果。板上的红、绿LED灯显示了工作状态,绿灯表示空闲(测量结束),红灯表示正在测量。试测了一个标称47uF的电容,结果如下图所示。

转载于:https://www.cnblogs.com/zlbg/p/4841939.html

MSP430 G2553 Launchpad实现电容测量相关推荐

  1. 基于STM32的电阻、电容测量(NE555芯片RC振荡法)

    文章目录 前言 一.电路图 1.电阻测量公式 2.电容测量公式 二.代码实现 1.外部中断代码 2.定时器中断处理数据 总结 前言 做的一个关于电阻和电容的测量电路,都是比较通用的.经过实际测试,电容 ...

  2. 单芯片电容测量方案PCAP01原理

    1 前言 对于电容传感器的测量来说,传统的电路方式有其无法克服的局限性.复杂的模拟电路设计,难以扩展的电容测量范围,都会给开发带来非常大的阻力. 德国acam公司专利的PICOCAP?测量原理则给电容 ...

  3. 电感电容电解电容测量仪

    '**************************************************** '* 电感电容电解电容测量仪 * '* 电容:1P-2.5uF * '* 电感:1uH-2. ...

  4. 电容测量仪-(模电、数电电子课程设计,毕业设计)Multisim仿真图以及实物设计(亲测好用)

    声明 本文仅在CSDN发布,其他均为盗版.请支持正版! 正版链接:https://blog.csdn.net/meenr/article/details/117549977 最简单电路实现两个量程档位 ...

  5. LM741构成的电容测量电路设计

    LM741构成的电容测量电路设计 由LM741等构成的电容测量电路如下图所示,该电路的测量原理是被测电容Cx充.放电而形成三角波,测量三角波的振荡周期就可知电容量的大小.由A1可构成密勒积分电路,经A ...

  6. 使用电容测量夹的一个小错误

    目录 简易的电容测量,可以使用夹式的电容测量器,如图1所示: 图1:正确使用方法 图1是正确的使用方法,手指应该在夹子的塑料部分,而不应该在金属上,否则会产生错误的测量结果.图2就是这样的错误使用方式 ...

  7. MSP430 G2553 硬件SPI OLED 单片机 0.96英寸7针OLED SPI 6针OLED

    SSD1306通信方式靠硬件选择: 四线SPI(只针对SSD1306的一个名字)的OLED款式1 D0时钟 D1数据 RST复位 DC数据命令选择 四线SPI(只针对SSD1306的一个名字)的OLE ...

  8. MSP430 G2553 硬件IIC OLED 单片机 OLED滚动显示

    效果: 总结: (1)网上没好用的源码: (2)SSD1306地址是0X3C,7位地址模式. (3)G2553手册确实介绍得很好. (4)SSD1306写入命令顺序:开始信号–>等待UCB0TX ...

  9. MSP430嵌入式接口编程(惯性测量单元温湿度双音多频磁力计LCD显示等)

    Energia IDE编程MSP430 GPIO 串口通讯 定时中断 添加库 嵌入式器件接口编程 加速度计 #include <math.h>void loop() {int x_adc_ ...

  10. MSP430 G2553 单片机 口袋板 日历 时钟 闹钟 万年历 电子时钟 秒表显示

    一.实验目的本次实验使用 MSp430G2553 以及 GZ 扩展版的 LCO 显示.蜂鸣器.机械按键,实现具有多功能电子钟的设计.功能包括,按键切换工作界面.设置时间.秒表计时.闹钟的设定.闹钟的暂 ...

最新文章

  1. python合并两个有序列表_合并两个有序链表(Python3)
  2. 检测输入路径是否存在错误_为什么存在用户输入错误
  3. 测试sql语句的执行效率
  4. LCFinder 0.3.0 Beta 发布,图像标注与目标检测工具
  5. lisp编程 滑动轴承的auto_基于Visual Lisp的滑动轴承设计
  6. opencv 图像几何变换
  7. 智慧城市发展路径中 中国特色是主色调
  8. ubuntu postgresql9.5 源码安装
  9. python3高性能网络编程_Python高级网络编程系列之基础篇
  10. 计算机桌面无法新建文件夹,Win7桌面不能新建文件夹和修改文件名怎么办?
  11. ndwi是什么意思_NDWI是什么意思
  12. coding AD:最短路径Floyd算法过程矩阵的计算:十字交叉法
  13. web音视频播放器(html5)方案总结
  14. ubuntu18 防火墙关闭_ubuntu18开启/关闭防火墙
  15. 假如让我来设计“腾讯视频”的推荐系统
  16. Linux下useradd与adduser的区别
  17. Cloud Foundry 峰会进入中国 全球专家与你面对面
  18. Vue 和 React 的区别
  19. LockSupport 以及 park、unpark 方法
  20. 0FFICE2007 EXCEL跨工作簿引用的缺点

热门文章

  1. DxDiag中字段结构
  2. 第三届中国CEO新年峰会参会感想二
  3. C语言制作扫雷游戏(结合图形库)
  4. java开发微信抢红包挂_java实现微信抢红包算法
  5. macbook卡在进度条开不了机_Mac 开机停在进度条解决方法
  6. 5月18日第壹简报,星期三,农历四月十八
  7. 用友系统中连接数据库服务器失败,用友u8服务器连接不到本地数据库
  8. 前端学习日志之复刻百度新闻女人专栏
  9. 获取Unique reads方法
  10. cin/cou效率太慢?试一下 ios::sync_with_stdio(false);