segunda-feira, 31 de julho de 2017

Capacímetro com o pic(medidor de capacitância) - compilador CCS

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!