Display 7 Segmentos Multiplexado

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Display 7 Segmentos Multiplexado

Mensagempor frodrigorocha » 07 Ago 2009 09:24

Olá amigos, preciso de uma ajuda com um display de 7 segmentos, preciso coloar o um valor de 8 bits em 3 displays fazendo multiplexação, minha pergunta é a seguinte: qual a farma mais coerente para essa operação? abaixo segue fragmento do meu programa

valor2=(valor1/100);
output_high(disp1);
output_b(tabela[valor2]);
delay_ms(10);
output_low(disp1);
delay_ms(10);

valor3=(valor1%100);
output_high(disp2);
output_b(tabela[valor3]);
delay_ms(10);
output_low(disp2);
delay_ms(10);

valor4=(valor1%10);
output_high(disp3);
output_b(tabela[valor4]);
delay_ms(10);
output_low(disp3);
delay_ms(10);

Sei que o código é precário, faz uma semana que estou estudando C, mais um dia chego lá...

Abraço,
Fábio Rocha.
frodrigorocha
Bit
 
Mensagens: 19
Registrado em: 06 Ago 2009 09:05
Localização: Canoas - RS

Mensagempor _blackmore_ » 07 Ago 2009 10:08

frodrigorocha

vou falar para vc fazer uma pesquisa aqui no fórum ... a pouco tempo apareceu um camarada que fez o mesmo questionamento ...

abrax!
_blackmore_
Dword
 
Mensagens: 1397
Registrado em: 28 Set 2008 13:26

Mensagempor fabim » 07 Ago 2009 10:09

Primo, o bom é o seguinte.
Você ter um array de 3 bytes no seu caso.
Sendo que cada byte equivale ao Cent Dez Uni.

void interrupt(void){

IF(estouro timer 0){
**************************************
Aqui dentro você cria uma rotina que simplesmente pegue o byte equivalente a centena e jogue no dsplay1..
Proxima interrupt, pegue o byte equivalente a dezena, e jogue no display2
Proxima interrupt, pegue o byte equivalente a unidade, e jogue no display3
se display==3"ou dois se contar de 0..2"{display=0}.
*******************************************************

Observe que você criou uma máquina, que independente de estar executando uma rotina no main, ou um calculo ou seja o que for.
Você simultâneamente vai estar escrevendo nos displays.

OBS> quer trocar os valores dos displays, no main ou em uma sub rotina, você escreve diretamente no array global de 3 bytes, e a interrupção por timer0 vai se encarregar de jogar os valores nos displays.

Ou seja.:
Estude sobre interrupção, Sobre interrupção do TMR0, Sobre configurar o timer0 para controlar o tempo de estouros.
Mais como saber qual o tempo entre estouros ?

Bom os zói dos seres humanos, na sua maioria.
Se uma fonte de luz tiver piscadas com intermitência não menor que uns 25hz, o olho não consegue saber que a luz esta piscando por causa da persistencia de captura.
Sendo assim, você sabe que cada display, tem que ter uma amostragem na média de tempo de:
1Segundo/25piscadas.. = 40mS.
Ou seja dentro de 40mS, você deve amostrar display1, 2 , 3, e continuar o loop infinito.

Bom se eu tenho um tempo entre frames displays de 40mS, e tenho 3 displays, sendo assim o tempo de persistencia de cada display é de !!

0.040 / 3displays.

13mS +/-.....

Código: Selecionar todos
 


OBS:erve!!

T=  13mS      13mS     13mS     13mS     13mS    13mS
| display1  |display2 |display3|display1|display2|display3|
|________ |_______|______ |            |            |
-------------|_______|______________|             |
------------------------|______________________|



OLHE no T.
do display1, até o proximo display1, contando entre bordas de subida de amostragem qual é o tempo ?
3 * 13mS = 39mS certo ?

Ou seja, eu ja havia dito que frequencia menor que 25hz o zóio pode perceber as piscadas alem de ficar fei pra burro.
Se eu configurei o tempo do tmr0 de forma que o tempo entre estouros fique por volta de 13mS, eu to tranquilo.
Resumindo, os requisitos estão completos...

Proximo passo.
Veja que, de T display1,,,,,,,,display1 novamente eu tenho uma montante de 39mS, porem este led fica aceso apenas em 39/3, ou seja 13mS.
Ou seja, tu criou um PWM com Ton de 33.3% on state e 66.6%of state.
Para 3 displays, e tempo de 13mS você não precisa fazer compensação de corrente dos led´s.. Porêm quando você fala em frequencia alta aí a historia muda.
Se o led = 15mA por exemplo aceso direto.
Para um PWM com 33% TON, rapidamente tu leva a mente a considerar que a Corrente de pulso deve Ser 3* maior para ficar com mesma intensidade.
Porêm o buraco é mais embaixo, pois tem que levar em consideração alguns fatores.
No datasheet do display, diz que a suportabilidade de máxima corrente em 1mS é de 35mA, só que os seus calculos disseram que precisa de 80mA pico!> e aí como fica ? o Ton esta menor que 1mS ? mesmo estando menor os ditos 80mA estão de acordo com a corrente de curva do componente ? a frequencia de amostragem do led estão de acordo com o dito pelo datasheet ?

Ou seja.. use display LCD... só mandar os bytes ele se vira com o resto..rsrs

Abraços

Fabim
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor rebelk » 07 Ago 2009 18:31

eu faço assim !


// Este programa para a fonte variavel de 0 a 30v
#include <16f876.h>
#device adc=10 // Configura o compilador para conversor A/D de 10 bits
#use delay(clock=5000000)
#fuses XT,NOWDT,PUT,NOPROTECT
#include <regs_16f87x.h>

#define disp_tensao_u pin_b0 // saidas para a multiplexagem dos displays de 7 seg
#define disp_tensao_d pin_b1
#define disp_tensao_c pin_b2
#define disp_tensao_m pin_b3

#define disp_corrente_u pin_b4 // saidas para a multiplexagem dos displays de 7 seg
#define disp_corrente_d pin_b5
#define disp_corrente_c pin_b6

// #define liga_display output_high(disp_tensao_u ) // seta o pino scl

#define ponto_decimal 0b10000000
float teste=0;
int16 valor_ad=0;

byte valor_tencao[5];
byte valor_corrente[5];
byte digitos_1[5]; //matriz para tenção
byte digitos_2[5]; //matriz para corrente

int bayte_display=0;
int dig=0;
boolean estado=0;
float constante_tensao=0.0298; // 30v / 1016 = 0.029
float constante_corrente=0.00488;

//**********************************************************************
//**********************************************************************
#int_timer0
trata_timer()
{

output_low(disp_tensao_u);
output_low(disp_tensao_d);
output_low(disp_tensao_c);
output_low(disp_tensao_m);

output_low(disp_corrente_u);
output_low(disp_corrente_d);
output_low(disp_corrente_c);

switch(dig)
{

case 0:

output_c(digitos_1[3]);
output_high(disp_tensao_u);
break;

case 1:

output_c(digitos_1[2]);
output_high(disp_tensao_d);
break;
case 2:

output_c(digitos_1[1]);
output_high(disp_tensao_c);
break;

case 3:

output_c(digitos_1[0]);
output_high(disp_tensao_m);
break;

case 4:

output_c(digitos_2[2]);
output_high(disp_corrente_u);
break;

case 5:

output_c(digitos_2[1]);
output_high(disp_corrente_d);
break;

case 6:

output_c(digitos_2[0]);
output_high(disp_corrente_c);
break;

}




dig++;
if(dig > 6) dig=0;
set_timer0(200); // interrupção a cada 15ms 50535 // 62035
estado=!estado; // faredura é de 50hz
output_bit(pin_b7,estado); // so para endicar a frequencia de varredura
// no pino b7

}
//**********************************************************************
//**********************************************************************
int8 ver_digito( int8 a)
{
switch(a)
{
case 0:

a=0b00111111; // 0
break;

case 1:

a=0b00000110; // 1
break;

case 2:

a=0b01011011; // 2
break;

case 3:

a=0b01001111; // 3
break;

case 4:

a=0b01100110; // 4
break;

case 5:

a=0b01101101; // 5
break;

case 6:

a=0b01111100; // 6
break;

case 7:

a= 0b00000111; // 7
break;

case 8:

a= 0b01111111; // 8
break;

case 9:

a= 0b01101111; // 9
break;

default: a=0b00111111; // 0
break;
}
return(a);
}

//**********************************************************************
//**********************************************************************
// converte o conteudo da matriz(valor_display) que é uma string em valores
// de 0.000v a 30.00v grgavados matriz (digitos)

converte_tensao()
{
byte q_matriz=0; // indica qual elemento da matriz sera lido
byte a=0;
byte vezes=0;
byte menos=0; // variavel que indica que foi encontrado o ponto e decido
// uma matriz;

while(vezes <= 5 )
{
a=(valor_tencao[q_matriz]-0x30);

if(a>9) // se o valor de (a) maior que 9 chegou no ponto decima
{
q_matriz--; // volta uma matriz e coloca o ponto decimal
digitos_1[q_matriz]=( digitos_1[q_matriz] | ponto_decimal ); // coloca o ponto decimal
q_matriz++;
menos=1;
}

else
{
digitos_1[q_matriz-menos]=ver_digito(a);
}
vezes++;
q_matriz++;
}

}



//**********************************************************************
//**********************************************************************
// converte o conteudo da matriz(valor_display) que é uma string em valores
// de 0.000v a 30.00v grgavados matriz (digitos)

converte_corrente()
{
byte q_matriz=0; // indica qual elemento da matriz sera lido
byte a=0;
byte vezes=0;
byte menos=0; // variavel que indica que foi encontrado o ponto e decido
// uma matriz;

while(vezes <= 5 )
{
a=(valor_corrente[q_matriz]-0x30);

if(a>9) // se o valor de (a) maior que 9 chegou no ponto decima
{
q_matriz--; // volta uma matriz e coloca o ponto decimal
digitos_2[q_matriz]=( digitos_2[q_matriz] | ponto_decimal ); // coloca o ponto decimal
q_matriz++;
menos=1;
}

else
{
digitos_2[q_matriz-menos]=ver_digito(a);
}
vezes++;
q_matriz++;
}

}




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



main()
{

setup_ADC_ports (RA0_analog);
setup_adc(ADC_CLOCK_INTERNAL );
set_adc_channel(0);

set_timer0(50); // carrega o timer 0 com 155
setup_timer_0 ( RTCC_INTERNAL );// configura o timer 0 para clock interno
enable_interrupts (global | int_timer0); // habilita interrupções


while (true)
{
set_adc_channel(0);
delay_us(20);
teste=((read_adc() & 0x3f8) * constante_tensao); // 0x3f8=1111111000b
sprintf(valor_tencao,"%02.3f",teste);// transforma o conteud // em uma string e coloca na matriz(valor_display)
converte_tensao();

set_adc_channel(1);
delay_us(20);
teste=( read_adc() * constante_corrente );
sprintf(valor_corrente,"%02.2f",teste);// transforma oy
converte_corrente();
delay_ms(100);



}
}
rebelk
Byte
 
Mensagens: 301
Registrado em: 15 Nov 2006 20:16


Voltar para PIC

Quem está online

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

x