|
|
View previous topic :: View next topic |
Author |
Message |
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
How to make INT_RB work for multiple RS 232 ports on 16F877A |
Posted: Sun Jul 30, 2006 8:03 am |
|
|
Hi,
I have written some code on receiving ascii on multiple RS 232 ports using the INT_Rb interrupt.
I can receive some characters but not the correct ones, the drivers I am using are the standard MAX 232 type, and the hardware works when I use the timed_getc() function.
Here is the code for the transmitter/receiver PIC 16F877A mcu
thanks
arunb
Code: |
#include <16F877A.h>
#FUSES HS,NOWDT,PUT,NOPROTECT,NOCPD,BROWNOUT,NOLVP,NODEBUG
#define EEPROM_SDA pin_c4
#define EEPROM_SCL pin_c3
#define EEPROM_SIZE 0x7FF8
#use delay(clock=16000000)
#use rs232(baud=9600,xmit=pin_c6, rcv=pin_c7,parity=n,stream=PC,ERRORS)
#use rs232(baud=1200,xmit=pin_d5, rcv=pin_b5,parity=n,brgh1ok,stream=DISPLAY,force_sw,sample_early)
#use rs232(baud=1200,xmit=pin_d7, rcv=pin_b3,parity=n,brgh1ok,stream=RHSDRIVE,force_sw,sample_early)
#use rs232(baud=1200,xmit=pin_d6, rcv=pin_b4,parity=n,brgh1ok,stream=LHSDRIVE,force_sw,sample_early)
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
#define LHSRCV pin_b4
#define DISRCV pin_b5
int bDReady,lhs,disp;
#ZERO_RAM
void initialise()
{
setup_adc(ADC_OFF );
set_tris_a(0b11111111);
set_tris_b(0b11111111);
set_tris_d(0b00011111);
set_tris_c(0b10111111);
set_tris_e(0b11111111);
output_float(pin_b4);
output_float(pin_d6);
output_float(pin_d5);
output_float(pin_b5);
output_float(pin_d7);
output_float(pin_b3);
enable_interrupts(INT_RB);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
void main()
{
initialise();
do
{
if (bDReady==2)
{
putc(disp,PC);
bDReady=0;
}
}while(TRUE);
}
#int_rda
void usart_isr()
{
int g,val;
g=getc();
val=fputc(g,DISPLAY);
}
#int_rb
void multi_rs232()
{
int h;
h=input_b();
if (bit_test(h,5)==0)
{
disp=fgetc(DISPLAY);
bDReady=2;
}
}
|
Here is the code for the reciver (that sends back the data)
Code: |
#include <16F648A.h>
#use delay(clock=4000000)
#FUSES INTRC,NOWDT,PUT,NOPROTECT,NOMCLR,NOCPD,BROWNOUT,NOLVP
#use rs232(baud=1200,xmit=pin_b2, rcv=pin_b1,parity=n)
char cRcvData;
#ZERO_RAM
void initialise()
{
setup_comparator(NC_NC_NC_NC);
set_tris_a(0b101111100);
set_tris_b(0b111111011);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
void main()
{
initialise();
do
{
}while(TRUE);
}
#int_rda
usart_rcv()
{
cRcvData=getc();
delay_us(100);
putc(cRcvData+1);
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Sun Jul 30, 2006 10:15 am |
|
|
A series of comments.
First, get rid of the fputc, inside the serial interrupt handler. The putc, at 1200bps, will take eight character times of the hardware serial. If more than two character come in succession, you will lose data.
Second comment. the int_rda, needs to fgetc(PC). By default, a 'getc', without a stream, when multiple streams are enabled, selects the _last_ defined stream. Wrong one for the hardware serial...
Third comment. BRGH10K, does nothing on software streams. There is also no point in using 'force_sw', on pins that don't support hardware mode.
Now you presumably do understand, that if a second character arrives on either stream supporting interrupts, while the 'reply' is being sent to DISPLAY, this reply will be garbaged.
The delays in the int_rda on the second chip, should be removed. Have the reply sent in the _main_ not in the interrupt handler.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|