[资料分享] MSP430 G2553 Launchpad实现电容测量

灞波儿奔   2017-9-16 18:52 楼主
一、基本原理
360截图20170916184948296.jpg
对于Source-Free RC电路,其电容放电的特性可以描述为:
360截图20170916184952054.jpg
其中V0是电容的初始电压,t是放电时间,R是串接的电阻阻值,C是电容值,v(t)是t时刻电容上的电压。因此,若已知V0、R、以及t1时刻的电压Vt1,便可求得C:
360截图20170916184955560.jpg
二、如何控制和测量
如上图所示,大致步骤为:1)由GPIO通过电阻R给电容C充电至Vcc;2)该GPIO输出0,电容C通过R进行放电,同时Timer开始计时、CA+开启;3)当电容电压放电至参考电压(此处是0.25Vcc)时,比较器CA+输出端出现电平变化;4)中断程序捕获这一变化,并利用Timer的capture mode获得该时刻的时间,最后通过以上方程计算电容值。
360截图20170916185000640.jpg
上图中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 //
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 }
复制代码



回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复