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消除电容触摸屏设计屏障 ...
随机推荐
- HDU 2201 熊猫阿波的故事
熊猫阿波的故事 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- Bootstrap-CSS
ylbtech-Bootstrap-Plugin: 1.返回顶部 1. 2. 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 1. 2. 11.返回顶部 作者:yl ...
- 通过BeanFactoryPostProcessor来获取bean
一.现在我们很多时候都在spring的容器中,进行bean的提取和操作,但是配置里面首先需要扫描相应的包来实现相关bean的注入 但是问题来了.如果我们在另外一个线程需要用的时候,并且没有配置扫描该类 ...
- [Python] numpy.sum
import numpy as np #Syntax: numpy.sum(a, axis=None, dtype=None, out=None, keepdims=<class numpy._ ...
- 接口自动化(三)--读取json文件中的数据
上篇讲到实际的请求数据放置在json文件内,这一部分记述一下python读取json文件的实现. 代码如下(代码做了简化,根据需要调优:可做一些容错处理): 1 import json 2 3 cla ...
- jenkins显示html样式问题的几种解决方案总结
前言 jenkins上使用HTML Publisher plugin插件生成的html报告样式会丢失,需要设置下才能正常显示. 一.样式丢失 1.官方文档的解释如下,参考地址https://stack ...
- leetcode14
public class Solution { public string LongestCommonPrefix(string[] strs) { ) { return ""; ...
- Date 当前程序日期格式 参数设置 DecimalSeparator
日期格式.货币格式等 Date DateFormat DecimalSeparator FormatSettings FormatSettings.DateSeparator='-'; 控制面板的日期 ...
- //todo 的用处
在代码中添加 //todo 以后要做的事 可以暂时打上标记,以后再来处理. 光有这个没什么用,关键是IDE要支持,比如VS2017,只要按下 ctrl+w,t 就可以在输出窗口中显示出所有 todo的 ...
- Android gralloc 模块实例
本文实例为借鉴 http://www.ixueyi.com/jingyan/1865079.html 该文档后所写.主要是android的gralloc操作显存的模块实例,如有不正确的地方欢迎指出谢谢 ...