PIC 16F887 receber string pela RS-232 - RESOLVIDO

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

PIC 16F887 receber string pela RS-232 - RESOLVIDO

Mensagempor sdr » 27 Mar 2009 17:01

Seguinte, estou querendo que o pic receba uma string pela 232, uma string que seja enviada por um outro dispositivo e não digitada pelo teclado.

#include <16F887.h>
#fuses HS,PUT,NOBROWNOUT,NOWDT,INTRC_IO,NOMCLR
#use delay(clock=8000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7) // no 16F688 xmit=PIN_C4,rcv=PIN_C5
#use i2c (MASTER,SCL=PIN_C3,SDA=PIN_C4)
#BYTE OSCCON=0X8F

//para receber a string
void get_string(char* s, unsigned int8 max) {
unsigned int8 len;
char c;
len=0;
do {
c=getc();
s[len++]=c;
}
while(kbhit());
s[len]=0;
}

#int_RDA

void recepcao_serial()
{
char string[10];
disable_interrupts(INT_RDA);
get_string;
enable_interrupts(INT_RDA);
}

main ()
{

OSCCON=0B01110100; // oscilador interno com 8MHz
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);

while(1)

}

esse é o código simplificado, feito no CCS, o problema é quando simulo ele no proteus, usando um programinha envio uma palavra para a com virtual do proteus, o pic recebe os dois primeiros bytes quando recebe o terceiro dá o erro FIFO's full - OERR set, e do quarto byte em diante DATA discarded.

já tentei o código do TCPIPCHIP timed_getc mas dá o mesmo erro, não sei pra onde correr, ajuda ai meu povo, vlw.
Editado pela última vez por sdr em 02 Abr 2009 17:11, em um total de 1 vez.
sdr
Bit
 
Mensagens: 7
Registrado em: 09 Mar 2009 17:41

Re: PIC 16F887 receber string pela RS-232

Mensagempor andre_luis » 27 Mar 2009 23:00

Voce está fazendo uma pesquiza dentro de uma interrupção. Conceitualmente isso parece errado.

Outra coisa: Esse erro após o 3 byte, é indício de que os bytes não estão sendo lidos no registrador da serial, que por acaso possui um buffer de 3 bytes.

Essa função na interrupção, não tem argumentos ?

Sugiro voce debugar passo-a-passo.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: PIC 16F887 receber string pela RS-232

Mensagempor sdr » 30 Mar 2009 16:39

andre_teprom escreveu:Voce está fazendo uma pesquiza dentro de uma interrupção. Conceitualmente isso parece errado.

Outra coisa: Esse erro após o 3 byte, é indício de que os bytes não estão sendo lidos no registrador da serial, que por acaso possui um buffer de 3 bytes.

Essa função na interrupção, não tem argumentos ?

Sugiro voce debugar passo-a-passo.


os dois primeiros bytes estão sendo lidos, o problema é que o buffer da serial não tá resetando. quando uso a funcão gets() ou fgets() elas pegam todos os bytes enviados, só que ela não me serve pois ela fica esperando um "enter".
sdr
Bit
 
Mensagens: 7
Registrado em: 09 Mar 2009 17:41

Mensagempor KILB » 30 Mar 2009 20:26

Tome este como exemplo!


#include <16F877.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#use delay(clock=20000000)
#fuses XT, PUT, NOWDT, NOBROWNOUT, NOLVP
#use rs232(BAUD=9600, parity=N, BITS=8, XMIT=pin_c6, RCV=pin_c7)

#define MAX_BUFFER 15
char BufferRX[MAX_BUFFER+1];
boolean CHEGOU_COMANDO = false;

//---------------------------------------------------------------------------
//Interrupção de recebimento de caracter pela UART.
//---------------------------------------------------------------------------
#int_rda
void Serial_Recebe_Car()
{
static unsigned char ch;
static int IndexBuf=0;

ch = getc(); //Pega o caracter no registrador da UART.

BufferRX[IndexBuf] = ch; //Guarda o caracter no buffer.

if( BufferRX[IndexBuf] == '*' ) //Se é o fim da string de comando.
{
BufferRX[IndexBuf+1] = '\0'; //Finaliza sting.
IndexBuf = 0;
CHEGOU_COMANDO = true; //Avisa que chegou uma string de comando.
}else{
IndexBuf++;
}
if( (BufferRX[0] != '>' ) || (IndexBuf >= MAX_BUFFER) )
{
IndexBuf = 0;
}

}
//---------------------------------------------------------------------------
#int_timer0
void MeuTimer()
{
static boolean led;
static int conta;
set_timer0(131-get_timer0());
conta++;
if(conta == 90)
{
conta=0;
led = !led;
output_bit(pin_d4,led);
}
}

//Programa Principal.
void main(void)
{
char COMANDO[15];
set_timer0(131);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64);
enable_interrupts(int_rda); //Habilita interrupção de recebimento.
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL); //Habilita registrador de interrupção.

set_tris_d(0b00000100); //somente o pino 2 da porta 'D' como entrada.
set_tris_b(0b00000000); //Todos saída.
output_b(0b00000000); //Todos os pinos de saída da porta b desligados.

while( true ) //Loop infinito.
{

if(CHEGOU_COMANDO == true)
{
CHEGOU_COMANDO = false;

strcpy(COMANDO,">CMD#01#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b0); //Liga Relê 1.
printf("Relê #1 LIGADO\r\n");
continue; //volta para o início do loop while().
}
strcpy(COMANDO,">CMD#01#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b0); //Desliga Relê 1.
printf("Relê #1 DESLIGADO\r\n");
continue;
}
//------------------------------------------
strcpy(COMANDO,">CMD#02#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b1); //Liga LED.
printf("Relê #2 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#02#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b1); //Desliga LED.
printf("Relê #2 DESLIGADO\r\n");
continue;
}
//------------------------------------------
strcpy(COMANDO,">CMD#03#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b2); //Liga LED.
printf("Relê #3 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#03#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b2); //Desliga LED.
printf("Relê #3 DESLIGADO\r\n");
continue;
}
//------------------------------------------
strcpy(COMANDO,">CMD#04#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b3); //Liga LED.
printf("Relê #4 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#04#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b3); //Desliga LED.
printf("Relê #4 DESLIGADO\r\n");
continue;
}
//------------------------------------------
strcpy(COMANDO,">CMD#05#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b4); //Liga LED.
printf("Relê #5 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#05#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b4); //Desliga LED.
printf("Relê #5 DESLIGADO\r\n");
continue;
}
//------------------------------------------
strcpy(COMANDO,">CMD#06#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b5); //Liga LED.
printf("Relê #6 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#06#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b5); //Desliga LED.
printf("Relê #6 DESLIGADO\r\n");
continue;
}
//------------------------------------------
strcpy(COMANDO,">CMD#07#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b6); //Liga LED.
printf("Relê #7 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#07#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b6); //Desliga LED.
printf("Relê #7 DESLIGADO\r\n");
continue;
}
//------------------------------------------
strcpy(COMANDO,">CMD#08#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b7); //Liga LED.
printf("Relê #8 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#08#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b7); //Desliga LED.
printf("Relê #8 DESLIGADO\r\n");
continue;
}
//-----------------------------------------

}

}
}





Valeu :P
VENDO BRASILIA 78 - AZUL CALCINHA - RODA GAIUCHA, PNEU TALA LARGA E TOCA FITA RODSTAR, TRATAR NO BUTECO
KILB
Byte
 
Mensagens: 103
Registrado em: 17 Fev 2007 21:52

Mensagempor sdr » 01 Abr 2009 15:05

vlw KILB, era isso que eu queria, só não entendi o que faz a interrupção do timer, ele não é necessário ,é?
sdr
Bit
 
Mensagens: 7
Registrado em: 09 Mar 2009 17:41

Mensagempor KILB » 01 Abr 2009 21:43

sdr escreveu:vlw KILB, era isso que eu queria, só não entendi o que faz a interrupção do timer, ele não é necessário ,é?



Não, não ... isto faz parte do codigo que eu uso e serve só pra fazer um led piscar e ao mesmo tempo me dizer que o programa esta virando...


Valeu
VENDO BRASILIA 78 - AZUL CALCINHA - RODA GAIUCHA, PNEU TALA LARGA E TOCA FITA RODSTAR, TRATAR NO BUTECO
KILB
Byte
 
Mensagens: 103
Registrado em: 17 Fev 2007 21:52

Mensagempor sdr » 02 Abr 2009 16:37

blz

adicionei um timeout pra encerrar a string quando passar um tempo depois do ultimo byte recebido:

#define KEYHIT_DELAY 5 // in milliseconds
#use rs232(BAUD=9600, parity=N, BITS=8, XMIT=pin_c6, RCV=pin_c7, timeout=KEYHIT_DELAY)
#define MAX_BUFFER 15

char BufferRX[MAX_BUFFER+1];
boolean CHEGOU_COMANDO = false;

//---------------------------------------------------------------------------
//Interrupção de recebimento de caracter pela UART.
//---------------------------------------------------------------------------
#INT_rda

void Serial_Recebe_Car()
{
static UNSIGNED char ch;
STATIC int IndexBuf=0;
do{

ch = getc(); //Pega o caracter no registrador da UART.
BufferRX[IndexBuf] = ch; //Guarda o caracter no buffer.
IndexBuf++;

}

while(RS232_ERRORS); //enquanto não houver o time_out

IF(!RS232_ERRORS)
{
BufferRX[IndexBuf] = '\0'; //Finaliza string.
IndexBuf = 0;
CHEGOU_COMANDO = true; //Avisa que chegou uma string de comando.
}

}

o arquivo EX_TGETC2.C da um exemplo de como fazer o timeout.
sdr
Bit
 
Mensagens: 7
Registrado em: 09 Mar 2009 17:41


Voltar para PIC

Quem está online

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

cron

x