andrescabral
Joined: 15 Mar 2007 Posts: 1
|
help me on RS232 connection between 2 PICS |
Posted: Thu Mar 15, 2007 8:45 am |
|
|
I'm trying to connect 2 PICs using the library RS232. I connect them by the protocol RS485 using the MAX485. If I send a simple byte everithing work fine, but if i send a frame of bytes(like MODBUS) the receiver doesn't read anything and it hang up after receive 1 or 2 bytes.
I used many types of PICS(16F84, 16F873, 16F873A, 18F2680, 16F870) and the problem is the same.
I read the line with a computer, and it only shows what the MASTER is sending.
Here is the MASTER's code
Code: |
#include <16F873A.h>
#device adc=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=9600,parity=E,xmit=PIN_C6,rcv=PIN_C7,bits=8,enable=PIN_C0,restart_wdt,ERRORS,STOP=1)
int1 fueratiempo=0,verok=0,listo=0,errormortal=0, inicializado=0;
int veces=0,trama[5];
int8 puntero=0;
void verificar(char c);
void esperar();
void leer(int puertaTX,int dire);
void enviar(int c,int dire);
void int_modbus();
char puertac=128,puertac1,puertaTX;
#int_TIMER0
RTCC_isr()
{fueratiempo=1;
verok=0;}
void main()
{int16 i;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
puertac=0xFF;
set_tris_A(0xFE);
set_tris_C(0xBE); //10111110
set_tris_B(0xFF); //11110000
port_b_pullups(true);
output_A(0);
while(true){
// if(inicializado==1){
for (i=1;i<=100;++i){
/*if(input(PIN_B0)){putc(26);}
else{putc(27);}*/
//puertac1 = input_b() & 0x3F;
if ( (puertac1=input_b()) != puertac ){
puertac=puertac1;
puertaTX=puertac;
//swap(puertaTX);
verok=0;
while(verok==0&&veces<1){
enviar(puertaTX,3);
veces+=1;}
//leer(puertaTX,3);
veces=0;
}
// else{/*if(errormortal==1){*/enviar(puertaTX,3);}
// }
/* leer(puertaTX,3);
if(!verok){enviar(puertaTX,3);}*/
}
}
}
void enviar(int c,int dire){
putc(dire);//delay_us(10);
putc(2);//delay_us(10);
putc(c);//delay_us(10);
putc(dire);//delay_us(10);
putc(c);//delay_us(10);
esperar();}
void leer(int puertaTX,int dire){
putc(dire);
putc(1);
putc(1);
putc(dire);
esperar();
}
void esperar(){
puntero=0;
listo=0;
verok=0;
set_timer0(0);
enable_interrupts(INT_TIMER0);
while(fueratiempo==0&&listo==0){
while(kbhit()){verificar(getch());}
}
disable_interrupts(INT_TIMER0);
}
void verificar(char c){
switch (puntero){
case 0:// recibo el esclavo a quien va dirigido
trama[0]= c;
puntero+=1;
break;
case 1:// recibo el dato
trama[1]= c;
puntero+=1;
break;
case 2:
trama[2]=c; //Address
puntero+=1;
break;
case 3:
trama[3]=c; //dato
listo=1;
puntero=0;
if (trama[0]==trama[2]&&(trama[1]==~trama[3])&&trama[0]==3)
{verok=1;
veces=0;
if (trama[1]!=puertaTX){errormortal=1;}
else{errormortal=0;}
}
break;
default:puntero=0;
}
}
|
And here's the SLAVE code
Code: |
#include <16F873A.h>
#device adc=8
#FUSES NOWDT, HS , NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=9600,parity=E,xmit=PIN_C6,rcv=PIN_C7,bits=8,enable=PIN_C0,restart_wdt,ERRORS, STOP=1)
#define address 3
int1 pausa_rx=0;
int trama[5],ini=0x80;
int8 puntero=0;
void analiza(int c);
void int_modbus();
int aux;
#int_TIMER0
RTCC_isr()
{pausa_rx=0;
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_tris_A(0xFF); //11111010
set_tris_B(0x1F); //00011111
set_tris_C(0xBE); //10111110
putc(202);
disable_interrupts(GLOBAL);
output_b(0x00);
while(true){
//if(kbhit()&&(!pausa_rx)){ aux=getc(); analiza(aux);}
while(kbhit()){analiza(getc());}
}
}
void analiza(char c){
//if(bit_test(rs232_errors,0)){output_bit( PIN_B7, 1);pausa_rx=1;}//putc(203);return;}
output_bit( PIN_B7, 1);
switch (puntero){
case 0:// recibo el esclavo a quien va dirigido
if (c==address) //si el comando es para mi
{trama[0]= c;
puntero+=1;}
else
{puntero =0;
set_timer0(0);
enable_interrupts(INT_TIMER0);
pausa_rx=1;}
break;
case 1:// recibo el comando
trama[1]= c;
puntero+=1;
break;
case 2:// recibo el dato o comando
trama[2]= c;
puntero+=1;
break;
case 3:
trama[3]=c; //Address
switch(trama[1]){
case 1:puntero=0; //LEER
if (trama[0]==trama[3]&&trama[1]==trama[2])
{int_modbus(); //rutina de respuesta
}
else{pausa_rx=1;
set_timer0(190);//}
enable_interrupts(INT_TIMER0);}
break;
case 2:puntero+=1;break;}
break;
case 4:
trama[4]=c; //dato o comando
puntero=0;
if (trama[0]==trama[3]&&trama[2]==trama[4])
{output_b (trama[2]);
int_modbus(); //rutina de respuesta
}
break;
default:puntero=0;
}
output_bit( PIN_B7, 0);
}
void int_modbus(){ //rutina de respuesta
putc(address);
putc(input_b());
putc(address);
putc(~input_b());
}
|
|
|