Página 1 de 1

como programar o 8051 pra controlar 8 displays de 7 seg?

MensagemEnviado: 06 Jun 2013 21:56
por renan-papaco
poderiam me ensinar um "passo-a-passo" de como fazer isso? por onde começar?

Re: como programar o 8051 pra controlar 8 displays de 7 seg

MensagemEnviado: 07 Jun 2013 08:17
por andre_luis
Renan,


O primeiro passo é a modelagem funcional do programa.
Você precisa dividir em camadas, cada uma acessando a subsequente :

1 ) Mapa de memória dos Segmentos.
2 ) Escrever em 1 display, baseado no mapa acima.
3 ) Escrever o valor nos 8 Displays, acessando a rotina acima.

etc...


+++

Re: como programar o 8051 pra controlar 8 displays de 7 seg

MensagemEnviado: 07 Jun 2013 08:40
por brasilma
O mesmo que o André já colocou apenas escrito diferente...

Com certeza você deve estar pensando em multiplexação.

O sistema é assim:

Uma rotina de contagem de tempo normal, com hora, minuto, e segundo rodando.

Uma tabela com os bytes (bits) correspondentes as "imagens" dos dígitos 0-9.

Uma área de memória para guardar estas imagens (dos bytes correspondentes aos dígitos da hora).

Uma rotina que a partir de cada digito da hora pega na tabela a imagem correspondente e escreve na área de memória, que é varrida por uma rotina que coloca os caracteres na saída para os displays, juntamente com os bits correspondentes a posição do display (em outro port).

Re: como programar o 8051 pra controlar 8 displays de 7 seg

MensagemEnviado: 10 Jun 2013 16:19
por ze
apesar do amiguinho não ter intimidade com palavras mágicas, tento superar isso. por ele agradeço aos 2 bons amigos, mas se eu fosse ele, teria dificuldades em agrad... ops entender o mencionado. nada pessoal claro. mas como estou aqui não pra ajudar mas pra confundir ainda mais, vejamos este complemento que é a lesma lerda que os amigos disseram mas... do meu jeito amalucado (que as vezes nem eu me entendo)

permita-me amigo marcelo usar algumas letras tuas...
"Uma área de memória para guardar estas imagens (dos bytes correspondentes aos dígitos da hora)."
Código: Selecionar todos
unsigned char dig[8];

"Uma rotina que a partir de cada digito da hora pega na tabela a imagem correspondente e escreve na área de memória, "
Código: Selecionar todos
void _2display7seg_apenas(unsigned char d) //os d+ vc se vira
{
dig[1]=d/10;
dig[0]=d%10;
}

"que é varrida por uma rotina que coloca os caracteres na saída para os displays,"
Código: Selecionar todos
#define PORTSEGMENTOS PA

" juntamente com os bits correspondentes a posição do display (em outro port)."
Código: Selecionar todos
#define PORTCATODOS PB

"Uma tabela com os bytes (bits) correspondentes as "imagens" dos dígitos 0-9."
Código: Selecionar todos
unsigned char const tabela[]= //veja a sintaxe do seu compilador pode ser const,flash,rom...
{
~0b11000000,//0 ... acende em 1
~0b11111001,//1
~0b10100100,//2
.
.
.
~0b10010000,//9
}


Código: Selecionar todos
unsigned char i, k=1; //globais
void interrupt //veja a sintaxe do seu compilador
timer_int(void)
{
//...reajusta hw
PORTCATODOS=0xff;//melhor apagar primeiro
PORTSEGMENTOS=tabela[dig[i]];//localiza desenho do número
PORTCATODOS=~k; //cada display - catodo comum. obviamente deves colocar um NPN portanto não precisa inverter o k
i++;//na proxima passada, proximo dígito e
k<<=1;//próximo display. o pulo do gato da varredura "Com certeza você deve estar pensando em multiplexação."
if (i>7)    {
      i=0;//só 8 digitos
      k=1;//volta ao 1º display
      }
//...faz + coisas
}


Código: Selecionar todos
void main (void)
{
unsigned char x;
//...ajuste o hw para interrupção de um timer qualquer. 8 displays? uns 400Hz
dig[7]=1;dig[6]=2;dig[5]=3;dig[4]=4;//...
for (;;)
{
...//
_2display7seg_apenas(x++)
//...
}
}

espero não ter atrapalhado. mas como sempre, pode não ser totalmente inútil pra algum incauto navegante errante do futuro

Re: como programar o 8051 pra controlar 8 displays de 7 seg

MensagemEnviado: 10 Jun 2013 22:56
por renan-papaco
lellis escreveu:apesar do amiguinho não ter intimidade com palavras mágicas, tento superar isso. por ele agradeço aos 2 bons amigos, mas se eu fosse ele, teria dificuldades em agrad... ops entender o mencionado. nada pessoal claro. mas como estou aqui não pra ajudar mas pra confundir ainda mais, vejamos este complemento que é a lesma lerda que os amigos disseram mas... do meu jeito amalucado (que as vezes nem eu me entendo)

permita-me amigo marcelo usar algumas letras tuas...
"Uma área de memória para guardar estas imagens (dos bytes correspondentes aos dígitos da hora)."
Código: Selecionar todos
unsigned char dig[8];

"Uma rotina que a partir de cada digito da hora pega na tabela a imagem correspondente e escreve na área de memória, "
Código: Selecionar todos
void _2display7seg_apenas(unsigned char d) //os d+ vc se vira
{
dig[1]=d/10;
dig[0]=d%10;
}

"que é varrida por uma rotina que coloca os caracteres na saída para os displays,"
Código: Selecionar todos
#define PORTSEGMENTOS PA

" juntamente com os bits correspondentes a posição do display (em outro port)."
Código: Selecionar todos
#define PORTCATODOS PB

"Uma tabela com os bytes (bits) correspondentes as "imagens" dos dígitos 0-9."
Código: Selecionar todos
unsigned char const tabela[]= //veja a sintaxe do seu compilador pode ser const,flash,rom...
{
~0b11000000,//0 ... acende em 1
~0b11111001,//1
~0b10100100,//2
.
.
.
~0b10010000,//9
}


Código: Selecionar todos
unsigned char i, k=1; //globais
void interrupt //veja a sintaxe do seu compilador
timer_int(void)
{
//...reajusta hw
PORTCATODOS=0xff;//melhor apagar primeiro
PORTSEGMENTOS=tabela[dig[i]];//localiza desenho do número
PORTCATODOS=~k; //cada display - catodo comum. obviamente deves colocar um NPN portanto não precisa inverter o k
i++;//na proxima passada, proximo dígito e
k<<=1;//próximo display. o pulo do gato da varredura "Com certeza você deve estar pensando em multiplexação."
if (i>7)    {
      i=0;//só 8 digitos
      k=1;//volta ao 1º display
      }
//...faz + coisas
}


Código: Selecionar todos
void main (void)
{
unsigned char x;
//...ajuste o hw para interrupção de um timer qualquer. 8 displays? uns 400Hz
dig[7]=1;dig[6]=2;dig[5]=3;dig[4]=4;//...
for (;;)
{
...//
_2display7seg_apenas(x++)
//...
}
}

espero não ter atrapalhado. mas como sempre, pode não ser totalmente inútil pra algum incauto navegante errante do futuro


obrigado pela ajuda viu? apesar de eu ainda não ter entendido muito bem... eu sou muito burro pqp...

afinal...oq esses operadores significam?
dig[1]=d/10;
dig[0]=d%10;
pra cada digito eu coloco um operador diferente?

Re: como programar o 8051 pra controlar 8 displays de 7 seg

MensagemEnviado: 11 Jun 2013 21:45
por ze
vai chover. aquilo é inerente à linguagem c não tem relação [direta] com sua inquietação. tentemos então ir além das suas expectativas...

pegue um fôlego antes de ler...
dig[7],...dig[0] são vetores (ou matriz) predefinidos em unsigned char dig[8] ou seja defini oito variáveis 8 bits na ram. Preferi matriz por ser facilmente acessivel por um index unsigned char i o qual é incrementado sincronizadamente com o deslocamento a esquerda (k<<=1) da unsigned char k (cujo valo inicial é 1) em cada passada pela interrupção do timer.
No exemplo usei apenas 2 elementos da matriz dig[0] e dig[1]. Se montar o hw direito, note que dig[1] e dig[0] SEMPRE serão "apontados" para os displays 1 e 0. ufa...

mais um fôlego...
Mas falemos agora do dig[7]. vamos colocar "1" no display 7. É só fazer dig[7]=1. o que ocorre? note que ao passar pela 8ª vez na interrupção o i++ (que começa com zero) incrementou 7 vezes e vale ...7! e o k<<=1 (que começa com 1) deslocou pra esquerda 7x e vale 0b10000000 (essa é + difícil). Se i=7, ao fazer PORTSEGMENTOS=tabela[dig[i]] portanto dig[i]=dig[7]=1 é o mesmo que PORTSEGMENTOS=tabela[1]. Note que [1] é o segundo item da tabela (começa com zero) é o mesmo que PORTSEGMENTOS=0b00110000 é o mesmo que PB=0b0110000 (note os segmentos A e B acesos em nivel alto). Neste momento único, o k vale 0b10000000 e este é aplicado em outro port PORTCATODOS=k potanto apontando para o display 7. Perceba que é 1 e não 0 pois o PORTCATODOS geralmente aciona um NPN ou uln2003 que p.ex. estão conectados aos catodos comuns dos displays. ufaa..

agora sim cheguemos onde voce quer... coloquemos o valor d=34 nos primeiros displays
dig[1]=d/10 = 34 dividido por 10 = 3,4 por sorte [ou azar] seu, este valor não pode ser contido dentro de um unsigned char. só cabe a parte inteira 3 portanto dig[1]=3 = dezena
dig[0]=d%10 = resto inteiro (a parte que é incabivel no unsigned char lembra?) da divisão de 34/10 o mesmo que d-dig[1]*10 = 34-3*10 = .....4! portanto dig[0]=4 unidade
Aqui um detalhe importante: d nunca deverá ser maior que 99... bom tente descobrir porquê.
Se dig[1]=4 e dig[0]=3 basta aplicar a complexa teoria acima do dig[7] e sua mente se abrirá... espero.

Complicado pra sua cabecinha? faça = ao amigo andré falou e contente-se por hora a "desenhar" algo no display ligando-o em um port qualquer. Breve estarás dominando o micromundo

Não se preocupe em se sentir pouco dotado intelectualmente de vez em quando (eu me sinto o tempo todo). A dúvida é a sala de estar da sabedoria. E eu nem na varanda estou ainda. Ainda tenho medo de vetores, arrays, matriz, ponteiro... sério...até hoje num entendo esta poha direito
aviso que tomei umas cachaças e eventualmente algo que eu disse pode parecer COM sentido.

ah e obrigado por dizer obrigado

Re: como programar o 8051 pra controlar 8 displays de 7 seg

MensagemEnviado: 12 Jun 2013 14:45
por renan-papaco
lellis escreveu:vai chover. aquilo é inerente à linguagem c não tem relação [direta] com sua inquietação. tentemos então ir além das suas expectativas...

pegue um fôlego antes de ler...
dig[7],...dig[0] são vetores (ou matriz) predefinidos em unsigned char dig[8] ou seja defini oito variáveis 8 bits na ram. Preferi matriz por ser facilmente acessivel por um index unsigned char i o qual é incrementado sincronizadamente com o deslocamento a esquerda (k<<=1) da unsigned char k (cujo valo inicial é 1) em cada passada pela interrupção do timer.
No exemplo usei apenas 2 elementos da matriz dig[0] e dig[1]. Se montar o hw direito, note que dig[1] e dig[0] SEMPRE serão "apontados" para os displays 1 e 0. ufa...

mais um fôlego...
Mas falemos agora do dig[7]. vamos colocar "1" no display 7. É só fazer dig[7]=1. o que ocorre? note que ao passar pela 8ª vez na interrupção o i++ (que começa com zero) incrementou 7 vezes e vale ...7! e o k<<=1 (que começa com 1) deslocou pra esquerda 7x e vale 0b10000000 (essa é + difícil). Se i=7, ao fazer PORTSEGMENTOS=tabela[dig[i]] portanto dig[i]=dig[7]=1 é o mesmo que PORTSEGMENTOS=tabela[1]. Note que [1] é o segundo item da tabela (começa com zero) é o mesmo que PORTSEGMENTOS=0b00110000 é o mesmo que PB=0b0110000 (note os segmentos A e B acesos em nivel alto). Neste momento único, o k vale 0b10000000 e este é aplicado em outro port PORTCATODOS=k potanto apontando para o display 7. Perceba que é 1 e não 0 pois o PORTCATODOS geralmente aciona um NPN ou uln2003 que p.ex. estão conectados aos catodos comuns dos displays. ufaa..

agora sim cheguemos onde voce quer... coloquemos o valor d=34 nos primeiros displays
dig[1]=d/10 = 34 dividido por 10 = 3,4 por sorte [ou azar] seu, este valor não pode ser contido dentro de um unsigned char. só cabe a parte inteira 3 portanto dig[1]=3 = dezena
dig[0]=d%10 = resto inteiro (a parte que é incabivel no unsigned char lembra?) da divisão de 34/10 o mesmo que d-dig[1]*10 = 34-3*10 = .....4! portanto dig[0]=4 unidade
Aqui um detalhe importante: d nunca deverá ser maior que 99... bom tente descobrir porquê.
Se dig[1]=4 e dig[0]=3 basta aplicar a complexa teoria acima do dig[7] e sua mente se abrirá... espero.

Complicado pra sua cabecinha? faça = ao amigo andré falou e contente-se por hora a "desenhar" algo no display ligando-o em um port qualquer. Breve estarás dominando o micromundo

Não se preocupe em se sentir pouco dotado intelectualmente de vez em quando (eu me sinto o tempo todo). A dúvida é a sala de estar da sabedoria. E eu nem na varanda estou ainda. Ainda tenho medo de vetores, arrays, matriz, ponteiro... sério...até hoje num entendo esta poha direito
aviso que tomei umas cachaças e eventualmente algo que eu disse pode parecer COM sentido.

ah e obrigado por dizer obrigado


agora sim eu consegui entender com mais clareza.

ou seja... se eu por exemplo quiser controlar os 8 displays cada display aceso o contador i++ deverá incrementar de modo proporcional, i++ será 0 pro digito n°1 até i++ ser 7 pro ultimo digito q seria o oitavo.

eu posso estar bastante confuso ainda...mas isso é meio normal...programação nunca foi muito meu forte...e os cursos tecnicos nunca ensinam nada direito...so me restando recorrer a esse forum... lembra quando queria mapear I/O em C? então...vejo q pra eu poder realmente fazer isso em software sem recorrer a gambiarras usando os ports P1 e P3... terei q investir tempo pra kct alem de muita paciência...possuo CI's o suficiente pra fabricar um mainframe de 1986 e n aguento mais acordar todo dia sabendo q não posso fazer grandes coisas com eles...