MSP430 G2553 Launchpad实现电容测量
一、基本原理
对于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的代码。
![](/assets/blank.gif)
![](/assets/blank.gif)
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实现电容测量相关推荐
- 基于STM32的电阻、电容测量(NE555芯片RC振荡法)
文章目录 前言 一.电路图 1.电阻测量公式 2.电容测量公式 二.代码实现 1.外部中断代码 2.定时器中断处理数据 总结 前言 做的一个关于电阻和电容的测量电路,都是比较通用的.经过实际测试,电容 ...
- 单芯片电容测量方案PCAP01原理
1 前言 对于电容传感器的测量来说,传统的电路方式有其无法克服的局限性.复杂的模拟电路设计,难以扩展的电容测量范围,都会给开发带来非常大的阻力. 德国acam公司专利的PICOCAP?测量原理则给电容 ...
- 电感电容电解电容测量仪
'**************************************************** '* 电感电容电解电容测量仪 * '* 电容:1P-2.5uF * '* 电感:1uH-2. ...
- 电容测量仪-(模电、数电电子课程设计,毕业设计)Multisim仿真图以及实物设计(亲测好用)
声明 本文仅在CSDN发布,其他均为盗版.请支持正版! 正版链接:https://blog.csdn.net/meenr/article/details/117549977 最简单电路实现两个量程档位 ...
- LM741构成的电容测量电路设计
LM741构成的电容测量电路设计 由LM741等构成的电容测量电路如下图所示,该电路的测量原理是被测电容Cx充.放电而形成三角波,测量三角波的振荡周期就可知电容量的大小.由A1可构成密勒积分电路,经A ...
- 使用电容测量夹的一个小错误
目录 简易的电容测量,可以使用夹式的电容测量器,如图1所示: 图1:正确使用方法 图1是正确的使用方法,手指应该在夹子的塑料部分,而不应该在金属上,否则会产生错误的测量结果.图2就是这样的错误使用方式 ...
- MSP430 G2553 硬件SPI OLED 单片机 0.96英寸7针OLED SPI 6针OLED
SSD1306通信方式靠硬件选择: 四线SPI(只针对SSD1306的一个名字)的OLED款式1 D0时钟 D1数据 RST复位 DC数据命令选择 四线SPI(只针对SSD1306的一个名字)的OLE ...
- MSP430 G2553 硬件IIC OLED 单片机 OLED滚动显示
效果: 总结: (1)网上没好用的源码: (2)SSD1306地址是0X3C,7位地址模式. (3)G2553手册确实介绍得很好. (4)SSD1306写入命令顺序:开始信号–>等待UCB0TX ...
- MSP430嵌入式接口编程(惯性测量单元温湿度双音多频磁力计LCD显示等)
Energia IDE编程MSP430 GPIO 串口通讯 定时中断 添加库 嵌入式器件接口编程 加速度计 #include <math.h>void loop() {int x_adc_ ...
- MSP430 G2553 单片机 口袋板 日历 时钟 闹钟 万年历 电子时钟 秒表显示
一.实验目的本次实验使用 MSp430G2553 以及 GZ 扩展版的 LCO 显示.蜂鸣器.机械按键,实现具有多功能电子钟的设计.功能包括,按键切换工作界面.设置时间.秒表计时.闹钟的设定.闹钟的暂 ...
最新文章
- python合并两个有序列表_合并两个有序链表(Python3)
- 检测输入路径是否存在错误_为什么存在用户输入错误
- 测试sql语句的执行效率
- LCFinder 0.3.0 Beta 发布,图像标注与目标检测工具
- lisp编程 滑动轴承的auto_基于Visual Lisp的滑动轴承设计
- opencv 图像几何变换
- 智慧城市发展路径中 中国特色是主色调
- ubuntu postgresql9.5 源码安装
- python3高性能网络编程_Python高级网络编程系列之基础篇
- 计算机桌面无法新建文件夹,Win7桌面不能新建文件夹和修改文件名怎么办?
- ndwi是什么意思_NDWI是什么意思
- coding AD:最短路径Floyd算法过程矩阵的计算:十字交叉法
- web音视频播放器(html5)方案总结
- ubuntu18 防火墙关闭_ubuntu18开启/关闭防火墙
- 假如让我来设计“腾讯视频”的推荐系统
- Linux下useradd与adduser的区别
- Cloud Foundry 峰会进入中国 全球专家与你面对面
- Vue 和 React 的区别
- LockSupport 以及 park、unpark 方法
- 0FFICE2007 EXCEL跨工作簿引用的缺点
热门文章
- DxDiag中字段结构
- 第三届中国CEO新年峰会参会感想二
- C语言制作扫雷游戏(结合图形库)
- java开发微信抢红包挂_java实现微信抢红包算法
- macbook卡在进度条开不了机_Mac 开机停在进度条解决方法
- 5月18日第壹简报,星期三,农历四月十八
- 用友系统中连接数据库服务器失败,用友u8服务器连接不到本地数据库
- 前端学习日志之复刻百度新闻女人专栏
- 获取Unique reads方法
- cin/cou效率太慢?试一下 ios::sync_with_stdio(false);