2166 views|2 replies

2015

Posts

0

Resources
The OP
 

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 is discharged 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 changes at the comparator CA+ output; 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:

Copy code
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 }
Copy code
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.


Copy code
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 **/
Copy code
five , Test results
The recommended serial port tool is Realterm, 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. The red and green LED lights on the board show the working status. The green light indicates idle (measurement completed), and the red light indicates measurement in progress. A nominal 47uF capacitor was tested, and the results are shown in the figure below.

This post is from Microcontroller MCU

Latest reply

Good,   Details Published on 2020-6-10 16:54
 

79

Posts

723

Resources
2
 

It's really good

This post is from Microcontroller MCU
 
 

2618

Posts

0

Resources
3
 

Good,

This post is from Microcontroller MCU
 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list