历史上的今天
返回首页

历史上的今天

今天是: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的代码。

推荐阅读

史海拾趣

Corsair Electrical Connectors Inc公司的发展小趣事

Corsair Electrical Connectors Inc公司自创立之初,便专注于电气连接器的制造。公司创始人凭借其深厚的行业经验和敏锐的市场洞察力,准确把握了连接器在电子行业中的重要地位,并决定以此为切入点,打造一家专业的连接器制造商。在创立初期,Corsair面临着资金短缺、技术落后等多重困难,但创始人凭借坚定的信念和不懈的努力,带领公司逐步走上了正轨。

Carlisle Interconnect Components公司的发展小趣事

为了进一步提升公司的竞争力和市场份额,Carlisle Interconnect Components公司积极寻求与产业链上下游企业的战略合作。通过与原材料供应商、设备制造商以及终端客户的紧密合作,公司实现了产业链的整合和优化。这种合作模式不仅降低了公司的生产成本和风险,更提高了产品的质量和交付速度,为公司赢得了更多的竞争优势。

启攀微电子(Chiphomer)公司的发展小趣事

启攀微电子(Chiphomer)公司成立于2003年,当时正值中国集成电路产业快速发展的初期。创始人张杨带领着一支由英美归国的留学精英和国内资深管理与技术人员组成的团队,立志要在这一领域闯出一片天地。然而,初创时期的资金短缺、技术壁垒和市场认可度低等问题,让公司面临着巨大的挑战。然而,他们凭借着对技术的执着追求和对市场的敏锐洞察,成功推出了首款SDH通信芯片,为公司的后续发展奠定了坚实的基础。

APM Hexseal公司的发展小趣事

随着公司的发展,APM Hexseal不断拓展其产品线,推出了包括断路器、密封开关、过滤器和密封件等一系列产品。这些产品都经过了严格的测试和认证,以确保其能够满足各种恶劣环境下的使用要求。其中,许多产品都获得了UL认证,进一步证明了其卓越的品质和可靠性。

Datapro International Inc公司的发展小趣事

随着技术的不断进步和市场的不断扩大,Datapro International Inc公司开始寻求新的市场机会。他们发现,随着企业信息化程度的提高,对数据存储和处理的需求也越来越大。于是,公司决定进军企业市场,并开发了一系列针对企业的数据存储解决方案。

在拓展企业市场的过程中,Datapro International Inc公司面临着来自竞争对手的激烈竞争。然而,他们凭借卓越的产品质量、专业的技术服务和灵活的商业模式,成功赢得了客户的信任和支持。随着企业市场的不断拓展,Datapro International Inc公司的业务规模也逐渐扩大。

FERYSTER公司的发展小趣事

随着市场的不断扩大,FERYSTER公司意识到产品质量对于企业的重要性。因此,公司投入大量资金用于提升质量管理体系,引入国际先进的生产设备和检测仪器。同时,公司还加强了员工的质量意识培训,确保每一个环节都符合质量标准。这些措施的实施,使得FERYSTER公司的产品质量得到了显著提升,赢得了客户的广泛赞誉。

问答坊 | AI 解惑

硬件工程师手册

华为内部硬件工程师手册,绝密!…

查看全部问答>

E题的方案

本帖最后由 paulhyde 于 2014-9-15 09:33 编辑 求助各位ggjj晒点淘汰的方案啊,写报告用的!!!!!!!!!!!!!! 凑字数啊  …

查看全部问答>

鼠标键盘?键盘鼠标? 超级创意二合一

今天出场的这款鼠标键盘虽然外表朴实,却也不会让人小觑。这款鼠标键盘将标准键盘切分成两半,其中右边键盘被设计成一个大型鼠标。 当你移动这个大型鼠标的时候,它会自动从键盘模式进入鼠标模式,屏幕上的光标也会随之移动。与此同时,这半边键盘 ...…

查看全部问答>

LED电源和驱动电路主要技术概况

作为一种新的光源,近年来各大公司和研究机构对LED电源和驱动电路的研究方兴未艾。与荧光灯的电子镇流器不同,LED驱动电路的主要功能是将交流电压转换为直流电压,并同时完成与LED的电压和电流的匹配。随着硅集成电路电源电压的直线下降,LED工作电 ...…

查看全部问答>

定时器a求助

各位兄弟 我写了一个简单的程序不能执行 在tt==20的地方,请教高手?谢谢 #include <msp430x14x.h> #define uint unsigned int #define uchar unsigned char uchar num,tt; uchar ta××e[]={ 0xc0,0xfc,0x24,0x4f, 0x66,0x6 ...…

查看全部问答>

我用 ADC12测量的电压值 有问题

应该是2.08v    但实际测出的值是  2.88v    不明白…

查看全部问答>

自动功率控制电路的一些问题

我最近做激光器的驱动电路,有一个自动功率控制电路这里有一些问题不明白,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?…

查看全部问答>