MSP430 G2553 Launchpad implements capacitance measurement
[Copy link]
1. Basic principles
For the Source-Free RC circuit, the characteristics of its capacitor discharge can be described as:
Where V0 is the initial voltage of the capacitor, t is the discharge time, R is the resistance of the series resistor, C is the capacitance, and v(t) is the voltage on the capacitor at time t. Therefore, if V0, R, and the voltage Vt1 at time t1 are known, C can be calculated:
2. How to control and measure
As shown in the figure above, the general steps are: 1) GPIO charges capacitor C to Vcc through resistor R; 2) The GPIO outputs 0, capacitor C discharges through R, and the timer starts timing and CA+ is turned on; 3) When the capacitor voltage is discharged to the reference voltage (here is 0.25Vcc), the level of the comparator CA+ output terminal changes; 4) The interrupt program captures this change, and uses the capture mode of the timer to obtain the time at that moment, and finally calculates the capacitor value through the above equation.
In the above figure, it is recommended to use a 1% precision resistor for R to improve the test accuracy.
3. State Transition Diagram
Fourth, test code
main.c program:
复制代码
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 program: To output the capacitance results to the PC via UART, the following program implements the printf() function. The code comes from NJC's MSP430 LaunchPad Blog and oPossum's code.
View Code
V. Test Results
Realterm is recommended as the serial port tool. Select the serial port number corresponding to the MSP430 Launchpad and set the serial port baud rate to 9600, 8-N-1. After the circuit is connected, press the S2 key to start the measurement. After the measurement is completed, the measurement results can be displayed on Realterm. The red and green LED lights on the board show the working status. The green light indicates idle (measurement is completed) and the red light indicates that the measurement is in progress. A nominal 47uF capacitor was tested, and the results are shown in the figure below.
|