Mostrando postagens com marcador Por Renato Lôbo Rodrigues.. Mostrar todas as postagens
Mostrando postagens com marcador Por Renato Lôbo Rodrigues.. Mostrar todas as postagens

quinta-feira, 31 de janeiro de 2019

PWM de 20KHZ com o PIC 12F683 - Saída variável de 0 a 10V.


          Olá pessoal que acompanha o blog! depois de um bom tempo sem nenhum post, temos mais um projeto realizado por nosso colaborador Renato Lôbo, que nos traz um circuito que controla a saída por meio do uso da modulação PWM.
           O funcionamento se baseia na leitura da tensão que vem do potenciômetro(que neste caso varia de 0 a 5V) e então o microcontrolador irá gerar um sinal de pwm na frequência de 20Khz  e com largura de pulso proporcional a entrada(ou seja para  0 a 5V temos 0 a 10V) veja Figura 1, O filtro passa baixas  na saída(R3 e C2) faz com que o sinal de onda quadrada se aproxime do sinal analógico, dando uma "suavizada" no contorno do sinal  que tera um ganho de potencia por meio do transistor BC337.

Figura 1 - sinal gerado pelo microcontrolador.

 O código fonte.

Paste your////////////////////////////////////////////////////////////////////////////////
//              Projeto: PWM de 20Khz                                         //
//                 Nome: Renato Lôbo Rodrigues                                //
//                 Data: 27/01/19                                             //
//                Email: lobosoft@oi.com.br                                   //
////////////////////////////////////////////////////////////////////////////////
#include <12F683.h>
#use delay (clock = 8Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

//Estes registros encontra-se nas funções especiais de cada modelo de pic.
#bit tris_bot1 = 0x85.0 //direção do pino A0
#bit bot1      = 0x05.0 //pino A0

#bit tris_bot2 = 0x85.1 //direção do pino A1
#bit bot2      = 0x05.1 //pino A1

#bit tris_pwm = 0x85.2 //direção do pino A2
#bit p_pwm    = 0x05.2 //pino A2

#bit tris_led = 0x85.5 //direção do pino A5
#bit led      = 0x05.5 //pino A5

#bit tris_adc = 0x85.4 //direção do pino A4
#bit adc      = 0x05.4 //pino A5

//Registro dos comparadores
#byte CMCON0            = 0x19          //Controle dos comparadores

//Registros do ADC
#byte ADCON0            = 0x1F          //Controle do ADC
#bit  ADCON0_GO_DONE    = ADCON0.1      //Status de conversão
#byte ANSEL             = 0x9F          //Selecioa os pinos Analógicos
#byte ADRESH            = 0x1E          //endereço do byte mais significativo
#byte ADRESL            = 0x9E          //endereço do byte menos significativo


//Registros de interrupção
#byte INTCON            = 0x0B          //Controle de interrupção
#bit  INTCON_GIE        = INTCON.7      //Registro geral
//#bit  INTCON_PEIE       = INTCON.6    //Interrupção de periferico

//Registros de PULL_UP
#byte OPTION_REG        = 0x81          //Registros de Opção 
#bit  OPT_REG_GPPU      = OPTION_REG.7  //habilitar ou desabilitar os Pull_up dos pinos 
#byte WPU               = 0x95          //Configurar os pinos que vão ser habilitados

//Registros do CCP1
#byte CCP1CON           = 0x15          //Registro do CCP1
//#bit  CCP1CON_DC1B1     = CCP1CON.5     //Bit 1 para byte menos significativo
//#bit  CCP1CON_DC1B0     = CCP1CON.4     //Bit 0 para byte menos significativo
#byte CCPR1L            = 0x13          //Byte mais significativo

//Registros do Timer2 para PWM
#byte T2CON             = 0x12          //Controle do timer 2
#byte PR2               = 0x92          //periodo do PWM


int16 pwm = 0;

//______________________________________________________________________________
//Rotina principal
void main()
{
   int1  st1         = false;    //status do botão
   int1  st2         = false;    //status do botão
   int   toc         = false;    //inicia regulando no potenciometro
   int16 valor_adc   = 0;        //inicia com zero 
   
   tris_bot1         = 1;        //pino A0 como entrada
   tris_bot2         = 1;        //pino A1 como entrada
   tris_adc          = 1;        //pino A4 entrada analogica
   tris_pwm          = 0;        //pino A2 do pwm como saída
   pwm               = 0;        //inicia o pwm com zero
   tris_led          = 0;        //pino A5 do led como saída
   led               = 0;        //led apagado
   
   OPT_REG_GPPU   = 0;  //zero = habilita os pull-up 
   WPU            = 3;  //00000011 liga pul-up dos pinos A0 e A1
                        //||||||||_Pino A0
                        //|||||||_Pino A1
                        //||||||_Pino A2
                        //|||||_Não usado, pino A3 não tem Pull_up interno
                        //||||_Pino A4 
                        //|||_Pino A5
                        //||_dois bit não usado

   CMCON0     = 7;      //000000111 Comparadores Desligados
                        //|||||||||_Tres bits "um" desliga todos os comparador
                        //||||||_Não usado para esse caso
   
   ADCON0     = 141;    //10001101 Controle do ADC
                        //||||||||_liga ou desliga o ADC
                        //|||||||_Status de conversão, zero terminou a conversão 
                        //||||||_Tres bits para determminar o canal usado 
                        //|||_Não implementado
                        //||_VDD
                        //|_Formatado a direita
                        
   ANSEL       = 88;    //10001000  frequência de atualização e pino A4 como ADC
                        //||||||||_Quatro bit seta o pinos analogicos
                        //||||_Tres bits seta a frequencia de conversão
                        //|_Não usado

   INTCON_GIE  = 1;     //Habilita Registro Geral
   
   CCP1CON     = 12;    //00001100 Habilita o modo PWM 
                        //||||||||_Quatro bits define o uso do PWM do CCP1
                        //||||_Dois bit do Duty
                        //||_Não usado
                        
   CCPR1L      = 0;     //Byte mais significativo
 
   T2CON       = 4;     //00000100
                        //||||||||_2 bit prescaler do time 2 = 1
                        //||||||_ bit liga o timer2
                        //|||||_Quatro bit do Postscaler = 1
                        //|_não usado
                        
   PR2         = 49;    //49 calculado para PWM com frequência de 20 Khz


   //Setando o Duty
   //CCPR1L = pwm>>2;   //DUTY(;
   //CCP1CON = (pwm <<4) | 12;

   while(true)     //laço infinito
   {
      ADCON0_GO_DONE = 1;
      while(ADCON0_GO_DONE)//Espera até terminar a conversão analogica para digital  
      valor_adc = ((int16)ADRESH<<8)|(ADRESL); //Formatado a direita
      
      if(!toc) pwm =  valor_adc/5.0895;   //1023/201

      CCPR1L = pwm>>2;                    //Duty
      //CCP1CON = (pwm<<4) | 12;      //dois bits do Duty    
      CCP1CON = (pwm<<4) | 12;
      
      if ( bot1)   st1=false;
      if (!bot1 && st1==false)
      {
           st1=true;
           led = 1 ; //Acende o led1
           if(pwm>=10) pwm=pwm-10;
           if(pwm<=10)pwm=0;
           CCPR1L = pwm>>2;               //Duty
           CCP1CON = (pwm <<4) | 12; //dois bits do Duty            
           toc = true;
           delay_ms(10);
           led = 0 ;
      }
      if ( bot2)   st2=false;
      if (!bot2 && st2==false)
      {
           st2=true;
           led = 1 ; //Acende o led1
           if(pwm<191) pwm=pwm+10;
           if(pwm>=191)pwm=201;
           CCPR1L = pwm>>2;               //Duty
           CCP1CON = (pwm<<4) | 12; //dois bits do Duty          
           delay_ms(10);
           led = 0 ;
      }
      if(!bot1 && !bot2) toc = false;
   }
} text here.

Esquemático do projeto:


PCB - do protótipo.
              O protótipo final ficou conforme a figura a seguir:


Obrigado e até a próxima!

quinta-feira, 30 de novembro de 2017

Girando motor de passo unipolar nos dois sentidos

     Olá, pessoal que acompanha o blog,para hoje temos uma postagem feita pelo nosso colaborador Renato Lôbo, que consiste em controlar um motor com o pic 12F675, neste projeto o motor de passo funcionará com  uma velocidade de 20 rpm.Projeto feito usado o compilador CCS.
O código fonte:

////////////////////////////////////////////////////////////////////////////////
// Projeto: Girando motor de passo unipolar (28byj-48) nos dois sentidos. //
// Nome: Renato Lôbo Rodrigues                                                //
// Data: 29/11/17                                                             //
// Email: lobosoft@oi.com.br                                                  //
////////////////////////////////////////////////////////////////////////////////

//http://giocarduino.altervista.org/e19-motore-passo-passo.pdf

//dois botões pulsadores no pino 3 e 4 do pic e GND
//0 pino 4 do pic (A3) deve ter um resistor de pull-up 

//pino 7 do pic em 1N1 da placa que acompanha o motor 28byj-48 
//pino 6 do pic em 1N2
//pino 5 do pic em 1N3
//pino 2 do pic em 1N4

//GND em - da placa
//12V em + da placa

//Configuração PIC
#include <12f675.h> 
//inicializando os fusiveis
#fuses INTRC_IO, NOMCLR, NOWDT,PROTECT,PUT,BROWNOUT,CPD
#use delay(clock=4Mhz)        //clock interno de 4mhz                 

#byte tris_portA     = 0x85   //sentido dos pinos do portA

#bit bot1= 0x05.3             //botão sentido horario
#bit bot2= 0x05.4             //botão sentido anti-horario


#bit bob_A1 = 0x05.0          //terminais do motor de passo bobina A e B
#bit bob_A2 = 0x05.1          //
#bit bob_B1 = 0x05.2          //
#bit bob_B2 = 0x05.5          //
                              //se 5 fios lique o center type no GND
                              //se 6 fios ligue os dois center type no GND

int1 roda = false;            //iniciando a variaval roda como falsa
int1 dir  = false;            //iniciando a variaval dir como falsa

int8 pulso =0;                //iniciando a pulso com zero

void motor(int8 num) //configuração de giro do motor em 0.5 passo
{
   switch(num)
   {
      case 0:  bob_A1=1;
               bob_A2=0;
               bob_B1=0;
               bob_B2=0;   
               break;
      case 1:  bob_A1=1;
               bob_A2=1;
               bob_B1=0;
               bob_B2=0;   
               break;
      case 2:  bob_A1=0;
               bob_A2=1;
               bob_B1=0;
               bob_B2=0;   
               break;
      case 3:  bob_A1=0;
               bob_A2=1;
               bob_B1=1;
               bob_B2=0;   
               break;
      case 4:  bob_A1=0;
               bob_A2=0;
               bob_B1=1;
               bob_B2=0;   
               break; 
      case 5:  bob_A1=0;
               bob_A2=0;
               bob_B1=1;
               bob_B2=1;   
               break;               
      case 6:  bob_A1=0;
               bob_A2=0;
               bob_B1=0;
               bob_B2=1;   
               break;
      case 7:  bob_A1=1;
               bob_A2=0;
               bob_B1=0;
               bob_B2=1;   
               break;
      case 8:  bob_A1=0;      //motor desligado
               bob_A2=0;
               bob_B1=0;
               bob_B2=0;   
               break;
   }
}

#int_timer1
void rotina_t1()              //na frenquência de 1khz esse motor gira a 20 rpm 
{
   if(roda)
   {   
      if(dir)
      {
         if(pulso < 7)pulso++;else pulso=0;  //gira anti-horário 
      }else{
         if(pulso > 0)pulso--;else pulso=7;  //gira horário
      }
      motor(pulso);                          //gira 0.5 passo a cada chamada
      roda=false;                            //avisa que terminou 0 0.5 passo
   }
   else
   {
      motor(8);
   }
   set_timer1(64536 + get_timer1());         //preset de contagem do timer1
}



void main ()
{            
   int1 st1 = false,st2 = false;             //status do botão
   
   setup_comparator(NC_NC_NC_NC);            //comparadores desligados
   setup_vref(FALSE);                        //sem valor de referencia
   port_a_pullups(0b00010000);               //pull-up para pino A3
   tris_portA=0b11011000;                    //entrada e saidos dos pinos
   
   bob_A1=0;                                 //todos pinos do motor inicia em zero
   bob_A2=0;
   bob_B1=0;
   bob_B2=0;    
   
   // Timer1 para estouro a cada 1 ms.(Frequência do Ocilador 4Mhz)
   enable_interrupts(global);
   setup_timer_1(t1_internal | t1_div_by_1);
   Enable_interrupts(int_timer1);
   set_timer1(64536);

   while (TRUE)
   {
      if(!roda)
      {
         if( bot1) st1 = false;               
         if(!bot1 && !st1)                   //gira horário 
         {
            dir=false;
            roda=true;
         }
         if( bot2) st2 = false;
         if(!bot2 && !st2)                   //gira anti-horário
         {
            dir=true;
            roda = true;
         }
      }
   }
}

Obrigado a todos. até a próxima!


segunda-feira, 21 de agosto de 2017

Contador 0-99 com pic - usando compilador CCS

Olá, para este post vamos ver como fazer um algoritmo que conta de 0 a 99 usando o compilador CCS, um projeto de Renato Lôbo. para isto vcs irão precisar: 

- Pic16F628 da Microchip
- Placa com display duplo de 7 segmentos de catodo comum
- Capacitor de 100nf para desacoplamento
- Cabinhos para ligação
- Matriz de contato
- Fonte de 5v 








O código fonte:

////////////////////////////////////////////////////////////////////////////////
// Projeto: Usando Varredura no acionamento de display de 7 segmentos.        //
// Nome: Renato Lôbo Rodrigues                                                //
// Data: 20/08/17                                                             //
// Email: lobosoft@oi.com.br                                                  //
////////////////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

#byte tris_portA     = 0x85
#byte tris_portB     = 0x86

#bit display0        = 0x05.0 //pino A0
#bit display1        = 0x05.1 //pino A1
#bit SegA            = 0x06.1 //pino B1
#bit SegB            = 0x06.2 //pino B2
#bit SegC            = 0x06.3 //pino B3
#bit SegD            = 0x06.4 //pino B4
#bit SegE            = 0x06.5 //pino B5
#bit SegF            = 0x06.6 //pino B6
#bit SegG            = 0x06.7 //pino B7


void digito(int8 num)
{
   switch(num)
   {
      case 0:  SegA=1;//  AAAA
               SegB=1;// F    B
               SegC=1;// F    B
               SegD=1;//   
               SegE=1;// E    C
               SegF=1;// E    C
               SegG=0;//  DDDD
               break;
      case 1:  SegA=0;//  
               SegB=1;//      B
               SegC=1;//      B
               SegD=0;// 
               SegE=0;//      C
               SegF=0;//      C
               SegG=0;//  
               break;
      case 2:  SegA=1;//  AAAA
               SegB=1;//      B
               SegC=0;//      B
               SegD=1;//  GGGG
               SegE=1;// E    
               SegF=0;// E    
               SegG=1;//  DDDD
               break; 
      case 3:  SegA=1;//  AAAA
               SegB=1;//      B
               SegC=1;//      B
               SegD=1;//  GGGG
               SegE=0;//      C
               SegF=0;//      C
               SegG=1;//  DDDD
               break; 
      case 4:  SegA=0;//  
               SegB=1;// F    B
               SegC=1;// F    B
               SegD=0;//  GGGG
               SegE=0;//      C
               SegF=1;//      C
               SegG=1;//  
               break; 
      case 5:  SegA=1;//  AAAA
               SegB=0;// F    
               SegC=1;// F    
               SegD=1;//  GGGG
               SegE=0;//      C
               SegF=1;//      C
               SegG=1;//  DDDD
               break;               
      case 6:  SegA=1;//  AAAA
               SegB=0;// F     
               SegC=1;// F     
               SegD=1;//  GGGG
               SegE=1;// E    C
               SegF=1;// E    C
               SegG=1;//  DDDD
               break; 
      case 7:  SegA=1;//  AAAA
               SegB=1;//      B
               SegC=1;//      B
               SegD=0;//
               SegE=0;//      C
               SegF=0;//      C
               SegG=0;//  
               break;
      case 8:  SegA=1;//  AAAA
               SegB=1;// F    B
               SegC=1;// F    B
               SegD=1;//  GGGG
               SegE=1;// E    C
               SegF=1;// E    C
               SegG=1;//  DDDD
               break;               
      case 9:  SegA=1;//  AAAA
               SegB=1;// F    B
               SegC=1;// F    B
               SegD=1;//  GGGG
               SegE=0;//      C
               SegF=1;//      C
               SegG=1;//  DDDD
               break;
   }
}
//___________________________________________
//Rotina principal
void main()
{
   int1        d = false;
   int8     dig0 = 0;
   int8     dig1 = 0;
   int8    valor = 0;
   int16   conta = 0;  
   
   tris_portA = 0b11111100;   
   tris_portB = 0b00000001;

 
   //DEFINE display0 e TODOS SEGMENTOS LIGADOS PARA TESTE DURANTE 1 SEGUNDO
   display0=1;display1=0;
   SegA=1;//  AAAA
   SegB=1;// F    B
   SegC=1;// F    B
   SegD=1;//   GG
   SegE=1;// E    C
   SegF=1;// E    C
   SegG=1;//  DDDD
   //aguarda 1 segundo
   delay_ms(1000);
   //DEFINE display1 e TODOS SEGMENTOS LIGADOS PARA TESTE DURANTE 1 SEGUNDO
   display0=0;display1=1;
   SegA=1;//  AAAA
   SegB=1;// F    B
   SegC=1;// F    B
   SegD=1;//   GG
   SegE=1;// E    C
   SegF=1;// E    C
   SegG=1;//  DDDD
   //aguarda 1 segundo
   delay_ms(1000);  
   
   while(true) //laço infinito
   {
      if(!d)                     //se d é falso
      {
         display0=1;display1=0;  //seleciona display0
         digito(dig0);           //chama rotina para digitos de 0 a 9
         d=1;                    //troca para display1
      }else{                     //se falso
         display0=0;display1=1;  //seleciona display1
         digito(dig1);           //chama rotina para digitos de 0 a 9
         d=0;                    //troca para display0
      }
      conta++;          //incremento de contagem para acertar um tempo de +/- 1S
      if(conta>=100)    //testa se ja venceu o tempo
      {
         if(valor<100){ //testa se o valor e maior que 100
            valor++;    //se verdadeiro incrementa o valor
         }else{ 
            valor=0;    // se falso atribui zero
         }
         
         dig0=valor%10; //extrai o resto da divisão para o display0
         dig1=valor/10; //extrai o inteiro da divisão para o display1
         
         conta=0;       //atribui zero para iniciar a contagem de tempo
      }
      delay_ms(10);     //tempo de espera para troca de display
   }
}

A demonstração:



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);
    }

sábado, 1 de julho de 2017

Motor de passo Bipolar - no CCS



Olá pessoal que acompanha o blog, hoje temos mais uma postagem do senhor Renato Lôbo Rodrigues,e neste exemplo será demonstrado como acionar um motor de passo por fase.

lista de peças para montagem em bancada:


- matriz de contatos pequena
- pic12F675, microcontrolador da Microchip
- 2 resistor de 10k para pull-up dos botões
- 2 botões de pressão
- 1 capacitor de acoplamento 104
- cabinhos para ligações dos componentes
- fonte de 5V 2A.
- Uma ponte H L298
- Motor de passo pequeno de 1A por fase

O código fonte:


///////////////////////////////////////////////////////////////////////
//              Projeto: Motor de passo Bipolar                      //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 28/06/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////

#include <12F675.h>        // inclusão do pic em questão
#OCS 4 MHz                 // oscilador 4.000.000 herts
#use fast_io(A)            // O método rápido de fazer E/S

//Configura os fusiveis
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT
//=======================================================================
//Definições de variaveis globais
//=======================================================================

#bit pulso = 0x05.2        //define pino A2 para pulso do motor
#bit dir   = 0x05.3        //define pino A3 para direção de rotação


#bit A     = 0x05.0        // define pino A0 para motor terminal A
#bit B     = 0x05.1        // define pino A1 para motor terminal B
#bit C     = 0x05.4        // define pino A2 para motor terminal C
#bit D     = 0x05.5        // define pino A3 para motor terminal D

#byte tris_portA = 0x85    // direção dos pinos do portA

int8 i = 0;              // variável i(indice) do tipo inteiro 8 bits 

//=======================================================================

void motor()               //função para girar o motor de passo Bipolar
{
   if (i<1) i=4;           //se i é menor que 1 então i = 4
   if (i>4) i=1;           //se i é maior que 4 então 1 = 1
   switch(i)               
   {
      case 1:A=1;B=0;C=0;D=1; break;    //1001
      case 2:A=0;B=1;C=0;D=1; break;    //0101
      case 3:A=0;B=1;C=1;D=0; break;    //0110
      case 4:A=1;B=0;C=1;D=0; break;    //1010
   }
}

void main()//Rotina principal do programa
{
   tris_portA = 0b00001100; //pinos A2 e A3 como entrada e o restante como saida
   While(true)              //loop infinito
   {
      if(!pulso)                 //se pulso é verdadeiro
      {
         if(dir) i++; else i--;  //igual a um: roda num sentido senão no outro sentido
         motor();                //vai para função motor()
         delay_us(800);          //800 microsegundos / simulação: 80 milesegundos
      }
   }
}//Fim de programa

A simulação:

Vídeo com o protótipo funcionando:





domingo, 18 de junho de 2017

Estrobo duplo alternado para estacionamento - CCS


Olá, hoje temos uma postagem do senhor Renato "Estrobo duplo alternado para estacionamento".
lista de peças para montagem em bancada:

- matriz de contatos pequena
- pic16F628A, microcontrolador da Microchip
- 2 resistor de 220 ohm para limitar a corrente do LED
- 2 LED de 3 ou 5 mm vermelho
- cabinhos para ligações dos componentes
- fonte de 5V, pode ser um carregador de celular ou suporte de 3 pilhas(4,5V)

O código fonte:
///////////////////////////////////////////////////////////////////////
//              Projeto: Estrobo duplo alternado para estacionamento //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 12/03/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

//Estes registros encontra-se nas funções especiais de cada modelo de pic.

#byte tris_portA = 0x85   //direção do portA
#bit led1        = 0x05.0 //pino A0
#bit led2        = 0x05.1 //pino A1

int1 flag=false;
//___________________________________________
void estrobo()
{
   int8 f;              //variável do laço for
   flag=!flag;          //inverte a variável flag
   if(flag){            //se flag é verdadeiro
      for(f=0;f<10;f++) //laço de contagem de 0 até 9
      {
         led1 = !led1 ; //Acende ou apaga o led1
         delay_ms(30);  //tempo de 30 milisegundos
      }
   }else{               //caso flag seja falso
      for(f=0;f<10;f++) //laço de contagem de 0 até 9
      {
         led2 = !led2 ; //Acende ou apaga o led1
         delay_ms(30);
      }
   }
}

//Rotina principal
void main()
{
   int16 conta=0;             //cria uma variável conta igual a zero
   tris_portA = 0b11111100;   //pino A0 e A1 como saída
   led1 = 0;                  //apaga o led1
   led2 = 0;                  //apaga o led2   

   while(true)                //laço infinito
   {
      conta++;                //inrementa conta
      if(conta>=25000)        // se conta é maior ou igual a 25000
      {
         conta=0;estrobo();   //zera a contagem e chama rotina de estrobo
      }//fim do if
   }//fim do while
} //fim do main

Vídeo de demonstração:

https://drive.google.com/file/d/0B9fK-FRZeeWNQWNsSXRzZmdMTVE/view?usp=sharing

quinta-feira, 1 de junho de 2017

Selecionando LED na sequência usando um botão - CCS

Selecionando LED na sequência usando um botão


lista de peças para montagem em bancada:

- matriz de contatos pequena
- pic16F628A, microcontrolador da Microchip
- 4 resistor de 220 ohm para limitar a corrente do LED
- 4 LED de 3 ou 5 mm vermelho
- Botão de contato
- cabinhos para ligações dos componentes
- fonte de 5V, pode ser um carregador de celular ou suporte de 3 pilhas(4,5V)

O código fonte:

///////////////////////////////////////////////////////////////////////
//              Projeto: Selecionar LED na sequência usando um botão //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 18/05/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

//Estes registros encontra-se nas funções especiais de cada modelo de pic.
#byte tris_portA = 0x85   //direção do portA
#byte tris_portB = 0x86   //direção do portB
#bit bot1        = 0x06.3 //pino B3

#bit RBPU        = 0x81.7 //Registro pullup do portB 

#bit led1        = 0x05.0 //pino A0
#bit led2        = 0x05.1 //pino A1
#bit led3        = 0x05.2 //pino A2
#bit led4        = 0x05.3 //pino A3

//___________________________________________
//Rotina principal
void main()
{
   int1 st1 = true;  //status do botão
   int8 ponteiro = 0;//seleciona um LED de cada vez
   
   tris_portB = 0b11111111; //todos os pinos como entrada
   RBPU = 0;                //pull-up portB ativados
   
   tris_portA = 0b11110000; //pino A0,A1,A2,A3 como saída
   led1 = 1;         //liga led1
   led2 = 0;         //desliga led2   
   led3 = 0;         //desliga led3   
   led4 = 0;         //desliga led4   
   
   while(true)       //laço infinito
   {
      //funciona quando solta o botão (KeyUp)
      if (!bot1)   st1=false;
      delay_ms(50);           //um tempo para anular repique da chave
      if ( bot1 && st1==false)
      {
           st1=true;
           ponteiro++;
           if(ponteiro>3)ponteiro=0;
           led1 = 0 ;led2 = 0 ;led3 = 0 ;led4 = 0 ; //Apaga todos os LEDs
           switch (ponteiro)
           {
            case 0:led1 = 1 ; //Acende o led1
                  break;
            case 1:led2 = 1 ; //Acende o led2
                  break;
            case 2:led3 = 1 ; //Acende o led3
                  break;
            case 3:led4 = 1 ; //Acende o led4
                  break;
           }
           delay_ms(200); //um tempo para anular repique da chave
      }//fim do if
   }//fim do while
} //fim do main

quinta-feira, 11 de maio de 2017

Usando timer 0 com o CSS (por: Renato Lôbo Rodrigues)

           Olá pessoal que acompanha o blog, temos mais uma postagem do senhor Renato Lôbo,um programa escrito em C para compilador CCS, que faz piscar um LED usando o timer0 configurado pelos registradores, usando como referência o datasheet do PIC6F628A da Microchip.
http://ww1.microchip.com/downloads/en/DeviceDoc/40044G.pdf

lista de peças para montagem em bancada:
- matriz de contatos pequena
- pic16F628A, microcontrolador da Microchip
- resistor de 220 ohm para limitar a corrente do LED
- LED 3 ou 5 mm vermelho
- cabinhos para ligações dos componentes
- fonte de 5V, pode ser um carregador de celular ou suporte de 3 pilhas(4,5V)
A simulação:




foto do projeto:


O código fonte :

///////////////////////////////////////////////////////////////////////
//              Projeto: pisca-pisca usando timer0                   //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 11/05/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

#byte tris_portA = 0x85 //direção dos pinos do portA
#byte tris_portB = 0x86 //direção dos pinos do portB

#bit led1      = 0x05.0 //pino A0

//##############################################################################
#bit GIE           = 0x0b.7 //interrupção blobal
#bit TOIE          = 0x0b.5 //interrupção timer0
#bit TMR1ON        = 0x10.0 //interrupção timer1
#bit TMR2ON        = 0x12.2 //interrupção timer2

#byte tmr0         = 0x01   //preload do timer0

#byte OPTION_REG = 0x81    //registro no endereço 0x81 do banco1

//___________________________________________
//Rotina de interrupção do timer0
#int_rtcc
void rotina_t0()
{
   static int8 conta;
   conta++;               // conta 125 vezes o tempo do timer0(4ms) para completar 500 miliseguundos
   if (conta==125)      //125*4ms = 500ms => ciclo de 1 segundo
   {
      led1=~led1;       //inverte a saída ligando ou desligando o LED.
      conta = 0;
   }
   tmr0 = 6;            //inicia a contagem em 6 e vai até 256(onde estoura)
}
//___________________________________________
//Rotina principal
void main()
{
   //pinos configurado como entrada por segurança  (alta impedância)
   tris_portA = 0b11111110; //todos os pinos do portA como entrada exceto pino A0 como saída
   tris_portB = 0b11111111; //todos os pinos do portB como entrada
   
   led1 = 1;       //Acende o led1

   //registro configurado para 4 milisegundos(veja pagina 25 do datasheet)
   OPTION_REG = 0b10000011;//1   = pull-up desabilitado
                           //0000= deixe tudo zero como padrão
                           //011 =prescaler dividido por 16

   tmr0 = 6;                        //preload do timer0 para 4ms
   GIE = 1;                         //interrupção global ativa
   TOIE = 1;                        //interrupção timer0 ativa
   TMR1ON = 0;                      //desabilita timer1
   TMR2ON = 0;                      //desabilita timer2
  

   while(true)     //laço infinito
   {
     
   }
}