Olá pessoal!
Com as dicas do colega MORA_L consegui fazer uma frase 'correr' sobre 8 display´s de 7 seguimentos, dentro das suas limitações gráficas deste. Mas estou tendo o seguinte problema, quando a frase termina de ser exibida, que é sinalizada pelo código "Enter" (0x0D) inserido na variável caracter[], não estou conseguindo fazer com que ela seja exibida novamente. Estou usando um pic 18f452 8MHz, e para fazer o chaveamento dos display´s está sendo usado um mux 74138, para se fazer uso de somente 3 saídas, portb, e p/ acionar os seguimentos o portd. O programa foi escrito no MikroC. Abaixo vai o código
Conto com a vossa ajuda
//-----------------------Precedência de Todas as Rotinas------------------------
void trata_dados();
//----------------------Declaração das variáveis Globais------------------------
unsigned short int *ponteiro,*aponta_carac,filtro=0b00000111,mux=0,
est_menu=0,est_desl=0,aux=0,est_sobe=0,delta=250,
i=0,j=0,x=0,dados=0,
display[9]={0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x0D},
caracter[41]={0x3E,0x43,0x4A,0x58,0x47,0x50,0x4D,0x3E,0x40,
0x4D,0x52,0x43,0x4A,0x46,0x4D,0x0D};
#define dsp1 0x00
#define dsp2 0x01
#define dsp3 0x02
#define dsp4 0x03
#define dsp5 0x04
#define dsp6 0x05
#define dsp7 0x06
#define dsp8 0x07
#define liga 19
#define desliga 3
#define on x.F0
#define data_aux x.F1
#define hora_aux x.F2
#define temperatura_aux x.F3
#define letreiro_aux x.F4
#define rotaciona x.F5
//-------Rotina que irá selecionar o caracter que será exibido no Display-------
//-------Esta Rotina é comum a todas declaradas neste programa------------------
void trata_dados() {
switch (dados) {
case 0x30: dados=0XC0;break; //0
case 0x31: dados=0XF9;break; //1
case 0x32: dados=0XA4;break; //2
case 0x33: dados=0XB0;break; //3
case 0x34: dados=0X99;break; //4
case 0x35: dados=0X92;break; //5
case 0x36: dados=0X82;break; //6
case 0x37: dados=0XF8;break; //7
case 0x38: dados=0X80;break; //8
case 0x39: dados=0X98;break; //9
case 0x3A: dados=0X7F;break; //. (Ponto Decimal)
case 0x3B: dados=0XBF;break; //- (Hífen ou menos)
case 0x3C: dados=0XC6;break; //C (Celsius)
case 0x3D: dados=0X9C;break; //º (Grau)
case 0x3E: dados=0XFF;break; // Blank, apaga display
case 0x3F: dados=0X88;break; //A
case 0x40: dados=0X83;break; //b
case 0x41: dados=0XC2;break; //C
case 0x42: dados=0XA1;break; //d
case 0x43: dados=0X86;break; //E
case 0x44: dados=0X8E;break; //F
case 0x45: dados=0XC2;break; //G
case 0x46: dados=0X8B;break; //h
case 0x47: dados=0XE7;break; //i
case 0x48: dados=0XE1;break; //j
case 0x49: dados=0X8D;break; //k
case 0x4A: dados=0XC7;break; //L
case 0x4B: dados=0XC8;break; //M
case 0x4C: dados=0XAB;break; //n
case 0x4D: dados=0XA3;break; //o
case 0x4E: dados=0X8C;break; //P
case 0x4F: dados=0X90;break; //q
case 0x50: dados=0XAF;break; //r
case 0x51: dados=0X92;break; //S
case 0x52: dados=0X87;break; //t
case 0x53: dados=0XE3;break; //u
case 0x54: dados=0XC1;break; //V
case 0x55: dados=0X81;break; //W
case 0x56: dados=0X89;break; //X
case 0x57: dados=0X91;break; //Y
case 0x58: dados=0XA4;break; //Z
default: dados=0x3E; //'\0';
}
}
//----------Rotina que irá exibir uma mensagem deslizante no display------------
//----------escrita pelo usuário------------------------------------------------
void letreiro() {
ponteiro=&display[0];
aponta_carac=&caracter[0];
mux=dsp1;
PORTB=mux;
do
{
if (rotaciona==1) { //Nas linhas abaixo é feito uma rotação entre o conteúdo
display[7]=display[6]; //das variáveis, fazendo com que os caracteres deslizem
display[6]=display[5]; //nos 8 display´s
display[5]=display[4];
display[4]=display[3];
display[3]=display[2];
display[2]=display[1];
display[1]=display[0];
display[0]=*aponta_carac;
rotaciona=0;
}
if (*ponteiro==0x0D && *aponta_carac==0x0D)
{
ponteiro=&display[0];
aponta_carac=&caracter[0];
mux=dsp1;
PORTB=mux;
}
//--------------------------Varredura dos Display´s-----------------------------
dados=*ponteiro; //Atribui à dados o conteúdo do display apontado por *ponteiro
trata_dados();
if (on==1) {
PORTD = dados; //
}
else {
PORTD=255; //Apaga os Display´s
}
if (*ponteiro==0x0D) { //Verifica se o conteúdo do end. apontado é = Enter
ponteiro=&display[0];
}
}
while(1);
}
//-----------------Rotina para tratamento da Interrupção------------------------
void interrupt() {
if (INTCON.T0IF==1) { //A interrupção foi estouro TMR0?
if (on==1) { //O display estava ligado?
on=0; //Sim, então desliga e sinaliza display
PORTD=255; //Apaga os Display´s
TMR0H=0xFF;
TMR0L=(256 - desliga);
}
else { //Não, então liga e sinaliza
on=1;
TMR0H=0xFF;
TMR0L=(256 - liga);
PORTB=++mux; //Increm. p/ ativar próximo display (dsp1 ==> dsp8)
++ponteiro; //Incrementa o ponteiro p/ próximo endereço
mux = (filtro & mux); //Limita a contagem entre 00000000 e 00000111
}
INTCON.T0IF=0;
}
if (PIR1.TMR1IF==1) {
//PORTB.F3=~PORTB.F3;
//i++;
rotaciona=1; //Sinaliza que deverá ser lido um novo caracter
if (*aponta_carac == 0x0D)
*aponta_carac = *aponta_carac; //Mantém o mesmo valor apontado
else aponta_carac++; //Incrementa o ponteiro_aux p/ endereço do próximo caracter
TMR1H=0; //0X92;
TMR1L=0; //0X7C;
PIR1.TMR1IF=0; //Limpa flag que sinaliza estouro TMR1
}
}
//--------------------------Início da Rotina Principal--------------------------
void main() {
ADCON1 = 0x80; //Seleciona canal analógico AN0(RA0) e AN1(RA1)
TRISA = 0xFF; //RA0 e RA1 c/ entrada
TRISE=1; //RE0 c/ entrada
TRISD = 0; //programa portD como saida
TRISB = 0b11110000; //programa portB como entrada
T0CON = 0b10000110; //Utilizado somente no 18F452
//OPTION_REG = 0b00000110; //Pré 1:4 utilizado somente no 16F877A
TMR0H=0xFF;
TMR0L=(256 - liga);
on=1; //Sinaliza que iniciará com período de 1ms, liga display
INTCON = 0b11100000; //Habilita interr. global, periféricos e chave indiv. TMR0
T1CON = 0b10110001; //Conf. Timer1 1:8 e Timer1 on
PIE1.TMR1IE = 0; //Timer1 habilitado chave individual
PIR1.TMR1IF=0; //Limpa flag que sinaliza estouro
TMR1L = 0;
TMR1H = 0;
letreiro();
}