Multiplexar display de 7 segmentos em C

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Re: Multiplexar display de 7 segmentos em C

Mensagempor ze2 » 21 Fev 2014 14:40

mostra-se um bom observador amigo. realmente tens toda a razão. Na ânsia de colaborar e participar, não avaliei (como de costume) com profundidade necessária a parte técnica mas apenas a "psicológica" do fonte do amigo. Peço-vos perdão e também para desconsiderar as letras anteriores
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

Re: Multiplexar display de 7 segmentos em C

Mensagempor valecovo » 22 Fev 2014 09:36

Código: Selecionar todos
PORTC=cen>>1; //bit6...1
RA2=cen;//bit0


Pois, isto ainda não percebo......mas é uma questão de estudar, se for necessário!

Pelo que percebi das vossa ajudas, esta parte do código ficará bem assim....
Código: Selecionar todos
while(true)
   {

      digital=1228; //digital=read_adc();
      inte=(unsigned long int)50*digital/1023; //Fica 60
     
      dec=inte%10;   //divide por 10 e atribui o resto para a variável (6).
      inte=inte/10;  //inte = 23
      uni=inte%10;   //uni = 3
      dez=inte/10;   //dez = 2
     
      dezenas();     //Escreve o digito das dezenas
      unidades();    //Escreve o digito das unidades
      decimas();     //Escreve o digito das decimas
   }


ou estarei errado.

Eu fiz um código para LCD (acho que já coloquei acima) e funciona bem, inclusivamente com "float".
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Multiplexar display de 7 segmentos em C

Mensagempor cfreund » 22 Fev 2014 11:09

É isso!

Com float também funciona. Mas é totalmente desnecessário.
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Multiplexar display de 7 segmentos em C

Mensagempor valecovo » 22 Fev 2014 18:53

Ok, está quase.

Obrigado pelas ajudas.

Agora só falta fazer com que o PIC16F676 leia a entrada analógica e funcione correto. Não consigo que ele leia pela portA0 definindo as outras portas com saídas. Fiz assim, mas não está a dar certo. Penso que só a portA4 (MLCR) não pode ser definida como saída. Não sei onde estou errando.
Outra coisa que acontece é que na simulação escreve dois digitos ao mesmo temo, não sei se na realidade depois vai dar certo?
Código: Selecionar todos
//Com display de catodo comum

#include <PIC16F676_Voltimetro_7Segmentos_02.h>

// DEFINIÇÃO E INICIALIZAÇÃO DOS PORTS

#use fast_io(a)
#use fast_io(c)

#byte porta = 0x05
#byte portc = 0x07

unsigned int dez, uni, dec;

int const esp=100;

////////// Apresentar digito das dezenas
void dezenas()
{
   output_high(pin_a1);
   delay_ms(1);
   switch(dez)
   {
      case 0:
      {
         portc = 0b111111;
      }
      break;
      case 1:
      {
         portc = 0b000110;
      }
      break;
      case 2:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b011011;
      }
      break;
      case 3:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b001111;
      }
      break;
      case 4:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b100110;
      }
      break;
      case 5:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b101101;
      }
      break;
      case 6:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b111101;
      }
      break;
      case 7:
      {
         portc = 0b000111;
      }
      break;
      case 8:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b111111;
      }
      break;
      case 9:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b101111;
      }
      break;
   }
   delay_ms(esp);
   output_low(pin_a1);
   output_low(pin_a5);
   delay_ms(1);
}

////////// Apresentar digito das unidades
void unidades()
{
   output_high(pin_a2);
   delay_ms(1);
   switch(uni)
   {
      case 0:
      {
         portc = 0b111111;
      }
      break;
      case 1:
      {
         portc = 0b000110;
      }
      break;
      case 2:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b011011;
      }
      break;
      case 3:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b001111;
      }
      break;
      case 4:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b100110;
      }
      break;
      case 5:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b101101;
      }
      break;
      case 6:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b111101;
      }
      break;
      case 7:
      {
         portc = 0b000111;
      }
      break;
      case 8:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b111111;
      }
      break;
      case 9:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b101111;
      }
      break;
   }
   delay_ms(esp);
   output_low(pin_a2);
   output_low(pin_a5);  //Pino do segmento "g"
   delay_ms(1);
}

////////// Apresentar digito das decimas
void decimas()
{
   output_high(pin_a4);
   delay_ms(1);
   switch(dec)
   {
      case 0:
      {
         portc = 0b111111;
      }
      break;
      case 1:
      {
         portc = 0b000110;
      }
      break;
      case 2:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b011011;
      }
      break;
      case 3:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b001111;
      }
      break;
      case 4:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b100110;
      }
      break;
      case 5:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b101101;
      }
      break;
      case 6:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b111101;
      }
      break;
      case 7:
      {
         portc = 0b000111;
      }
      break;
      case 8:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b111111;
      }
      break;
      case 9:
      {
         output_high(pin_a5);
         delay_ms(1);
         portc = 0b101111;
      }
      break;
   }
   delay_ms(esp);
   output_low(pin_a4);  //Pino de ativacao das decimas
   output_low(pin_a5);  //Pino do segmento "g"
   delay_ms(1);
}

////////// PROGRAMA PRINCIPAL
void main()
{
   unsigned long int digital, inte; // unsigned long int para ADC maior 10 bits
   float tensao;
   dez=0;      //Dezenas
   uni=0;      //Unidades
   dec=0;      //decimas
   
   set_tris_a(0b001001);
   set_tris_c(0b000000);

   porta = 0;  // Reseta portas
   portc = 0;
   
   DISABLE_INTERRUPTS(GLOBAL);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
     
   setup_adc(ADC_CLOCK_INTERNAL);    //enables the a/d module and sets the clock to internal adc clock
   setup_adc_ports(sAN0);      //sets all the adc pins to analog
   setup_adc(adc_clock_div_2);
   set_adc_channel(0);      //the next read_adc call will read channel
   delay_ms(1);            //a small delay is required after setting the channel
     
   while(true)
   {
      digital=read_adc();     //digital=1118;
   
      inte=(unsigned long int)50*digital/1023;
     
      dec=inte%10;   //divide por 10 e atribui o resto para a variável.
      inte=inte/10;  //inte =
      uni=inte%10;   //uni =
      dez=inte/10;   //dez =
     
      decimas();     //Escreve o digito das decimas
      unidades();    //Escreve o digito das unidades
      dezenas();     //Escreve o digito das dezenas
   }
}
/////////// FIM DO PROGRAMA



Onde deveria escrever, não escreve e repete o digito. Para a 05,9V:
Aqui devia escrever as décimas, escreve as dezenas no lugar das dezenas e das unidades.
Vol02.jpg


Aqui devia escrever as dezenas, escreve as décimas no lugar das unidades e das décimas.
Vol01.jpg


Aqui escreve as unidades no lugar das dezenas e das décimas.
Vol03.jpg
Você não está autorizado a ver ou baixar esse anexo.
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Multiplexar display de 7 segmentos em C

Mensagempor andre_luis » 22 Fev 2014 19:42

Isso não resolve o seu problema, mas percebi que você não preve o tratamento para os casos onde há "zero á esquerda", o que significa que no caso do valor 1,2 seria escrito 01,2. Sugiro incluir as seguintes linhas:

Código: Selecionar todos
     decimas();                                                                       //Escreve o digito das decimas
     unidades();                                                                      //Escreve o digito das unidades
     if ( dez == 0 ) { /* NAO ESCREVE NADA - DEIXA EM BRANCO */ } else dezenas();     //Escreve o digito das dezenas



+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Multiplexar display de 7 segmentos em C

Mensagempor valecovo » 24 Fev 2014 13:07

Olá

O problema não é escrever o zero. O problema é não escrever onde deveria e escrever dois dígitos ao mesmo tempo.
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Multiplexar display de 7 segmentos em C

Mensagempor andre_luis » 24 Fev 2014 22:19

valecovo escreveu:O problema não é escrever o zero. O problema é não escrever onde deveria e escrever dois dígitos ao mesmo tempo.


Pelo comportamento acima, me parece que a lógica de acionamento do seu circtuito pode estar invertida.
Repare que os dígitos acendem aos pares, ficando apagado justamente o que deveria estar aceso.

Faz um teste agora, mas trocando o output_low pelo output_high e vice-versa, como indicado abaixo:

Código: Selecionar todos
    ////////// Apresentar digito das dezenas
    void dezenas()
    {
       output_low(pin_a1);
      ...
       output_high(pin_a1);
    }
    ////////// Apresentar digito das unidades
    void unidades()
    {
       output_low(pin_a2);
      ...
       output_high(pin_a2);
    }
    ////////// Apresentar digito das decimas
    void decimas()
    {
       output_low(pin_a4);
       ...
       output_high(pin_a4);  //Pino de ativacao das decimas
    }
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Multiplexar display de 7 segmentos em C

Mensagempor ze2 » 25 Fev 2014 11:17

tá bão. não agrego muita coisa mas ...
perdi (ou ganhei) alguns minutos fazendo isso nesta madrugada de insônia. pode não lhe ser totalmente inútil. e também pra algum incauto navegante do futuro (se voce estiver lendo isso aí pelos anos 2080, pode ser que eu não esteja mais entre vocês). note-se o minimalismo extremo. não estão representados resistores e transistores drivers. no fonte, (100% c, extremamente simples, disponíveis mediante súplica) estão os conceitos que mencionei. ocupou cerca de 340 bytes.

https://imageshack.com/a/img833/7941/u3ky.gif
u3ky.gif


salve a figura abaixo. renomeie para figura.zip. abra com o 7-zip. terás ao teu dispor os arquivos que poderás rodar na simulação.

http://imageshack.com/a/img401/2365/tvcf.jpg
tvcf.jpg


ah sim. usei email fake no imageshack. acho que as imagens só duram 30 dias...bem antes de 2080...enfim
acho que o gif roda uma vez só.. depois eu vejo lemcasa..

abç
Você não está autorizado a ver ou baixar esse anexo.
Editado pela última vez por andre_luis em 27 Fev 2014 19:27, em um total de 1 vez.
Razão: imagem copiada para a base local
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

Re: Multiplexar display de 7 segmentos em C

Mensagempor valecovo » 25 Fev 2014 17:53

Amigo Ze, já estou a suplicar. Se me puder enviar o ficheiro em C para valecovo@hotmail.com ou postar aqui agradeço. Gostava de ver onde estou falhando.

Já agora, utilizar 3 displays independentes ou utilizar um de 4 dígitos fará muita diferença na simulação??? E na realidade????

Baixei a figura, conforme instruções, e funciona.

Estou a aprender!

Um abraço pelas ajudas

José Silva
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Multiplexar display de 7 segmentos em C

Mensagempor andre_luis » 25 Fev 2014 19:40

José,



Fez o teste que eu sugeri mais acima ?

O problema dos caracteres duplicados parece estar relacionado á lógica de varredura dos displays, que está enviando [110 , 101 , 011] para os transistores ao invéz de [001 , 010 , 100] que seria o correto.


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Multiplexar display de 7 segmentos em C

Mensagempor ze2 » 26 Fev 2014 08:32

sabia que ias gostar. teu pedido é uma ordem. Infelizmente (ou felizmente) está em hitech-c e com acesso direto ao hw do pic. Por isso talvez não te seja (a ti) totalmente útil. Caso queiras entender bit a bit, deverás passar os olhos pelo datasheeet. Por outro lado, creio que não terás dificuldade em portar pro teu compilador. Neste caso, me inclua fora.
Otimizei um pouco mais. Ocupou 274 bytes. Estou curioso pra ver quanto vai ocupar com outro compilador.
Código: Selecionar todos
/* Programa para uControlador PIC16F676 voltimetro */
/* 25/02/2014 - V00.001A */
#include <pic.h>
#define tm1h   0xf6 //int timer1 200Hz @ 4MHz
#define tm1l   0x3c
//configuração = proteção do código & 4Mhz & ...
__CONFIG(CP_OFF & MCLRE_OFF & FOSC_INTRCIO & PWRTE_ON & WDTE_OFF & BOREN_ON);
__EEPROM_DATA('V','o','l','t',' ','Z','e',' ');
__EEPROM_DATA('V','0','0','.','0','0','1','A');
//***************************************************************
unsigned char dig[3],k,i,tmp;
//***************************************************************
void delay(unsigned char dl) //dl*2,5ms
{
tmp=dl;
while(tmp);
}
/**************************************************************************/
unsigned int adc_read(void)
{
 ADCON0 = (3 << 2) | 0x83;  // enable ADC, fosc/32
 while(GO_nDONE)
  continue; // wait for conversion complete
return ADRESH*256 + ADRESL;
}
unsigned char const tabela[10]={
   0b00111111,    //Dígito 0
   0b00000110,    //Dígito 1
   0b01011011,    //Dígito 2
   0b01001111,    //Dígito 3
   0b01100110,    //Dígito 4
   0b01101101,    //Dígito 5
   0b01111101,    //Dígito 6
   0b00000111,    //Dígito 7
   0b01111111,    //Dígito 8
   0b01101111     //Dígito 9
        };
//************************************************************
static void interrupt
timer1_int(void)
{
TMR1IF=0;  //zera flag timer1
TMR1H=tm1h;  //restaura 200Hz interrupt
TMR1L=tm1l;
tmp--;
PORTA = 0b11111111;   //apaga display
PORTC=tabela[dig[i]];
RA5=tabela[dig[i]]>>6; //bit6
PORTA& = ~k;
i++;   //na próxima vez, próximo valor indexado e
k<<=1;   //próximo dígito
if (i>2) {i=0; k=1;}  //redefinição de variáveis
}
//***************************************************************
/* coloca o valor nos displays */
//***************************************************************
void dsp7(unsigned int dado)
{
dig[0]=dado/100;
dig[1]=(dado/10)%10;
dig[2]=dado%10;
}
//**********************************************************************
//***************INICIO DO PROGRAMA PRINCIPAL***********
//**********************************************************************
void main(void)
{
unsigned int a=000;
TRISC=0b000000;   //segmentos
TRISA=0b00010000;  //RA4=enrada analógica
//WPUA= 0b111111;  //pullup em tudo
ANSEL=0b00001000;  //AN3=entrada de voltagem
CMCON=0xff;   //entradas do comparador = digital
ADFM=1;    //p/ 10 bits deslocados p/ direita
VCFG=0;    //Ref.= VDD
ADCON1=0b00010000; //ad=fosc/8
TMR1H=tm1h;   // int. 200Hz
TMR1L=tm1l;   //   "
TMR1IF=0;   //zera flag timer1
TMR1IE=1;   //hab. int. timer1
PEIE=1;
T1CON=0b00010101;  // prescaler /2 fosc/4 timer1 on
GIE=1;    //hab int.
//while(a<11) {dsp7(a);a++;delay(30);} //teste
//while(a<101) {dsp7(a);a+=10;delay(30);} //teste
//while(a<1001) {dsp7(a);a+=100;delay(30);} //teste
//-------------loop------------------------
for (;;)
{
a=adc_read();
dsp7(a);
delay(50);
}
//------------------------------------------
}

Nota que o circuito está semipronto de acordo com tuas necessidades. Para ajuste/calibração, basta atuar no trimpot. Existe a possibilidade de se calibrar via sw gravando na eeprom.Isso evitaria o uso de trimpot. No entanto ainda não é o momento pra isso.
E quanto aos displays não fará diferença em ambos aspectos. Dica: caso desejes usar o meu.hex como está ao invés de criar teu próprio, sugiro usar um transistor pnp nos catodos comuns
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

Re: Multiplexar display de 7 segmentos em C

Mensagempor valecovo » 26 Fev 2014 18:40

andre_teprom, já fiz tanta alteração que já estou a ficar maluco, mas acho que o problema não está aí porque se você ver na imagem o circuito activo é um e os dígitos activados são os outros, não sei se percebeu o que eu quis dizer!

Ze, este código para mim é chinês!!!!!!!!!!!!!!!!! Mas vou tentar entender.....
Mas considerando que funciona, só preciso de saber quais os pinos do CI correspondentes no display, para fazer a montagem. Fala-me em transístores PNP com cátodos!!! Mas os transístores PNP não deverão ser usados com displays de ânodo comum?????? É que penso que os displays que tenho são todos de cátodo comum e neste caso tenho que utilizar os transístores NPN, ou estarei errado???? A programação terá de ser diferente consoante o caso, não é?????

Bom, e agora ainda vou ter outra árdua tarefa! Ainda vou ter que gravar o PIC e vai ser a primeira vez que o vou fazer. Não sei como vai correr....
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Multiplexar display de 7 segmentos em C

Mensagempor ze2 » 27 Fev 2014 07:57

Amigo Silva, infelizmente (ou felizmente) não tenho intimidade com as "facilidades" de teu amado compilador. O que vês são apenas, como te disse, maneiras de aceder directamente os ciruitos lógicos internos do pic os quais deverão ser percebidos com relativa profundidade. As demais funções são C em sua total pureza. Sobre tais temas, terei dificuldade em te dar apoio. Nada mais posso comentar sobre isso.
Os pinos do display são os do ciruito que te passei, oras. Caso não tenhas notado, no programa estão como PORTA, PORTC e RA5
No caso do pnp: sim pnp mesmo. pra isso basta ligar o coletor no gnd e emissor nos catodos. A base nos pinos obviamente. Nível zero fá-lo-á conduzir. Podes perfeitamente usar npn. Para tal basta alterar a programação para PORTA| = k; Quando perceberes isso, PORTAs se abrirão para ti! No hw passam a ser imperativos resistores nas bases.
Creio que não terás dificuldades em gravar o pic. Caso as tenhas, não te acanhes em contactar.

Estou a ter dificuldades em traduzir para teu idioma. Em algum eventual novo contacto, se não te importares, usarei o meu.(rs. estou a brincar...)

De um certo ponto de vista, realmente me sinto "chinês" pois noto que sou o único idiota que escreve asneiras offtopic. Talvez instinto desrrobotizante, [des]humanizante, seilá e tal.... Num outro forum, moderador (desocupado) apagava isso... sério!. enfim... é meu estilo literário e to nem aí co 6. kk.
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

Re: Multiplexar display de 7 segmentos em C

Mensagempor valecovo » 27 Fev 2014 16:08

Olá
ze, agradeço-lhe do fundo do coração as ajudas que me tem dado neste forum.

Eu vou tentar gravar o PIC com um gravador manhoso que estou montando. Se tiver algumas dificuldades, depois volto a chatear.

Quanto ao código vou estudá-lo e tentar perceber como as coisas acontecem. Talvez daqui a uns dias volte a pedir explicações. Se isso acontecer, peço desde já a sua compreensão.

Quanto à linguagem, apesar do meu "tradutor" não ser grande coisa, não há problema. Estava a brincar. Esteja à vontade.

Sobre as ligações do PIC ao display, na altura não me lembrei da figura. Vou ver a figura e passar o esquema .

Mas agora surgiu-me outra dúvida sobre os transístores. Você diz que eles activam com nível zero?!?!?!?!? Mas, segundo os meus conhecimentos de electrónica, a diferencia de potencial entre a base e emissor deverá ser de 0,6V para ele conduzir. No caso do PNP, 0,6V inferior, o que, vendo bem as coisas, deve estar correto. E se você o diz, não duvido.
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Multiplexar display de 7 segmentos em C

Mensagempor ze2 » 27 Fev 2014 17:16

Sem problema se duvidares. A dúvida é a sala de estar da sabedoria. FIco feliz por teres percebido o facto dos 0,6V 'base abaixo'. E ainda mais por teu [raro] bom senso de gratidão!
Complementando: se fores ligar o pnp com emissor nos catodos e colector no gnd, podes ligar directamente a base nos pinos desde que não te esqueças de colocar resistores nos segmentos. Esta seria a chamada configuração 'seguidor de emissor'
Sucessos meu novo velho amigo!
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

AnteriorPróximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x