No Keil dá pau. Por quê ?

Software e Hardware para linha x51

Moderadores: 51, guest2003, Renie, gpenga

No Keil dá pau. Por quê ?

Mensagempor Silvio51 » 10 Fev 2007 22:33

Pessoal....essa parte do meu programa compila normalmente no SDCC....tô tentando usar o Keil agora e simplesmente não funciona:

void get_int()interrupt 4 using 0
{ while(!RI); // espera enquanto SPIF=0 -0x80
RI=0;
sbuffer=SBUF;
}
void get_string()
{ contdados=0;
sbuffer='x'; //suja afim de evitar erros
while(sbuffer!='\r')
{ get_int(); /* : ERROR C205: CAN´T CALL AN INTERRUPT FUNCTION */

dados[contdados++]=sbuffer;
}
dados[--contdados]='\0'; // troca '\r' por '\0'
}

Quem puder ajudar agradeço....
Silvio51
Byte
 
Mensagens: 383
Registrado em: 02 Nov 2006 14:04
Localização: Brasil

Mensagempor Maurício » 10 Fev 2007 23:16

Salve, Silvio51.

No keil, uma função de interrupção não pode ser tratada como uma função comum. Você não pode chamar uma função de interrupção, pelo programa, como se elas fossem funções comuns. Elas são automáticas. São chamadas somente SE ocorrer alguma interrupção.
Por isso é que são funções de interrupção.

Não sei bem o que vc quer, mas, experimenta este código aqui:

Código: Selecionar todos
bit chegou_dado = 0;
bit string_recebida = 0;

void get_int ( void ) interrupt 4
{
   chegou_dado = 1;
   sbuffer=SBUF;
   RI=0;
}

void get_string()
{
   static unsigned char contdados=0;
   
   if ( sbuffer != '\r' )
   {
      dados[contdados++]=sbuffer;
   }
   else
   {
      dados[contdados]='\0'; // troca '\r' por '\0'
      string_recebida = 1;
      contdados = 0;
   }
}

void trata_string ( void )
{
   string_recebida = 0;
}

main ( )
{
   while ( 1 )
   {
      if ( chegou_dado )
      {
         chegou_dado = 0;
         get_string ( );
      }
      if ( string_recebida ) trata_string ( );
   }
}


Sem esquecer, claro, que a serial precisa ser configurada antes de ser usada.

[]'s

RETI.
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor Silvio51 » 11 Fev 2007 12:51

Maravilha Maurício....entendí....era exatamente isso que eu queria fazer. Porém, neste exemplo, que é do livro do Denyz, ele diz que não usa a interrupção serial....não entendí bem já que existe a função de atendimento da interrupção e também não sei se é possível receber um dado na serial do At89S8252 sem ser sinalizado por interrupção. Pode ser que não seja ético eu por esse exemplo em discussão, mas a intenção não é outra senão apenas tirar dúvidas no Keil (sou iniciante no mesmo).

Segue abaixo a rotina completa:

#include<at89s8252.h>
bit buffer_cheio;
code char men1[]={"\tDIGITE UM DADO PARA SER SALVO NA EEPROM (40 CARACTERES)\r\r"}; // locação dinâmica
code char men2[]={"\tGRAVANDO DADOS\r"}; // locação dinâmica
code char men3[]={"\tDADOS SALVOS\r"}; // locação dinâmica
code char men4[]={"\tSEUS DADOS: \t"};

/*--------------- variaveis globais --------------*/
xdata char E2prom[40];
char cont_e2prom=0;
char sbuffer;
char dados[40];
char contdados;

/*---------------- Area para codigo --------------*/

/*-----Rotina para configurar o Timer 2 como gerador de Baud-rate-----*/
void serial()
{ SCON=0x50; // Modo 1 e Habilita a recepção de dados
TCLK=1; // Seta bit de Controle
RCLK=1; // Seta bit de Controle
C_T2=0; // Clock como base
RCAP2H=0xFF; // 115200 Baud-rate
RCAP2L=0xFD;
TR2=1; // Habilita operação do periférico
}
void envia(char *dado)
{ serial();
SBUF=*dado;
while(!TI);
TI=0;
}
void get_int()interrupt 4 using 0
{ while(!RI); // espera enquanto SPIF=0 -0x80
RI=0;
sbuffer=SBUF;
}
void get_string()
{ contdados=0;
sbuffer='x'; //suja afim de evitar erros
while(sbuffer!='\r')
{ get_int();
dados[contdados++]=sbuffer;
}
dados[--contdados]='\0'; // troca '\r' por '\0'
}
void grava_dados(char *pont) // grava na memória EEPROM
{ WMCON=0x1A; // acesso à memória e2prom
E2prom[cont_e2prom]=*pont; // gravacao
while(WMCON==0x18); // enquanto a memoria nao apta a gravar novos dados
cont_e2prom++;
WMCON=0x0A; // desabilita acesso a memoria e2prom
}
void grava_string()
{ char cont;
for(cont=0;dados[cont]!='\0';cont++) // grava dados na EEPROM
{ grava_dados(&dados[cont]); }
grava_dados(&dados[cont]); // grava '\0'
}
void main()
{ char cont;
P1_3=0;
for(cont=0;men1[cont];cont++) //envia mensagem 1
{ envia(&men1[cont]); }
contdados=0;
get_string();
for(cont=0;men2[cont];cont++) // envia mensagem 2
{ envia(&men2[cont]); }
grava_string();
for(cont=0;men3[cont];cont++) //envia mensagem 3
{ envia(&men3[cont]); }
for(cont=0;men4[cont];cont++) //envia mensagem 4
{ envia(&men4[cont]); }
for(cont=0;E2prom[cont]!='\0';cont++) //envia mensagem 3
{ envia(&E2prom[cont]); }
}

Este programa se comunica com o PC recebendo até 40 caracteres pela serial (115000 baud-rate Xtal 11.0952 Mhz) e os salva na EEPROM do AT89S8252.
ps: Para o SDCC está correto ou essa chamada é redundante já que teoricamente, como você bem escreveu, não se deve chamar uma interrupção ?
Obrigado pelos esclarecimentos....
Silvio51
Byte
 
Mensagens: 383
Registrado em: 02 Nov 2006 14:04
Localização: Brasil

Mensagempor Maurício » 11 Fev 2007 17:45

Silvio51 escreveu:ps: Para o SDCC está correto ou essa chamada é redundante já que teoricamente, como você bem escreveu, não se deve chamar uma interrupção ?
Obrigado pelos esclarecimentos....


Aí eu já não sei te dizer, porque eu nunca usei o SDCC. Se funciona normalmente, então, deve ser correto.

Vc pode receber/transmitir dados de/para o 8051, sem precisar usar interrupção. Dê uma olhada nas funções GETCHAR e PUTCHAR.

Basta ficar monitorando o flag RI, pra ver se chegou algum dado. Se chegou, vc captura com GETCHAR. Sem usar interrupção.

Na página de downloads do meu livro, tem alguns programas que fazerm comunicação serial com o 8051.
Dá uma olhada lé e vê se te serve. É pro Keil.

http://www.editoraerica.com.br/download ... troladores

Verifica tb no manual do Keil, as funções padrão de entrada/saída do 8051 ( STDIO.H).

Boa sorte aí !!!

[]'s

RETI.
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor Viktor » 19 Fev 2007 09:27

Em vez de chamar a função, gere ua setando RI ou TI conforme o caso.
Viktor
Byte
 
Mensagens: 281
Registrado em: 12 Out 2006 11:33


Voltar para 8051

Quem está online

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

x