Página 1 de 1

Serial no at98s52

MensagemEnviado: 02 Mar 2007 10:17
por blackhawk123
Estou tentando usar a serial no at98s52, mas ela não quer funcionar. Estou usando o Proteus para simular e o SDCC para compilar, a configuração da serial que usei é essa:

IE=0001000;
SM0=0;
SM1=1;
TL1=EB;
TH1=FE;
TMOD=00100000;
P3=FF;


void serial (void) interrupt 4
{
P2=SBUF;
}


O programa le o P1 e envia (SBUF=P2) pela serial, quando recebe unda do ele escreve em P2.

O problema é que quando eu mando escrever na serial o Proteus mosta no registrador SBUF o valor de P1, mas ele não é enviado pela serial.

MensagemEnviado: 02 Mar 2007 11:13
por Maurício
Poste suas rotinas de inicialização e tratamento da serial. Velocidade, bits recebidos/transmitidos, paridade e número de stop bits, e principalmente, o cristal que vc está utilizando.

A serial se dá melhor com cristais de valores 11.0592MHz e seus múltiplos/sub-múltiplos. Cristais de frequências com valores redondos (12MHz, por exemplo), geram uma taxa de erros muito grande nas comunicações.

Não há base numérica binária nativa na linguagem C. Os padrões núméricos da linguagem são: o decimal, o hexadecimal e o octal.

A serial usa a mesma interrupção, tanto para transmissão, como para recepção. Sem verificar qual dos flags foi acionado, como é que vc sabe que o dado no momento foi transmitido ou recebido ?

Não conheço SDCC. Uma boa referência pode ser o livro do Denys:

http://www.editoraerica.com.br/buscafinal.asp?cod=0794

[]'s

RETI.

MensagemEnviado: 04 Mar 2007 16:05
por blackhawk123
Maurício, o cristal que estou usando é de 12Mhz, mas ainda não testei no 8051. Só simulei no Proteus. Os programas que estou usando são esses 2:

Código: Selecionar todos
#include<at89x52.h>

void Serial(void)interrupt 4
{
   P2 = SBUF;
}


main(void)
{
   EA = 1;
   ET1 = 0;
   ET0 = 0;
   EX0 = 0;
   EX1 = 0;
   IP = 0x10;
   ES = 1;
   SM0 = 0;
   SM1 = 1;
   TL1 = 0xEB;
   TH1 = 0xFE;
   TCON = 0x10;
   P3 = 0;
   P2 = 0;
   P1 = 0xFF;
   P0 = 0;

for(;;)
{
   if(P3_7==0)
   {
      SBUF = P1;
   }
}
}

Código: Selecionar todos
#include<at89x52.h>

void Serial(void)interrupt 4
{
   P2 = SBUF;
}


main(void)
{
   EA = 1;
   ET1 = 0;
   ET0 = 0;
   EX0 = 0;
   EX1 = 0;
   IP = 0x10;
   ES = 1;
   SM0 = 0;
   SM1 = 1;
   TL1 = 0xEB;
   TH1 = 0xFE;
   TCON = 0x10;
   P3 = 0xFF;
   P2 = 0;
   P1 = 0xFF;
   P0 = 0;

for(;;)
{
   if(P3_7==0)
   {
      SBUF = P1;
   }
   P2 = SBUF;
}
}

MensagemEnviado: 05 Mar 2007 03:30
por Maurício
No 8051 pra gerar baud-rates, o único timer responsável por isso é o TIMER1.
No seu programa, vc não configurou o TIMER1 e está acionando o TIMER0 (TCON = 0x10), talvez aí esteja o problema do programa.
No 8052 vc pode usar, ou TIMER1, ou TIMER2, ou os dois simultâneamente, em taxas de transmissão/recepção diferentes.

Experimenta isso aqui:

Código: Selecionar todos
#include <REG51.H>

bit serial_liberada = 1;

void Serial(void)interrupt 4
{
   if (TI)
   {
       TI = 0;
       serial_liberada = 1;
   }

   if (RI)
   {
       RI = 0;
       P2 = SBUF;
   }
}

void configura_serial(void)
{
    SCON   = 0x50;   // SCON: modo 1 => 8N1, 8 bits, REN=1 => recepção habilitada
    TMOD   = 0x20;   // TMOD: timer 1, modo 2, 8 bits reload
    TH1 = TL1 = 0xE6;   // TH1: valor de carga para 1200bps @ 12MHz; ERRO = 0,16%
    TR1   = 1;      // TR1: timer 1 rodando
    RI   = 0;      // inicia com o flag de recepção resetado; habilitado para receber
}

main(void)
{
   P3 = P1 = 0xFF;
   P2 = P0 = 0;
   EA = ES = 1;
   configura_serial();

   while ( 1 )
   {
      if(P3_7==0)
      {
         while (!serial_liberada);     // espera transmitir
         SBUF = P1;  // (???) só vai transmitir 0xFF, sempre
         serial_liberada = 0;
      }
   }
}


Eu não testei. Espero que ajude.

[]'s

RETI.

MensagemEnviado: 09 Mar 2007 10:09
por blackhawk123
Maurício, obrigado pela ajuda, vou ver se funciona.

MensagemEnviado: 10 Mar 2007 22:21
por rubenprom
Mauricio, no trecho do programa:

.
.
.
void configura_serial(void)
{
SCON = 0x50; // SCON: modo 1 => 8N1, 8 bits, REN=1 => recepção habilitada
TMOD = 0x20; // TMOD: timer 1, modo 2, 8 bits reload
TH1 = TL1 = 0xE6; // TH1: valor de carga para 1200bps @ 12MHz; ERRO = 0,16%
TR1 = 1; // TR1: timer 1 rodando
RI = 0; // inicia com o flag de recepção resetado; habilitado para receber
}
...

o SCON =0x50 , está mesmo no modo1??pelo tenho lido, nao será que SCON=0x50 esta no modo 0??

Ruben

MensagemEnviado: 10 Mar 2007 22:39
por Maurício
Fala, rubenprom. Blz?

É isso mesmo. Os bits de SCON a partir do bit 7 são:

SM0 -- SM1 -- SM2 -- REN -- TB8 -- RB8 -- TI -- RI

SM1 = 1 e SM0 = 0, configura a serial no MODO1 (assíncrona, 8bits, baud-rate dado por TIMER1). E seta tb o bit REN, habilitando a serial a receber dados. Então, SCON = 0x50.

Pra configurar a serial no MODO0, habilitando o bit de recepção, ficaria:

SCON = 0x10;

E no mesmo modo, mas sem receber: SCON = 0x00;

Mas, tive sérios problemas usando o MODO0 no Keil. Talvez, em outros compiladores, funcione melhor.

[]'s

RETI.

MensagemEnviado: 12 Mar 2007 10:26
por rubenprom
Fala Mauricio

Bahhhhhhhhh, peço ai desculpas, tavas certo, isso que dá fazer calculos às 3 da manha, eu tinha conertido a sequencia em decimal, porem estava esquecendo a base HEXA. Olha que foi um erro muito grave meu!

mas valeu

Ruben

MensagemEnviado: 23 Mar 2007 10:11
por blackhawk123
Maurício, obrigado pela ajuda, acabei de testar o seu programa e ele funcionou perfeitamente.