Ir ao conteúdo
  • Cadastre-se

Voltimetro e Aperimetro para fonte de bancada


Ir à solução Resolvido por .if,

Posts recomendados

Olá pessoal beleza, eu atualmente estou fazendo um projetinho aqui, meu objetivo é fazer um voltímetro e amperímetro para um fonte de bancada variável de 0 a 25V com um trafo de v2 = 25 e 6A, porém eu preciso de um voltímetro e um amperímetro, portanto, eu resolvi fazer um instrumento de medição com o PIC16F676 que é bem baratinho ele custa uns 5 reais. O projeto do voltímetro esta quase pronto, porém, eu sou novato e estou aprendendo a programar e eu queria umas dicas para fazer uma programação com o display 7segmentos para mostrar a tensão da variável do AD, porque eu achei minha rotina muito ruim, eu uso muito if e else, acredito que se vocês podem me dar umas dicas para melhorar esse código. Também peço umas dicas para fazer o amperímetro.

 

 

Eu uso o MPLABX e o compilador XC8, veja o código do meu projeto:

 

//********************************************************************************************************************************************************
// Voltimetro de Bancada digital
// Autor: Lucas Pereira de Souza Pinto   DATA: 21/04/2015
// Projeto com crystal de 20mhZ
// TOSC = 1/FOSC
// FOSC: Frequêcia do oscilador
// TOSC: Oscilador interno
// Formula para o timer  Tempo_requerido = (4)*[(1)/(FOSC)]*Prescaler*(8bits_our_16bits - Carga_do_timer)
// Cálculos para este projeto
// Ciclo de maquina = (1/20mhZ)*4 = 200*10^-9S ou 0,2uS//200uS
// 500000*10^-6 = (0,2*10^-6)*(8)*(65536 - Q)
//********************************************************************************************************************************************************

//********************************************************************************************************************************************************
//Include
#include <stdio.h>
#include <stdlib.h>
#include <pic16f676.h>
#include <xc.h>
#define _XTAL_FREQ 20000000         // cristal de 20 Mhz
#define delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
//********************************************************************************************************************************************************

//********************************************************************************************************************************************************
//CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF           // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF          // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON           // RESET ON
#pragma config BOREN = OFF          // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF             // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF            // Data Code Protection bit (Data memory code protection is disabled)
//********************************************************************************************************************************************************

//********************************************************************************************************************************************************
//Definições
#define BUTTON   PORTAbits.RA2  //BOTÃO PARA TROCAR DE V/A
#define Q1       PORTCbits.RC4  //NPN1
#define Q2       PORTAbits.RA4  //NPN2
#define Q3       PORTAbits.RA5  //NPN3
#define A         PORTCbits.RC0  //A
#define B         PORTCbits.RC1  //B
#define C         PORTCbits.RC2  //C
#define D         PORTCbits.RC3  //D
#define LED     PORTCbits.RC5  //AMPERIMETRO

//********************************************************************************************************************************************************
const unsigned char display[] ={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
//********************************************************************************************************************************************************
//Protótipos de Funções
void bank(char num);                     //Protótipo da função do banco para acesso do banco da memória
void delay_ms_125();                     //Protótipo da função Timer1 125mS
void delay_ms_5();                       //Protótipo da função Timer1 5mS
void delay_ms_1();                       //Protótipo da função Timer1 1mS
void pic_init();                         //Protótipo para iniciar o pic
void config_AD();                        //Protótipo para configurar conversor AD
int  read_AD();                          //Protótipo para conversão AD
//********************************************************************************************************************************************************

//********************************************************************************************************************************************************
void interrupt  interrup(void)           // Vetor nterrupção
{
}
//********************************************************************************************************************************************************

//********************************************************************************************************************************************************
// Programa Principal
int main()
{  
    pic_init();                         //START PIC
    config_AD();                        //CONFIG AD
    float var = 0;                      //VARIAVEl GLOBAL
       
    while(1)
    {
     var = read_AD()*25.0;
     var = var/1024;

    
     if(var == 0)
     {
         PORTC = display[0x00];
         Q1 = 1;
         Q2 = 0;
         Q3 = 0;
         delay_ms_5();
         PORTC = display[0x00];
         Q1 = 0;
         Q2 = 1;
         Q3 = 0;
         delay_ms_5();
         PORTC = display[0x00];
         Q1 = 0;
         Q2 = 0;
         Q3 = 1;
         delay_ms_5();
     }
     else if(var >= 00.5)
     {
         PORTC = display[0x05];
         Q1 = 1;
         Q2 = 0;
         Q3 = 0;
         delay_ms_5();
         PORTC = display[0x00];
         Q1 = 0;
         Q2 = 1;
         Q3 = 0;
         delay_ms_5();
         PORTC = display[0x00];
         Q1 = 0;
         Q2 = 0;
         Q3 = 1;
         delay_ms_5();

     }
     else if(var >= 01.0)
     {
         PORTC = display[0x00];
         Q1 = 1;
         Q2 = 0;
         Q3 = 0;
         delay_ms_5();
         PORTC = display[0x01];
         Q1 = 0;
         Q2 = 1;
         Q3 = 0;
         delay_ms_5();
         PORTC = display[0x00];
         Q1 = 0;
         Q2 = 0;
         Q3 = 1;
         delay_ms_5();

     }
     else
     {
         LED = 1;
     }

    }//End_while
}//End_main
//********************************************************************************************************************************************************

//********************************************************************************************************************************************************
//Trabalhos das funções
void delay_ms_125()
{
       //start
       TMR1H = 0x31;                   //Timer 1 para 125mS
       TMR1L = 0x2D;
       T1CONbits.TMR1ON = 1;
       while(!PIR1bits.TMR1IF);
       T1CONbits.TMR1ON = 0;
       PIR1bits.TMR1IF = 0;
       PIR1bits.T1IF = 0;
       TMR1H = 0x00;
       TMR1L = 0x00;
}
void delay_ms_5()
{
       //start
       TMR1H = 0xF3;                   //Timer 1 para 5mS
       TMR1L = 0xCA;
       T1CONbits.TMR1ON = 1;
       while(!PIR1bits.TMR1IF);
       T1CONbits.TMR1ON = 0;
       PIR1bits.TMR1IF = 0;
       PIR1bits.T1IF = 0;
       TMR1H = 0x00;
       TMR1L = 0x00;
}
void delay_ms_1()
{
       //start
       TMR1H = 0xFF;                   //Timer 1 para 5mS
       TMR1L = 0xC1;
       T1CONbits.TMR1ON = 1;
       while(!PIR1bits.TMR1IF);
       T1CONbits.TMR1ON = 0;
       PIR1bits.TMR1IF = 0;
       PIR1bits.T1IF = 0;
       TMR1H = 0x00;
       TMR1L = 0x00;
}
void pic_init()
{
        //CMCON = 0b00000111;            //Desliga todos os comparadores

        bank(1);                        //Seleciona banco 1 da memória
        TRISA = 0b00001111;             //RA0 como entrada e as demais como saída
        TRISC = 0b00000000;             //PORTC todos como saída
        bank(0);                        //Seleciona banco 0 da memória

        //TIMER1
        INTCONbits.GIE = 0;             //GIE:Global Habilitar Interrupção global
        INTCONbits.PEIE = 0;            //Habilitar Interrupção periférico

        //PIE1 ? PERIPHERAL INTERRUPT ENABLE REGISTER 1 (ADDRESS: 8Ch)
        PIE1bits.TMR1IE = 0;            //TMR1 Desabilitar estouro do Timer1
       PIE1bits.T1IE = 0;

        //PIR1 ? PERIPHERAL INTERRUPT REGISTER 1 (ADDRESS: 0Ch)
        PIR1bits.TMR1IF = 0;            //TMR1IF: TMR1 Flag de estouro
        PIR1bits.T1IF = 0;

        //T1CON ? TIMER1 CONTROL REGISTER (ADDRESS: 10h)
        T1CONbits.T1CKPS0 = 1;          //T1CKPS1:T1CKPS0: Timer1 Input Clock Prescale Select bits
        T1CONbits.T1CKPS1 = 1;          //T1CKPS1:T1CKPS0: Timer1 Input Clock Prescale Select bits
        T1CONbits.TMR1CS = 0;           //TMR1CS: Timer1 Clock Source Select bit
        T1CONbits.TMR1ON = 0;           //TIMER 1 DESABILITADO
        T1CONbits.TMR1ON = 0;           //TIMER 1 OFF
        Q3 = 0;
        A = 0;
}
void bank(char num)
{
    //Banco 0
    if(num == 0)
    {
        STATUSbits.RP0 = 0;
    }
    //Banco 1
    else if(num == 1)
    {
        STATUSbits.RP0 = 1;
    }
}
void config_AD()
{
    //CONFIGURAÇÃO DO REGISTRADOR ADCON0

    ADCON0bits.ADFM = 1;        //Justificar resultado para direita
    ADCON0bits.VCFG = 0;  //Tensão de referência do pic padrão 5V
    ADCON0bits.CHS0 = 0; //Seleção do canal (AN0)
    ADCON0bits.CHS1 = 0; //Seleção do canal (AN0)
    ADCON0bits.CHS2 = 0; //Seleção do canal (AN0)

    //CONFIGURAÇÃO DO REGISTRADOR ADCON1

    ADCON1bits.ADCS0 = 0; //Clock do conversor analógico digital FOSC/4
    ADCON1bits.ADCS1 = 0; //Clock do conversor analógico digital FOSC/4
    ADCON1bits.ADCS2 = 1; //Clock do conversor analógico digital FOSC/4

    //CONFIGURAÇÃO DO REGISTRADOR ANSEL

    ANSELbits.ANS0 = 1;     //Apenas RA0/RA1 como analógica
    ANSELbits.ANS1 = 1;     //Apenas RA0/RA1 como analógica
    ANSELbits.ANS2 = 0;     //Apenas RA0/RA1 como analógica
    ANSELbits.ANS3 = 0;     //Apenas RA0/RA1 como analógica
    ANSELbits.ANS4 = 0;     //Apenas RA0/RA1 como analógica
    ANSELbits.ANS5 = 0;     //Apenas RA0/RA1 como analógica
    ANSELbits.ANS6 = 0;     //Apenas RA0/RA1 como analógica
    ANSELbits.ANS7 = 0;     //Apenas RA0/RA1 como analógica

    ADCON0bits.ADON = 1; //Conversor Analógico - Digital ligado

    //CONFIGURAÇÃO DO REGISTRADOR PIE1

    PIE1bits.ADIE = 0;      //Interrupçao do para conversor A/D desligado

    //CONFIGURAÇÃO DO REGISTRADOR PIR1

    PIR1bits.ADIF = 0;      //Flag de interrupção para conversor A/D, limpa por software  
}
int read_AD()
{
    int result_AD;                              //Declaração variavel local
    ADCON0bits.GO = 1;                          //Inicia conversão
    while(ADCON0bits.GO);                       //aguarda conversão
    result_AD = (((int)ADRESH)<<8)|(ADRESL);    //Obtem o valor da conversão
    return result_AD;                           //Retorna para result_AD
}
//********************************************************************************************************************************************************

Veja o esquemático do projeto em anexo:

 

 

post-709648-0-59878800-1430044149_thumb.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
  • Solução

Realmente você tem razão: sua rotina está muito ruim

por partes...

0º faça um pisca led avantajado usando uma interrupt do timer0 p.ex. a 1Hz. Conheça o coração pulsante do seu mc (cara que profundo...)

1º defina o circuito. Aquele não está totalmente ruim

2º com o conhecimento adquirido na etapa 0º, faça uma interrupt de p.ex. 60Hz e a cada passada por ela escreva algo num display diferente.

 

não é beeeemm assim!!! é só pra você sintonizar com a coisa e entender o trem. Mas deve dar o resultado esperado

//dentro da interruptif (i==0) {PORTA=1<<0; PORTC=1<<2;}if (i==1) {PORTA=1<<1; PORTC=2<<2;}if (i==2) {PORTA=1<<2; PORTC=3<<2;}if(i++>2) i=0;

deve aparecer 123 no diplay

Use RA0,RA1,RA2 pra varrer os 3 displays (catodo comum) acione um a cada interrupção. RC0(AN4) pra corrente RC51(AN5) pra tensão RC2,3,4,5 como ABCD

3º pra este mc pra corrente você provavelmente vai ter que usar um ampop. Vai ter que que ter que sujar mais um pouco as mãos. Atiny25 já tem ampop interno. Mas vai ter que se desapegar do pic (o que não sei qual seria menos difícil pra você)

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 3 semanas depois...

Realmente você tem razão: sua rotina está muito ruim

por partes...

0º faça um pisca led avantajado usando uma interrupt do timer0 p.ex. a 1Hz. Conheça o coração pulsante do seu mc (cara que profundo...)

1º defina o circuito. Aquele não está totalmente ruim

2º com o conhecimento adquirido na etapa 0º, faça uma interrupt de p.ex. 60Hz e a cada passada por ela escreva algo num display diferente.

 

não é beeeemm assim!!! é só pra você sintonizar com a coisa e entender o trem. Mas deve dar o resultado esperado

//dentro da interruptif (i==0) {PORTA=1<<0; PORTC=1<<2;}if (i==1) {PORTA=1<<1; PORTC=2<<2;}if (i==2) {PORTA=1<<2; PORTC=3<<2;}if(i++>2) i=0;

deve aparecer 123 no diplay

Use RA0,RA1,RA2 pra varrer os 3 displays (catodo comum) acione um a cada interrupção. RC0(AN4) pra corrente RC51(AN5) pra tensão RC2,3,4,5 como ABCD

3º pra este mc pra corrente você provavelmente vai ter que usar um ampop. Vai ter que que ter que sujar mais um pouco as mãos. Atiny25 já tem ampop interno. Mas vai ter que se desapegar do pic (o que não sei qual seria menos difícil pra você)

valeu Isadora, você iluminou minha mente aqui, eu fiz uma gambiarra usando um esquema parecido com o seu separando unidade, centena, dezena etc...

 

veja a gambiarra auhuhahua.

 

#include <stdio.h>

#include <stdlib.h>

#include <p18f4550.h>

#include <delays.h>

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator (HS))

#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))

//Definição linhas de dados do display***********************

#define A            PORTDbits.RD0  //A

#define B            PORTDbits.RD1  //B

#define C            PORTDbits.RD2  //C

#define D            PORTDbits.RD3  //D

//Definição de linhas de endereço do display*****************

#define T1           PORTDbits.RD4  //NPN1

#define T2           PORTDbits.RD5  //NPN2

#define T3           PORTDbits.RD6  //NPN3

#define T4           PORTDbits.RD7  //NPN4

//************************************************************

//************************************************************

//Protótipos de Funções

void aciona_display(int numero, int casa);

void escrever_variavel(int valor);

void escrever_unidade(int unidade);

void escrever_dezena(int dezena);

void escrever_centena(int centena);

void escrever_milhar(int milhar);

int main ()

{

    TRISD = 0x00;

    while(1)

    {   

     escrever_variavel(8458);  

    }

}

void aciona_display(int numero, int casa)

{

    if(casa == 1)

    {

        switch(numero)

        {

            case 0: A=0,B=0,C=0,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 1: A=1,B=0,C=0,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 2: A=0,B=1,C=0,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 3: A=1,B=1,C=0,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 4: A=0,B=0,C=1,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 5: A=1,B=0,C=1,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 6: A=0,B=1,C=1,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 7: A=1,B=1,C=1,D=0,T1=1,T2=0,T3=0,T4=0;

            break;

            case 8: A=0,B=0,C=0,D=1,T1=1,T2=0,T3=0,T4=0;

            break;

            case 9: A=1,B=0,C=0,D=1,T1=1,T2=0,T3=0,T4=0;

            break;

        }

    }

    if(casa == 2)

    {

        switch(numero)

        {

            case 0: A=0,B=0,C=0,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 1: A=1,B=0,C=0,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 2: A=0,B=1,C=0,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 3: A=1,B=1,C=0,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 4: A=0,B=0,C=1,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 5: A=1,B=0,C=1,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 6: A=0,B=1,C=1,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 7: A=1,B=1,C=1,D=0,T1=0,T2=1,T3=0,T4=0;

            break;

            case 8: A=0,B=0,C=0,D=1,T1=0,T2=1,T3=0,T4=0;

            break;

            case 9: A=1,B=0,C=0,D=1,T1=0,T2=1,T3=0,T4=0;

            break;

        }

    }

    if(casa == 3)

    {

        switch(numero)

        {

            case 0: A=0,B=0,C=0,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 1: A=1,B=0,C=0,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 2: A=0,B=1,C=0,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 3: A=1,B=1,C=0,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 4: A=0,B=0,C=1,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 5: A=1,B=0,C=1,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 6: A=0,B=1,C=1,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 7: A=1,B=1,C=1,D=0,T1=0,T2=0,T3=1,T4=0;

            break;

            case 8: A=0,B=0,C=0,D=1,T1=0,T2=0,T3=1,T4=0;

            break;

            case 9: A=1,B=0,C=0,D=1,T1=0,T2=0,T3=1,T4=0;

            break;

        }

    }

        if(casa == 4)

     {

        switch(numero)

        {

            case 0: A=0,B=0,C=0,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 1: A=1,B=0,C=0,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 2: A=0,B=1,C=0,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 3: A=1,B=1,C=0,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 4: A=0,B=0,C=1,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 5: A=1,B=0,C=1,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 6: A=0,B=1,C=1,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 7: A=1,B=1,C=1,D=0,T1=0,T2=0,T3=0,T4=1;

            break;

            case 8: A=0,B=0,C=0,D=1,T1=0,T2=0,T3=0,T4=1;

            break;

            case 9: A=1,B=0,C=0,D=1,T1=0,T2=0,T3=0,T4=1;

            break;

        }

    }//desabilita todos os 4511

}

void escrever_variavel(int valor)

{

     escrever_unidade(valor);

     escrever_dezena(valor);

     escrever_centena(valor);

     escrever_milhar(valor);

}

void escrever_unidade(int unidade)

{

    unidade = ((unidade/1000)%10);//Primeiro digito

    aciona_display(unidade,1),Delay1KTCYx(1);

}

void escrever_dezena(int dezena)

{

dezena = ((dezena/100)%10);//Segundo digito

aciona_display(dezena,2),Delay1KTCYx(1);

}

void escrever_centena(int centena)

{

    centena = ((centena/10)%10);//Terceiro digito

    aciona_display(centena,3),Delay1KTCYx(1);

}

void escrever_milhar(int milhar)

{

    milhar = (milhar%10);//Quarto digito

    aciona_display(milhar,4),Delay1KTCYx(1);

}

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!