一、基本原理
对于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的代码。
上一篇:MSP430G2553 Launchpad 硬件I2C驱动
下一篇:MSP430 G2553 比较器Comparator_A+、数据流程图DFD、状态转换图STD
推荐阅读




推荐帖子
- 上位机软件类编写心得
- 开发上位机软件的语言有很多,为何偏偏选中了.NET呢,主要是因为这个语言开发上位机软件相当方面而且微软提供了大量的类库和API。虽然底层实现代码不像JAVA一样可以开源的,但是这个不影响这门语言的推广,试问有几个人会真正意义上去研究底层的代码呢?再说我们是搞工程的,在保证质量的前提下追求的是速度。而且。NET开发图形界面是相当方便的,不像JAVA一样代码都要自己一笔一笔的写蛮麻烦。对于,NET开发上位机软件,我们应该做到什么程度才算用的比较熟练了呢?我觉得应该是自己会创建类,其实,NET最重要的
-
wateras1
DIY/开源硬件专区
- 细数T-BOX中TI的明星产品之车载以太网 | 第一节 DP83TC811S-Q1:车载以太网让您的T...
- 第一节DP83TC811S-Q1:车载以太网让您的T-BOX如虎添翼近年来“车联网”概念的热度一直都居高不下。说起车联网,当然就不得不提车载以太网以及车联网的核心组成部分之一---T-BOX!本文将会从车载以太网100BASE-T1说起,深入剖析车载以太网特点,并且详细介绍TI的明星产品DP83TC811S-Q1的优点以及在T-BOX的应用中的优势所在。什么是车载以太网?---从100BASE-T1说起以太网早已被广泛应用于商业和工业,但直到100BASE-T1
-
alan000345
TI技术论坛
- JTAG在线调试映射问题
- 这两天用JTAG调试时发现奇怪的问题:每次发生中断时就跑飞,在网上搜了一下,原来是发生中断时没有找到中断向量表。我用反汇编单步调试,中断发生时,PC并没有跳到0x30000000处的中断向量表处(我已经在ADS把ROBase设置成0x30000000,也在IRQ中断设置了断点)就直接跑飞了。于是我把程序下载到NANDFlash(程序正常运行,中断没问题),在这情况下我再次使用JTAG在线调试,这下子中断不再跑飞了。于是我可以确定,JTAG在线调试发生中断时PC是跳到0x0开始的中断向量表。
-
good969
嵌入式系统
- LPC2478驱动nand flash(k9f5608)
- 本帖最后由宇外星空于2017-4-114:30编辑 本文首发在CSDN,但是因为个人觉得CSDN可能更偏向于纯软件开发,而电子工程世界更适合和工程师们交流;所以决定还是将博客的主要发布改到这儿,初次见面,大家好~~关于LPC2478的操控系列是依据本人在工作项目中的经验而编写,会一步步分享给大家我的开发之路,有可能的话考虑出本小书将工程项目总结提炼一下作为LPC2478的实践工程入门读物吧(希望梦想能实现),所以有何建议和问题大家尽管提。先从控制nandflash开始写起,因为工
-
宇外星空
NXP MCU
- 用C#做过智能设备应用程序时怎么没有monthCalendar和dateTimePicker,这样的日期控件?
- 用C#做过智能设备应用程序时怎么没有monthCalendar和dateTimePicker,这样的日期控件? 工具箱里怎么没有?怎么加入??用C#做过智能设备应用程序时怎么没有monthCalendar和dateTimePicker,这样的日期控件?
-
senorspring
嵌入式系统
- pic求教
- 请问pic能做飞控吗?pic求教
-
yyyyyx
Microchip MCU