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程序:
// C meter 2015.9.26
//
// P1.5(TA0.0) --[||||]----------- P1.4(CA3)
// R=10kOhm |
// -----
// cap -----
// |
// GND
// http://zlbg.cnblogs.com
///////////////////////////////////////// #include "io430.h" #define LED1 BIT0 // P1.0, red led
#define LED2 BIT6 // P1.6, green led #define VMEAS BIT4 // P1.4(CA4) for voltage measurement of the cap
#define VCTRL BIT5 // P1.5(TA0.0) for voltage control
#define PUSH2 BIT3 // P1.3, button #define RXD BIT1 //P1.1
#define TXD BIT2 //P1.2 #define READY 0
#define CHARGING 1
#define DISCHARGING 2
#define FINISH_DC 3 #define R_SERIES 10000 //10kOhm
#define LN4 1.3863 //functions for C meter
void P1Init(void);
void TA0Init(void);
void CAInit(void);
37 void setReadyStatus(void); //functions for printf()
void sendByte(unsigned char);
void printf(char *, ...);
void initUART(void); char state = READY;
unsigned char overflowsCharging = ;
unsigned char overflowsDischarging = ;
unsigned char i = ;
float capacitance = ; // unit: nF void main(void)
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD; // DCO setup
BCSCTL1 = CALBC1_1MHZ; //running at 1Mhz
DCOCTL = CALDCO_1MHZ; // P1 setup
P1Init(); // Timer0 setup
TA0Init(); // CA setup
CAInit(); // UART setup
initUART(); setReadyStatus(); __enable_interrupt(); // enter LP mode
LPM0; } void P1Init(void)
{
P1OUT = ; // set P1.3 (PUSH2) as input with pullup
P1OUT |= PUSH2;
P1REN |= PUSH2; // set P1.0, P1.6, P1.5 as output
P1DIR |= LED1 + LED2 + VCTRL; // enable P1.3 interrupt
P1IES |= PUSH2; // high -> low transition
P1IFG &= ~PUSH2; // clear the flag
P1IE |= PUSH2;
} void TA0Init(void)
{
// use SMCLK (1MHz), no div, clear, halt
TA0CTL = TASSEL_2 + ID_0 + MC_0 + TACLR; // TA0CCTL0: compare mode, enable interrupt
TA0CCTL0 = CCIE; // TA0CCTL1: capture mode, no capture, CCI1B(CAOUT) input, syn capture
// interrupt enabled
TA0CCTL1 = CCIS_1 + SCS + CAP + CCIE;
} void CAInit(void)
{
//0.25 Vcc ref on V+, halt
CACTL1 = CAREF_1 + CAIES;
// input CA4 (P1.4), remove the jumper) on V-, filter on
CACTL2 = P2CA3 + CAF;
} void setReadyStatus(void)
{
state = READY;
// light led2 and turn off led1 to indicate ready
P1OUT &= ~LED1;
P1OUT |= LED2; //stop and clear timer, stop T0_A1 capture & CA+
TA0CTL = TASSEL_2 + ID_0 + MC_0 + TACLR;
TA0CCTL1 &= ~CM_3;
CACTL1 &= ~CAON; overflowsCharging = ;
} void initUART(void) {
//config P1.1 RXD, P1.2 TXD
P1SEL |= TXD + RXD;
P1SEL2 |= TXD + RXD; //reset UCA0, to be configured
UCA0CTL1 = UCSWRST;
//config
UCA0CTL1 |= UCSSEL_2; //SMCLK
UCA0BR0 = ;
UCA0BR1 = ;//1MHz baut rate = 9600 8-N-1
UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1
//make UCA0 out of reset
UCA0CTL1 &= ~UCSWRST;
} void sendByte(unsigned char byte )
{
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = byte; // TX -> RXed character
} #pragma vector = PORT1_VECTOR
__interrupt void P1_ISR(void)
{
if((P1IFG & PUSH2) == PUSH2)
{
P1IFG &= ~PUSH2; //clear the flag
switch(state)
{
case READY:
state = CHARGING;
// light LED1 and turn off LED2, indicate a busy status
P1OUT |= LED1;
P1OUT &= ~LED2;
//start timer, continuous mode
TACTL |= MC_2;
//start charging
P1OUT |= VCTRL;
break;
default:
break;
} }
else
{
P1IFG = ;
}
} #pragma vector = TIMER0_A0_VECTOR
__interrupt void CCR0_ISR(void)
{
switch(state)
{
case CHARGING:
if (++overflowsCharging == ) // wait 6.5535*50 = 3.28s
{
state = DISCHARGING;
CACTL1 |= CAON; // turn on CA+
TA0CCTL1 |= CM_1; // start TA1 capture on rising edge
P1OUT &= ~VCTRL; // start discharging
overflowsDischarging = ;
}
break;
case DISCHARGING:
overflowsDischarging++;
default:
break; } } #pragma vector = TIMER0_A1_VECTOR
__interrupt void CCR1_ISR(void)
{
TA0CTL &= ~MC_3; //stop timer
TA0CCTL1 &= ~CCIFG; // clear flag
switch(state)
{
case DISCHARGING:
state = FINISH_DC;
capacitance = (overflowsDischarging* + TA0CCR1)* / (R_SERIES*LN4); //nF
//send result to PC
printf("Capatitance: %n", (long unsigned)capacitance);
printf(" nF\r\n"); setReadyStatus();
break;
default:
break;
}
}
printf.c程序:为将电容结果通过UART输出至PC显示,以下这段程序实现了printf()函数,代码来自于NJC's MSP430 LaunchPad Blog博客和oPossum的代码。
/******************************************************************************
* Reusable MSP430 printf()
*
* Description: This printf function was written by oPossum and originally
* posted on the 43oh.com forums. For more information on this
* code, please see the link below.
*
* http://www.43oh.com/forum/viewtopic.php?f=10&t=1732
*
* A big thanks to oPossum for sharing such great code!
*
* Author: oPossum
* Source: http://www.43oh.com/forum/viewtopic.php?f=10&t=1732
* Date: 10-17-11
*
* Note: This comment section was written by Nicholas J. Conn on 06-07-2012
* for use on NJC's MSP430 LaunchPad Blog.
******************************************************************************/ #include "stdarg.h" void putc(unsigned);
void puts(char *); static const unsigned long dv[] = {
// 4294967296 // 32 bit unsigned max
,// +0
, // +1
, // +2
, // +3
, // +4
// 65535 // 16 bit unsigned max
, // +5
, // +6
, // +7
, // +8
, // +9
}; static void xtoa(unsigned long x, const unsigned long *dp) {
char c;
unsigned long d;
if (x) {
while (x < *dp)
++dp;
do {
d = *dp++;
c = '';
while (x >= d)
++c, x -= d;
putc(c);
} while (!(d & ));
} else
putc('');
} static void puth(unsigned n) {
static const char hex[] = { '', '', '', '', '', '', '', '', '',
'', 'A', 'B', 'C', 'D', 'E', 'F' };
putc(hex[n & ]);
} void printf(char *format, ...)
{
char c;
int i;
long n; va_list a;
va_start(a, format);
while(c = *format++) {
if(c == '%') {
switch(c = *format++) {
case 's': // String
puts(va_arg(a, char*));
break;
case 'c':// Char
putc(va_arg(a, char));
break;
case 'i':// 16 bit Integer
case 'u':// 16 bit Unsigned
i = va_arg(a, int);
if(c == 'i' && i < ) i = -i, putc('-');
xtoa((unsigned)i, dv + );
break;
case 'l':// 32 bit Long
case 'n':// 32 bit uNsigned loNg
n = va_arg(a, long);
if(c == 'l' && n < ) n = -n, putc('-');
xtoa((unsigned long)n, dv);
break;
case 'x':// 16 bit heXadecimal
i = va_arg(a, int);
puth(i >> );
puth(i >> );
puth(i >> );
puth(i);
break;
case : return;
default: goto bad_fmt;
}
} else
bad_fmt: putc(c);
}
va_end(a);
} /******************************************************************************
* MSP430G2553 printf() Tests
*
* Description: A modified version of the test code for testing oPossum's
* tiny printf() function. More information on the printf()
* function can be found at the following link.
*
* http://www.43oh.com/forum/viewtopic.php?f=10&t=1732
*
* This specific code tests the printf() function using
* the hardware UART on the MSP430G2553 with a baud rate
* of 9600. Once the character 't' is received, the test
* sequence is started.
*
* This code was originally created for "NJC's MSP430
* LaunchPad Blog".
*
* Author: Nicholas J. Conn - http://msp430launchpad.com
* Email: webmaster at msp430launchpad.com
* Date: 06-07-12
******************************************************************************/ void sendByte(unsigned char); /**
* puts() is used by printf() to display or send a string.. This function
* determines where printf prints to. For this case it sends a string
* out over UART, another option could be to display the string on an
* LCD display.
**/
void puts(char *s) {
char c; // Loops through each character in string 's'
while (c = *s++) {
sendByte(c);
}
}
/**
* puts() is used by printf() to display or send a character. This function
* determines where printf prints to. For this case it sends a character
* out over UART.
**/
void putc(unsigned b) {
sendByte(b);
} /**
* Sends a single byte out through UART
**/
五、测试结果
串口工具推荐使用Realterm,选择MSP430 Launchpad对应的串口号,串口波特率设为9600、8-N-1。电路连接好后,按下S2键开始测量,测量完成后,在Realterm上可以显示测量结果。板上的红、绿LED灯显示了工作状态,绿灯表示空闲(测量结束),红灯表示正在测量。试测了一个标称47uF的电容,结果如下图所示。
MSP430 G2553 Launchpad实现电容测量的更多相关文章
- MSP430 G2553 LaunchPad GPIO中断
P1.P2端口上的每个管脚都支持外部中断.P1端口的所有管脚都对应同一个中断向量(Interrupt Vector),类似的,P2端口的所有管脚都对应另一个中断向量:通过PxIFG寄存器来判断中断来源 ...
- MSP430 G2553 LaunchPad设置GPIO
一. 背景知识:逻辑运算符的使用 当程序初始化时,对于复位状态有不确定性的寄存器(如PxOUT),建议采用直接赋值:其他情况下最好使用逻辑运算符修改寄存器. 直接赋值 REGISTER = 0b111 ...
- MSP430 G2553 计时/计数器 Timer_A
MSP430G2553包含了两个16-bit Timer_A计时/计数器.本文简单介绍了Timer_A的功能和寄存器使用,本文及后续的随笔部分参考了"Scientific Instrumen ...
- MSP430 G2553 低功耗模式LPMx
MSP430除了正常运行时的active模式外,还支持五种低功耗模式(Low-power mode),分别为LPM0.LPM1.LPM2.LPM3.LPM4,由状态寄存器中的CPUOFF.OSCOFF ...
- MSP430 G2553 基本时钟模块+ (Basic Clock Module+)
一.时钟源 MSP430的Basic Clock Module+支持的时钟源有: DCOCLK:内部数字控制振荡器,Internal digitally contrlled oscillator.所有 ...
- MSP430 G2553 比较器Comparator_A+、数据流程图DFD、状态转换图STD
一.CA+构造 MSP430G2553带有一个比较器Comparator_A+(CA+),其构造框图如下图所示. 二.输入 & 输出 如上图所示,比较器有一个同向输入端(V+)和一个反向输入端 ...
- MSP430 G2553 Timer 中断总结
目前总共用到了四个中断向量,我觉得已经把G2553的所有定时器中断都用到了. 定时器有两个,TA0与TA1,每个定时器又有两个中断向量 1,CCR0到达时的中断,在计数模式时候很有用,平时定时器的基本 ...
- MSP430 G2553 寄存器列表与引脚功能
USCI_B0 USCI_B0 发送缓冲器UCB0TXBUF 06Fh USCI_B0 接收缓冲器UCB0RXBUF 06Eh USCI_B0 状态UCB0STAT 06Dh USCI B0 I2C ...
- 用Gen4消除电容触摸屏设计屏障【转】
转自:http://www.cntronics.com/sensor-art/80015498?page=2 中心议题: 电容式触摸屏设计到产品的各种挑战 解决方案: 用Gen4消除电容触摸屏设计屏障 ...
随机推荐
- [转]命令行在IIS添加虚拟目录
来自:http://www.jb51.net/softjc/29702.htmlMkwebdir -c LocalHost -w "Default Web Site" –v Com ...
- 集群(heartbeat)搭建
HA 即(high available cluster)高可用集群,又称双机热备,保证关键性业务的不间断提供服务. 如:两台机器A和B,正常情况A提供服务,B待命闲置:一但A宕机或服务宕掉,自动切换至 ...
- 【UVA】10635 Prince and Princess(LCS)
题目 传送门:QWQ 分析 水题.$ O(nlogn) $的LCS 代码 #include <bits/stdc++.h> using namespace std; *, INF=1e9; ...
- Java内存分配及值、引用的传递
关于堆栈的内容网上已经有很多资料了,这是我找的加上自己理解的一篇说明文: 一.内存区域类型 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制: 2. 栈:存放基本类型的变量数 ...
- Axure 原型图 (转)
Axure RP是很有名的一个界面原型设计工具,可以灵活快捷的对C/S.B/S程序设计原型. 近期我要开发一个Android客户端,也打算使用Axure RP设计原型. 下载地址:http://pan ...
- Python_01-入门基础
以后我会发表一系列python脚本的学习资料,python版本为2.x. 目录: 1 Python入门基础 1.1 学习资源 1.2 所有语言的入门程序---Hello World! 1.3 帮助函 ...
- CVE-2017-7494:Linux Samba named pipe漏洞
描述: 漏洞是由于代码中一个管道申请命令的判断导致的,可以通过构造特定请求执行上传的so文件. 漏洞影响了Samba 3.5.0 之后到4.6.4/4.5.10/4.4.14中间的所有版本. 测试: ...
- [udemy]WebDevelopment_CSS
Your First CSS(Cascading Style Sheets) Cascading means it always takes selector that is at the end 即 ...
- 3-java_string学习笔记:
java中String的常用方法
- Java文件下载详解
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException ...