Material para montagem em matriz de contato:
- Pic16F883 da Microchip
- Cristal de 20Mhz
- LCD de 16 x 2
- 2 Trimpot de 10K
- Resistencia de 180R
- Resistencia de 1k
- Resistencia de 10k
- Resistencia de 100k
- Resistencia de 1M
- Capacitor de 100nf
- 2 Capacitores de 15pF
- Vários capacitores para teste
- Cabinhos para licação
- Matriz de contato
- Fonte de 5v
Imagem do esquemático no simulador:
Protótipo do projeto:
O código Fonte:
////////////////////////////////////////////////////////////////////////////////
//Projeto:Capacimetro.c //
//data:27/07/2017 //
//créditos: http://www.eletronite.com.br/projetos/capacimetro-com-arduino //
//Convertido de arduino para pic: Renato Lobo Rodrigues //
// //
//lobosoft@oi.com.br //
////////////////////////////////////////////////////////////////////////////////
#include <16F883.h>
#DEVICE ADC=10
#use delay (clock = 20Mhz)
//Configura os fusiveis
#fuses HS
#fuses NOWDT
#fuses PUT
#fuses BROWNOUT
#fuses NOMCLR
#fuses PROTECT
#bit carga_Pin1 =0x05.5 //pin_A5 pino para carga do capacitor com resistor de 1k
#bit carga_Pin1_tris =0x85.5
#bit carga_Pin10 =0x05.4 //pin_A4 pino para carga do capacitor com resistor de 10k
#bit carga_Pin10_tris =0x85.4
#bit carga_Pin100 =0x07.0 //pin_C0 pino para carga do capacitor com resistor de 100k
#bit carga_Pin100_tris =0x87.0
#bit carga_Pin1000 =0x07.1 //pin_C1 pino para carga do capacitor com resistor de 1M
#bit carga_Pin1000_tris =0x87.1
#bit descarga_Pin =0x07.2 //pin_C2 pino para descarregar capacitor atraves de resistor de 1k
#bit descarga_Pin_tris =0x87.2
#define Valor_resistor1 1000.0F // valor do resistor de 1k
#define Valor_resistor10 10000.0F // valor do resistor de 10k
#define Valor_resistor100 100000.0F // valor do resistor de 100k
#define Valor_resistor1000 1000000.0F // valor do resistor de 1M
#define auto_Capacitance 0.000228F
// Variáveis globais
unsigned int32 inicio_tempo;
unsigned int32 Tempo_total;
float microFarads;
float nanoFarads;
float picoFarads;
unsigned char carga_Pin = 0;
float Valor_resistor;
void descarregaCap();
#include "lcd-4.c"
//Rotina de interrupção
#int_rtcc
void rotina_t0()
{
set_timer0(255) + get_timer0();
inicio_tempo++;
}
void main()
{
LCD_init(); //inicializa o LCD
//configura a interrupção do timer0
enable_interrupts(global);
setup_timer_0(rtcc_internal | rtcc_ext_l_to_h);
setup_timer_0(rtcc_8_bit | rtcc_div_1);
Enable_interrupts(int_timer0);
set_timer0(255);
//configura o ADC do pic canal 0
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN0);
// Configura pinos como entrada
carga_Pin10_tris = 1;
carga_Pin100_tris = 1;
carga_Pin1000_tris = 1;
carga_Pin1_tris = 1;
// imprime texto estático na tela
lcd_gotoxy(1,1);
printf (lcd_putc,"Lobosoft Ltda. ");
lcd_gotoxy(1,2);
printf (lcd_putc,"Cap = ");
while(true)
{
// Seleciona melhor resistor para capacitor a ser medido
carga_Pin = 0;
do
{
descarregaCap();
switch (carga_Pin)
{
case 0:
carga_Pin10_tris = 1;
carga_Pin100_tris = 1;
carga_Pin1000_tris = 1;
carga_Pin1_tris = 0;
carga_Pin1 = 1;
Valor_resistor = Valor_resistor1;
break;
case 1:
carga_Pin1_tris = 1;
carga_Pin100_tris = 1;
carga_Pin1000_tris = 1;
carga_Pin10_tris = 0;
carga_Pin10 = 1;
Valor_resistor = Valor_resistor10;
break;
case 2:
carga_Pin1_tris = 1;
carga_Pin10_tris = 1;
carga_Pin1000_tris = 1;
carga_Pin100_tris = 0;
carga_Pin100 = 1;
Valor_resistor = Valor_resistor100;
break;
case 3:
carga_Pin1_tris = 1;
carga_Pin10_tris = 1;
carga_Pin100_tris = 1;
carga_Pin1000_tris = 0;
carga_Pin1000 = 1;
Valor_resistor = Valor_resistor1000;
break;
}
//seleciona canal zero do ADC para leitura
set_adc_channel(0);
delay_us(10);
inicio_tempo = 0;
//aguarda carga de 63.2% do capacitor para calculo
while (read_adc() < 648); // 647 é 63.2% de 1023 (valor máximo da entrada analógica)
//calcula tempo de carga com 39.82% de correção
Tempo_total = (inicio_tempo*1.3982)*39.82;
carga_Pin++;
} while (Tempo_total < 1000 && carga_Pin != 4);
// Converte valor de capacitor medido para unidade de engenharia e imprime no display LCD
microFarads = ((float)Tempo_total / Valor_resistor) - auto_Capacitance;
if(microFarads >0)
{
lcd_gotoxy(7,2);
printf (lcd_putc," ");
lcd_gotoxy(7,2);
if (microFarads > 1)
{
printf (lcd_putc,"%fuf",microFarads);
}
else
{
nanoFarads = microFarads * 1000.0;
if (nanoFarads > 1)
{
printf (lcd_putc,"%fnf ",nanoFarads);
}
else
{
picoFarads = nanoFarads * 1000.0;
printf (lcd_putc,"%fpf",picoFarads);
}
}
descarregaCap();
delay_ms(500);
}
else
{
//Se o capacitor não estiver conectado diz que esta ausente
lcd_gotoxy(7,2);
printf (lcd_putc,"Ausente ");
}
}
}
// Função para descarregar capacitor
void descarregaCap() {
carga_Pin10_tris = 1;
carga_Pin100_tris = 1;
carga_Pin1000_tris = 1;
carga_Pin1_tris = 1;
descarga_Pin_tris = 0;
descarga_Pin = 0;
//Aguarda a descarga total do capacitor
while (read_adc() > 0);
descarga_Pin_tris = 1;
}
Biblioteca para LCD alfanumérico
////////////////////////////////////////////////////////////////////////////////
// BIBLIOTECA DO LCD //
// data:27/07/2017 //
// //
// //
////////////////////////////////////////////////////////////////////////////////
// Modifique os pinos o quanto Quiser.
#define LCD_DB4 PIN_b4
#define LCD_DB5 PIN_b5
#define LCD_DB6 PIN_b6
#define LCD_DB7 PIN_b7
#define LCD_RS PIN_b0
#define LCD_E PIN_b1
// Se voce quiser uma interface de 6 pinos para seu LCD, então
// conecte o pino R/W do LCD ao terra, e comente a seguinte linha
//#define USE_LCD_RW 1
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
//#define lcd_line_two 0x40 //LCD RAM address for the 2nd line
#define lcd_line_1 0x00 //LCD RAM address for the 1 line
#define lcd_line_2 0x40 //LCD RAM address for the 2 line
#define lcd_line_3 0x10 //LCD RAM address for the 3 line
#define lcd_line_4 0x50 //LCD RAM address for the 4 line
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(60);
#endif
}
}
/*------------duas linhas----------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
*/
//------------quatro linhas----------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
switch(y)
{
case 1:
address = lcd_line_1;
address += x-1;
break;
case 2:
address = lcd_line_2;
address += x-1;
break;
case 3:
address = lcd_line_3;
address += x-1;
break;
case 4:
address = lcd_line_4;
address += x-1;
break;
default:
address = lcd_line_1;
address += x-1;
break;
}
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1,2);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif
//implementado por Renato Lôbo Rodrigues
#separate
void lcd_cursor_on()
{
lcd_send_byte(0,0x0E);
}
#separate
void lcd_cursor_blink()
{
lcd_send_byte(0,0x0F);
}
#separate
void lcd_cursor_off()
{
lcd_send_byte(0,0x0C);
}
#separate
void lcd_shift_left()
{
lcd_send_byte(0,0x18);
}
#separate
void lcd_shift_right()
{
lcd_send_byte(0,0x1C);
}
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!