|
|
View previous topic :: View next topic |
Author |
Message |
FRANCESC Guest
|
16F873 AND RS-232 |
Posted: Sat Aug 02, 2003 12:25 pm |
|
|
Hi all
We try to comunicate two 16F873 by RS-232 port using interrupts.
We not sure if the programs are correct, because on receiver LCD not appears nothing.
We try to locate examples on Internet, and not found nothing
Please Help to run the programs.
//*********************EMITER*********************
#include <16f873.h>
#fuses xt,nowdt,put,nolvp
#use delay(clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use RS232(BAUD=9600,BITS=8,XMIT=PIN_C6,RCV=PIN_C7)
int channel;
Main()
{
while(1)
{
channel=0;
do
{
channel=channel+1;
switch(channel){
case 1:
putc('A');
delay_ms(100);
break;
case 2:
putc('B');
delay_ms(100);
break;
case 3:
putc('C');
delay_ms(100);
break;
}
delay_ms(100);
}
while(channel<3);
}
}
/****************** RECEIVER *****/
#include <16f873.h>
#fuses xt,nowdt,put,nolvp
#use delay(clock=4000000)
#use RS232(BAUD=9600,BITS=8,XMIT=PIN_C6,RCV=PIN_C7)
#include <lcd2.c>
CHAR dat;
#INT_RDA
RECEPT_INTERRUPT()
{
switch (dat)
{
case 'A':
lcd_gotoxy(1,1);
lcd_putc("Detect.A");
delay_ms(3000);
case 'B':
lcd_gotoxy(1,1);
lcd_putc("Detect.B");
delay_ms(3000);
case 'C':
lcd_gotoxy(1,1);
lcd_putc("Detect.C");
delay_ms(3000);
}
}
main()
{
lcd_init();
enable_interrupts(int_rda);
ENABLE_INTERRUPTS(GLOBAL);
while(1)
{
dat=getch();
lcd_gotoxy(1,1);
lcd_putc("Run");
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516606 |
|
|
sar
Joined: 08 Sep 2003 Posts: 36
|
Re: 16F873 AND RS-232 |
Posted: Sat Aug 02, 2003 12:46 pm |
|
|
Hi
For examples on internet try: <a href="http://www.vermontficks.org/pic.htm" TARGET="_blank">http://www.vermontficks.org/pic.htm</a>
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516607 |
|
|
R.J.Hamlett Guest
|
Re: 16F873 AND RS-232 |
Posted: Sat Aug 02, 2003 2:55 pm |
|
|
:=Hi all
:=We try to comunicate two 16F873 by RS-232 port using interrupts.
:=We not sure if the programs are correct, because on receiver LCD not appears nothing.
:=We try to locate examples on Internet, and not found nothing
:=Please Help to run the programs.
:=
:=//*********************EMITER*********************
:=#include <16f873.h>
:=#fuses xt,nowdt,put,nolvp
:=#use delay(clock=4000000)
:=#use fast_io(A)
:=#use fast_io(B)
:=#use RS232(BAUD=9600,BITS=8,XMIT=PIN_C6,RCV=PIN_C7)
:=int channel;
:=
:=Main()
:={
:=while(1)
:={
:= channel=0;
:= do
:= {
:= channel=channel+1;
:=
:= switch(channel){
:= case 1:
:= putc('A');
:= delay_ms(100);
:= break;
:=
:= case 2:
:= putc('B');
:= delay_ms(100);
:= break;
:=
:= case 3:
:= putc('C');
:= delay_ms(100);
:= break;
:= }
:= delay_ms(100);
:= }
:= while(channel<3);
:=}
:=}
This will send 'A', then 'B', then 'C', at 100mSec intervals, then stop (there is nothing to reset the counter).
:= /****************** RECEIVER *****/
:= #include <16f873.h>
:= #fuses xt,nowdt,put,nolvp
:= #use delay(clock=4000000)
:= #use RS232(BAUD=9600,BITS=8,XMIT=PIN_C6,RCV=PIN_C7)
:= #include <lcd2.c>
:= CHAR dat;
:=#INT_RDA
:=RECEPT_INTERRUPT()
:= {
:= switch (dat)
:= {
:= case 'A':
:= lcd_gotoxy(1,1);
:= lcd_putc("Detect.A");
:= delay_ms(3000);
This should work on it's own, but there is no way for the character to get into 'dat', and the code is now 'stuck' in the interrupt handler for 3 seconds. _Do not put delays in the interrupt handler, unless they are absolutely unavoidable_. They are uneccessary in this context, and will cause problems. Interrupt code should allways be kept as quick as possible, if another interrupt is likely...
:= case 'B':
:= lcd_gotoxy(1,1);
:= lcd_putc("Detect.B");
:= delay_ms(3000);
:= case 'C':
:= lcd_gotoxy(1,1);
:= lcd_putc("Detect.C");
:= delay_ms(3000);
:=
:= }
:=}
:=
:=main()
:={
:= lcd_init();
:= enable_interrupts(int_rda);
:= ENABLE_INTERRUPTS(GLOBAL);
:= while(1)
:= {
:= dat=getch();
You do _not_ want this line. This will attempt to wait for a character to arrive, and then read it. On the basis of the peculiarity of enabling a receive interrupt handler, then never reading the value in the handler to clear the interrupt, combined with trying to read the character in the main at the same time, I am not suprised it doesn't work. What will happen, is that a character arrives, and the interrupt handler is immediately called. No character has been read (since the interrupt handler is called before the 'polled' read routine can respond). Then in the interrupt handler, you do not read the character, but the handler will clear the interrupt flag. The 'polled' routine here, then does not know that a character exists (since it is looking for this flag), and will permanently loop. When the next character arrives, the 'buffer overrun' error will be set, and the interrupt handler again called, with the same effect, except now the UART is 'hung', with an overrun error...
:= lcd_gotoxy(1,1);
:= lcd_putc("Run");
:= }
:=}
The interrupt routine, is where the character should be read. Do something like this:
#INT_RDA
void RECEPT_INTERRUPT(void)
{
dat=getch();
}
main()
{
lcd_init();
enable_interrupts(int_rda);
ENABLE_INTERRUPTS(GLOBAL);
while(1)
{
while (dat==0);
//Wait here for character.
switch (dat)
{
case 'A':
lcd_gotoxy(1,1);
lcd_putc("Detect.A");
break;
//You were omitting the break, so all cases would
//execute one after the other, once the first condition
//was met, but this never happened, because the character
//was never transfered to 'DAT'...
case 'B':
lcd_gotoxy(1,1);
lcd_putc("Detect.B");
break;
case 'C':
lcd_gotoxy(1,1);
lcd_putc("Detect.C");
break;
default:
lcd_gotoxy(1,1);
lcd_putc("Another");
break;
}
dat=0;
}
}
Increase the time between _sending_ the characters to 3 seconds, if you want this spacing. The receiver waits for a character, so the timing is dependant on the 'master'.
Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516610 |
|
|
|
|
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
|