Измеритель емкости на PIC контроллере

Capmeter photoПростая схема достаточно точного измерителя емкости на PIC16F88, отображающего емкость на символьном ЖКИ.

Схема измерителя емкости:

Capmeter sch

При нажатии кнопки TEST, порт RA3 устанавливается в лог. "1". Резисторы R2 и R3 делят напряжение с порта RA3 пополам. Деленное напряжение подается на порт RA2 в качестве опорного для компаратора. Измеряемый конденсатор заряжается, а таймер начинает счет. Когда напряжение на конденсаторе превышает 1/2 опорного, таймер останавливается, и количество прошедших периодов таймера, умноженное на 10 - является емкостью конденсатора в нанофарадах. Значение емкости отображается на ЖКИ.

 

Код программы измерителя емкости:

/*
* Project name:
Capacitance Meter

* Test configuration:
MCU: PIC16F88
Oscillator: HS, 8.0000 MHz internal
SW: mikroC v8.1.0.0
*/

#define Vappied PORTA.F3
#define TEST PORTA.F0
unsigned int gCap = 0;
char gOverTest = 0;
char gMessage[8];
char gCapstr[8];
void interrupt(){
if(PIR1.TMR2IF){
TMR2 = 0x87; // best value to create 69.3us
gCap++;
if(gCap > 65500) gOverTest = 1;
PIR1.TMR2IF =0; // Clear int bit
}
}

void main(){
char i,j;
char cap_size;
ANSEL = 0;
TRISB = 0;
PORTB = 0;
OSCCON = 0x7E; // 8Mhz, RC internal clock
OPTION_REG.T0CS = 0;
INTCON.GIE = 1; //Enable global interrupt
INTCON.PEIE = 1; //Enable peripheral interrupt
//------------ Set up Timer2 ------------
PIE1.TMR2IE = 1;
T2CON = 0; // timer2 off, prescaler 1:1
TMR2 = 0x87;
PIR1.TMR2IF =0; // Clear int bit
//----------------------------------------
CMCON = 5; // one independent comparator
// RA1 = Vin- , RA2 = Vin+ = Vref
CMCON.C2INV = 1; // C2 output inverted
//------------------------------------------
ANSEL |= 6;
TRISA |= 6; // RA1 and RA2 are analog input
//---------------------------------------------
TRISA |= 1; // RA0 is digital input
TRISA &= ~8; // RA3 is digital outupt
//------------------------------------------
//while(1){}

Lcd_Init(&PORTB);
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 1, "Capacita");
Lcd_Out(2, 1, "nceMeter");
delay_ms(2000);
Lcd_Cmd(Lcd_Clear);
Lcd_Cmd(LCD_CURSOR_OFF);
Lcd_Out(1, 1, "Ready...");
Vappied = 0;

while(1){
if(!TEST) {
gCap = 0;
gOverTest =0;
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 1, "Testing.");
Lcd_Out(2, 1, "...");
TMR2 = 0x87;
Vappied = 1; //apply voltage
T2CON.TMR2ON = 1; // start timer
//T1CON.TMR1ON = 1; // start timer1
while(!CMCON.C2OUT) {
if(gOverTest) break;
}
T2CON.TMR2ON = 0; // stop timer
Vappied = 0;
//---------------------------------
if(!gOverTest){
WordToStr(gCap, gMessage); // convert int to string
//---------- remove space ' ' ----------
j=0;
for(i=0; i<6; i++){
if(gMessage[i]!= ' ') {
gCapstr[j] = gMessage[i];
j++;
gCapstr[j] = 0;
}
}
//--------------------------------------
cap_size = strlen(gCapstr); // find capacitor size in x10 nanofarad
switch (cap_size) {
case 1: {
gCapstr[4] = 0;
gCapstr[3] = gCapstr[0];
gCapstr[2] = '0';
gCapstr[1] = '.';
gCapstr[0] = '0';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 5, gCapstr);
break;
}
case 2: {
gCapstr[4] = 0;
gCapstr[3] = gCapstr[1];
gCapstr[2] = gCapstr[0];
gCapstr[1] = '.';
gCapstr[0] = '0';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 5, gCapstr);
break;
}
case 3: {
gCapstr[4] = 0;
gCapstr[3] = gCapstr[2];
gCapstr[2] = gCapstr[1];
gCapstr[1] = '.';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 5, gCapstr);
break;
}
case 4: {
gCapstr[5] = 0;
gCapstr[4] = gCapstr[3];
gCapstr[3] = gCapstr[2];
gCapstr[2] = '.';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 4, gCapstr);
break;
}
case 5: {
gCapstr[6] = 0;
gCapstr[5] = gCapstr[4];
gCapstr[4] = gCapstr[3];
gCapstr[3] = '.';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 3, gCapstr);

break;
}
}
Lcd_Out(2, 1, "uF");
} else {
gOverTest = 0;
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 1, "Can not ");
Lcd_Out(2, 1, "test.");
}
delay_ms(1000);
}
}
}

Фото готового устройства:

Capmeter photo

 

Загрузка...