Just for fun
Hardware:
Cần 1 điện trở cỡ vài Mohm nối song song với tụ cần đo, 2 chân tụ 1 chân nối vào 1 chân của msp430, chân còn lại nối đất (xem description trong source code)
Một cách đơn giản là hàn 3 chân header cái lỗ tròn (để cắm tụ vào) với 3 chân header cái lỗ vuông(để cắm vào lauchpad). Hàn 1 điện trở vào chân giữa với 1 trong 2 chân còn lại là xong.
Firmware:
Nguyên lý của chương trình này cũng không có gì là cao siêu, đơn giản chỉ cần nạp cho tụ đầy rồi đo thời gian xả của tụ.
Do cấu tạo của schmitt trigger trong msp430 thì tụ chỉ xả đến khoảng 0.25Vcc -> 0.55Vcc. Chọn giá trị 0.42Vcc. Áp dụng công thức v = Vcc * exp(-t/RC) tính ra được C ~ 0.976t với t tính bằng ms và C tính bằng pF.
Source code và thư viện LCD.c
Code:
//******************************************************************************
// MSP430G2xx3 - Capacitance metter, RO Method
//
// Description: Simple C-metter program using RO method.
// TimerA0 is used to measure discharge-time of
// the capacitor and display the C-value on LCD.
// Measure range: 0 -> 3000 pF
// |
// |-----------[R1//C]--|gnd
// |
//
// Built with CCS Version: 4.2.3
// Ho Tuan Vu - DHBK Tp.HCM - golden.spirit92@gmail.com
//******************************************************************************
#include <msp430g2553.h>
/* Define some global variables */
unsigned int meas_cnt;
unsigned int base_cnt;
/* Program subroutine */
void measure_count(void);
void display(int num);
/* Main program */
void main(void){
char j;
WDTCTL = WDTHOLD + WDTPW; // Stop watchdog timer
BCSCTL1 = CALBC1_16MHZ; // Set range
DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation
P2SEL = 0;
P2SEL2 = 0;
P2REN = 0;
TA0CCR0 = 0xFFFF;
TA0CTL = TASSEL_2;
lcd_init();
lcd_clear();
lcd_puts("Capacitance:");
base_cnt = 0; // Measure base capacitance
for(j = 0; j < 5; j++){
measure_count();
base_cnt += meas_cnt;
_delay_cycles(5000);
}
base_cnt = base_cnt/5;
/* The capacitor is discharged from Vcc to about 0.43*Vcc
=> the discharge time T = RC.ln(0.42), R = 1M2 => C ~ 0.061*(TAOR) (pF)
*/
signed long count;
while(1){
measure_count();
count = (meas_cnt - base_cnt);
if(count >= 0){
count = count*0.61;
display(count);
_delay_cycles(5000000);
}
}
}
void measure_count(void){
P2DIR |= BIT6;
P2OUT |= BIT6;
_delay_cycles(1000);
TA0R = 0;
P2DIR &= ~BIT6; // P2.6 input
TA0CTL |= MC_1; // Start timer, up mode
while(P2IN & BIT6); // Trap CPU
meas_cnt = TA0R; // Read TAR
P2DIR |= BIT6;
P2OUT &= ~BIT6; // P2.6 = 0
TA0CTL &= ~MC_1; // Stop timer;
}
void display(int num){
lcd_gotoxy(1,0);
lcd_putn(num);
lcd_puts("pF ");
}
https://www.dropbox.com/s/sj0zhxrk1dbqxl9/Cmetter.rar