历史上的今天
今天是:2024年12月30日(星期一)
2021年12月30日 | MSP430 G2553 Launchpad实现电容测量
2021-12-30 来源:eefocus
一、基本原理

对于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(" nFrn");
223
224 setReadyStatus();
225 break;
226 default:
227 break;
228 }
229 }
printf.c程序:为将电容结果通过UART输出至PC显示,以下这段程序实现了printf()函数,代码来自于NJC's MSP430 LaunchPad Blog博客和oPossum的代码。
史海拾趣
|
今天出场的这款鼠标键盘虽然外表朴实,却也不会让人小觑。这款鼠标键盘将标准键盘切分成两半,其中右边键盘被设计成一个大型鼠标。 当你移动这个大型鼠标的时候,它会自动从键盘模式进入鼠标模式,屏幕上的光标也会随之移动。与此同时,这半边键盘 ...… 查看全部问答> |
|
作为一种新的光源,近年来各大公司和研究机构对LED电源和驱动电路的研究方兴未艾。与荧光灯的电子镇流器不同,LED驱动电路的主要功能是将交流电压转换为直流电压,并同时完成与LED的电压和电流的匹配。随着硅集成电路电源电压的直线下降,LED工作电 ...… 查看全部问答> |
|
我最近做激光器的驱动电路,有一个自动功率控制电路这里有一些问题不明白,PD是提供了电流,可是PD的电流方向是向下的,A1运放“+”输入端电流又进不去,那这个方向的电流到底流到哪里呀,这里“+”端又没有接地,电流走不通呀,小弟不明白呀,请各 ...… 查看全部问答> |
|
分享我收集的嵌入式wince/android/linux著名网站和博客地址 3001、android 著名博客 http://blog.csdn.net/Luoshengyang/ ——老罗的android 之旅,一个android大牛人的博客,文章高深莫测,只有少数前期文章适合初学者。 http://blog.csdn.net/mr_raptor ——华清远见一个老师的博客,适合android入门初学 ...… 查看全部问答> |
|
MSP430F169 P54 输出1之后自动清零是怎么回事? 现在用P54.其片内功能是MCLK的输出,现在设置其为输出,选择为IO功能,可是在置一之后会自动清零。(P5DIR|=BIT4;P5SEL&=~BIT4,P5OUT|=BIT4;)??why?… 查看全部问答> |




