|
|
View previous topic :: View next topic |
Author |
Message |
trirath
Joined: 14 Jun 2010 Posts: 20 Location: Pathunthanee Thailand
|
2 Interrupt for 2 ch rs232 not work |
Posted: Tue Jun 29, 2010 4:29 am |
|
|
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,BORV46,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=38400 ,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR)
#use rs232(baud=38400,xmit=PIN_B1, rcv=PIN_B0,STREAM=Client)
#include <stdlib.h>
#include <input.c>
#include <string.h>
#define BUFFER_SIZE_MON 32
//------client Side -----------------
int8 buffer[32];
int8 wr_index=0;
int1 msg_ready=0;
char BUFFER_SIZE;
//---------------------------------
//------MONITOR SIDE---------------
int8 buffer_mon[BUFFER_SIZE_MON+1];
int8 wr_index_mon=0;
int1 msg_ready_mon=0;
//---------------------------------
#int_rda
void serial_mon_isr() {
int8 ch_mon;
ch_mon=getc();
if(ch_mon!='\r' && wr_index_mon < BUFFER_SIZE_MON )
buffer_mon[wr_index_mon++]= ch_mon;
else {
buffer_mon[wr_index_mon++]= '\0';
msg_ready_mon=1;
}
}
#int_ext
void serial_isr() {
int8 ch;
ch=getc();
if(wr_index== BUFFER_SIZE)
{
buffer[wr_index++]=ch;
buffer[wr_index++]='\0';
msg_ready=1 ;}
else buffer[wr_index++]=ch;
}
void main(void){
enable_interrupts(INT_EXT_H2L);
enable_interrupts(int_rda);
enable_interrupts(global);
while(true){
if(msg_ready_mon){
disable_interrupts(int_rda);
fprintf(Client,"%s\r\n>>",buffer_mon);
wr_index_mon=0;
msg_ready_mon=0;
enable_interrupts(int_rda);
}
if(msg_ready){
disable_interrupts(INT_EXT_H2L);
fprintf(MONITOR,"%s\r\n>>",buffer_mon);
wr_index=0;
msg_ready=0;
enable_interrupts(INT_EXT_H2L);
}
}
}
i tried each interrupt it work only 1 intterupt(RDA or EXTB0)
but not work when used both interrupts as above . |
|
|
trirath
Joined: 14 Jun 2010 Posts: 20 Location: Pathunthanee Thailand
|
|
Posted: Tue Jun 29, 2010 4:31 am |
|
|
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,BORV46,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=38400 ,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR)
#use rs232(baud=38400,xmit=PIN_B1, rcv=PIN_B0,STREAM=Client)
#include <stdlib.h>
#include <input.c>
#include <string.h>
#define BUFFER_SIZE_MON 32
//------client Side -----------------
int8 buffer[32];
int8 wr_index=0;
int1 msg_ready=0;
char BUFFER_SIZE;
//---------------------------------
//------MONITOR SIDE---------------
int8 buffer_mon[BUFFER_SIZE_MON+1];
int8 wr_index_mon=0;
int1 msg_ready_mon=0;
//---------------------------------
#int_rda
void serial_mon_isr() {
int8 ch_mon;
ch_mon=getc();
if(ch_mon!='\r' && wr_index_mon < BUFFER_SIZE_MON )
buffer_mon[wr_index_mon++]= ch_mon;
else {
buffer_mon[wr_index_mon++]= '\0';
msg_ready_mon=1;
}
}
#int_ext
void serial_isr() {
int8 ch;
ch=getc();
if(wr_index== BUFFER_SIZE)
{
buffer[wr_index++]=ch;
buffer[wr_index++]='\0';
msg_ready=1 ;}
else buffer[wr_index++]=ch;
}
void main(void){
enable_interrupts(INT_EXT_H2L);
enable_interrupts(int_rda);
enable_interrupts(global);
while(true){
if(msg_ready_mon){
disable_interrupts(int_rda);
fprintf(Client,"%s\r\n>>",buffer_mon);
wr_index_mon=0;
msg_ready_mon=0;
enable_interrupts(int_rda);
}
if(msg_ready){
disable_interrupts(INT_EXT_H2L);
fprintf(MONITOR,"%s\r\n>>",buffer);
wr_index=0;
msg_ready=0;
enable_interrupts(INT_EXT_H2L);
}
}
}
|
sorry edit something |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Jun 29, 2010 7:19 am |
|
|
In your #int_ext routine you are detecting a H_L transition via external interrupt. THe first time that occurs is the start bit. Then you have to manually shift in the remaining bits. You don't have a character until you do all that. So your interrupt handling is incorrect for this case. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Jun 29, 2010 8:38 am |
|
|
The software serial routine handles shifting in the byte.
The first problem is that the correct routines are not being used. The INT_RDA, needs to use fgetc(MONITOR), and the int_ext, fgetc(Client).
As it stands, the code will hang, since the second RS232 will be called by default on a getc. When int_rda triggers it goes to the wrong getc, never clears the character, leaving the interrupt permanently triggering....
38400bps, is only 312 instructions/bit. Now, if the code is in the first interrupt routine, when the falling edge arrives on INT_EXT, it could take as much as perhaps 150 instruction times to get 'out' again (time to save the registers, and enter the routine, if it has _just_ been called, time to get the character, and store it, time to restore the registers and exit). The second routine then gets called (another perhaps 40 instructions to reach the 'getc', meaning that 190 instruction times have now counted by. The getc, will wait for 156 instruction times (half a bit), before sampling the data, so the character will be missed. Change the #use RS232 for the software stream, to:
Code: |
#use rs232(baud=38400,xmit=PIN_B1, rcv=PIN_B0,sample_early,STREAM=Client)
|
Best Wishes |
|
|
trirath
Joined: 14 Jun 2010 Posts: 20 Location: Pathunthanee Thailand
|
|
Posted: Tue Jun 29, 2010 8:44 am |
|
|
Why this case is work for only 1 with int ext?
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,BORV46,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=38400,xmit=PIN_B1, rcv=PIN_B0,STREAM=client )
#include <stdlib.h>
#include <input.c>
#include <string.h>
//------client Side -----------------
int8 buffer[32];
int8 wr_index=0;
int1 msg_ready=0;
char BUFFER_SIZE =4;
//---------------------------------
#int_ext
void serial_isr() {
if(wr_index== BUFFER_SIZE)
{
buffer[wr_index++]=getc();;
buffer[wr_index++]='\0';
msg_ready=1 ;}
else buffer[wr_index++]=getc();;
}
void main(void){
enable_interrupts(global);
enable_interrupts(int_ext_h2l);
while(true){
if(msg_ready){
disable_interrupts(int_ext_h2l);
fprintf(client ,"client to Client %s\r\n>>",buffer);
wr_index=0;
msg_ready=0;
enable_interrupts(int_ext_h2l);
}
|
Put AAAAA
result is >>client to Client AAAAA
It work properly. Why?
I found the code first time I post. If I swap
such as 1)
Code: |
#use rs232(baud= ,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR)
#use rs232(baud=38400,xmit=PIN_B1, rcv=PIN_B0,STREAM=client) |
It will work for the Monitor side but not work for beside Monitor.
Code: |
#use rs232(baud=38400,xmit=PIN_B1, rcv=PIN_B0,STREAM=client)
#use rs232(baud= ,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR) |
It will work for the client but not work for beside monitor. |
|
|
trirath
Joined: 14 Jun 2010 Posts: 20 Location: Pathunthanee Thailand
|
|
Posted: Tue Jun 29, 2010 9:38 am |
|
|
Code: | #include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,BORV46,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600 ,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR)
#use rs232(baud=9600,xmit=PIN_B1, rcv=PIN_B0,STREAM=Client)
#include <stdlib.h>
#include <input.c>
#include <string.h>
#define BUFFER_SIZE_MON 32
//------client Side -----------------
int8 buffer[32];
int8 wr_index=0;
int1 msg_ready=0;
char BUFFER_SIZE=4;
//---------------------------------
//------MONITOR SIDE---------------
int8 buffer_mon[BUFFER_SIZE_MON+1];
int8 wr_index_mon=0;
int1 msg_ready_mon=0;
//---------------------------------
#int_rda
void serial_mon_isr() {
int8 ch_mon;
ch_mon=fgetc(MONITOR);
if(ch_mon!='\r' && wr_index_mon < BUFFER_SIZE_MON )
buffer_mon[wr_index_mon++]= ch_mon;
else {
buffer_mon[wr_index_mon++]= '\0';
msg_ready_mon=1;
}
}
#int_ext
void serial_isr() {
if(wr_index== BUFFER_SIZE)
{
buffer[wr_index++]=getc(Client);
buffer[wr_index++]='\0';
msg_ready=1 ;}
else buffer[wr_index++]=getc(Client);
}
void main(void){
enable_interrupts(INT_EXT_H2L);
enable_interrupts(int_rda);
enable_interrupts(global);
while(true){
if(msg_ready_mon){
disable_interrupts(int_rda);
fprintf(MONITOR,"MOnitor to Monitor %s\r\n>>",buffer_mon);
fprintf(Client,"MOnitor to Client %s\r\n>>",buffer_mon);
wr_index_mon=0;
msg_ready_mon=0;
enable_interrupts(int_rda);
}
if(msg_ready){
disable_interrupts(INT_EXT_H2L);
fprintf(Client,"client to client %s\r\n>>",buffer);
fprintf(MONITOR,"client to MONITOR %s\r\n>>",buffer);
wr_index=0;
msg_ready=0;
enable_interrupts(INT_EXT_H2L);
}
}
} |
Thank you Ttelmah
I tried with you but work well for client to monitor but not work in case of monitor to client.
In case 2 it not affect any. |
|
|
trirath
Joined: 14 Jun 2010 Posts: 20 Location: Pathunthanee Thailand
|
|
Posted: Tue Jun 29, 2010 9:48 am |
|
|
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,BORV46,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600 ,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR)
#use rs232(baud=9600,xmit=PIN_B1, rcv=PIN_B0,STREAM=Client)
#include <stdlib.h>
#include <input.c>
#include <string.h>
#define BUFFER_SIZE_MON 32
//------client Side -----------------
int8 buffer[32];
int8 wr_index=0;
int1 msg_ready=0;
char BUFFER_SIZE=4;
//---------------------------------
//------MONITOR SIDE---------------
int8 buffer_mon[BUFFER_SIZE_MON+1];
int8 wr_index_mon=0;
int1 msg_ready_mon=0;
//---------------------------------
#int_rda
void serial_mon_isr() {
int8 ch_mon;
ch_mon=fgetc(MONITOR);
if(ch_mon!='\r' && wr_index_mon < BUFFER_SIZE_MON )
buffer_mon[wr_index_mon++]= ch_mon;
else {
buffer_mon[wr_index_mon++]= '\0';
msg_ready_mon=1;
}
}
#int_ext
void serial_isr() {
if(wr_index== BUFFER_SIZE)
{
buffer[wr_index++]=fgetc(Client);
buffer[wr_index++]='\0';
msg_ready=1 ;}
else buffer[wr_index++]=fgetc(Client);
}
void main(void){
enable_interrupts(INT_EXT_H2L);
enable_interrupts(int_rda);
enable_interrupts(global);
while(true){
if(msg_ready_mon){
disable_interrupts(int_rda);
fprintf(MONITOR,"MOnitor to Monitor %s\r\n>>",buffer_mon);
fprintf(Client,"MOnitor to Client %s\r\n>>",buffer_mon);
wr_index_mon=0;
msg_ready_mon=0;
enable_interrupts(int_rda);
}
if(msg_ready){
disable_interrupts(INT_EXT_H2L);
fprintf(Client,"client to client %s\r\n>>",buffer);
fprintf(MONITOR,"client to MONITOR %s\r\n>>",buffer);
wr_index=0;
msg_ready=0;
enable_interrupts(INT_EXT_H2L);
}
}
}
|
Latest code: still work for client to monitor but not work for Monitor to client. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Jun 29, 2010 10:09 am |
|
|
Comments:
You still have not added 'sample_early' to the software RS232 definition. You need it.
You have a huge problem with the printout. The printout takes something like 22 character times, and during the whole of this, you have the interrupt disabled. You cannot use a software RS232, as 'full duplex'. While you are sending, data will be lost. If interrupts are left 'on' character timings on the output will be destroyed. If left off, incoming characters will be missed.
Best Wishes |
|
|
trirath
Joined: 14 Jun 2010 Posts: 20 Location: Pathunthanee Thailand
|
|
Posted: Wed Jun 30, 2010 5:12 am |
|
|
If add 'sample_early' like this
Code: |
#use rs232(baud=9600 ,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR)
#use rs232(baud=9600,xmit=PIN_B1, rcv=PIN_B0,sample_early,STREAM=Client)
|
The result is (test with sent 'A' from terminal 5 times Client side).
Also I tried to test sent first from Monitor side but anything quite.
result:
client to MONITOR is `AAAA lost 1 byte <--- This appear after first start(reset or On-off PIC)
client to client is `AAAA lost 1 byte<--- This appear after first start(reset or On-off PIC)
client to MONITOR AAAAA <-- Next since 2nd is good
client to client AAAAA <-- Next since 2nd is good
However, a side monitor can not receive and send to both monitor and client, or sometimes does work, sometimes does not work!?
If I moved 'sample_early' out, the client side works properly but still not work for monitor side.
client to MONITOR AAAAA <-- Since power on or reset. It work fine.
client to client AAAAA <-- Since power on or reset. It work fine.
Please suggest again (I trial and error over and over again but any thing still the same. Also add 'sample_early' into
Code: |
#use rs232(baud=9600 ,xmit=PIN_C6, rcv=PIN_C7,sample_early, STREAM=MONITOR)
|
only client work fine but Monitor side quite!
I expected the #int_ext routine is good except #int_rda (Test #int_rda Stand Alone is work fine). |
|
|
trirath
Joined: 14 Jun 2010 Posts: 20 Location: Pathunthanee Thailand
|
priority Interrupt |
Posted: Thu Jul 01, 2010 6:24 am |
|
|
hi Ttelmah and all
I found that code is working very well when use for PIC16F873A.
Code: |
#include <16F873A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=38400,xmit=PIN_C6, rcv=PIN_C7,STREAM=MONITOR)
#use rs232(baud=38400,xmit=PIN_B1, rcv=PIN_B0,STREAM=client) |
I think a problem about the priority interrupt but I don't know how to do code as I read CCS manual.
BR |
|
|
|
|
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
|