CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

2 Interrupt for 2 ch rs232 not work

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
trirath



Joined: 14 Jun 2010
Posts: 20
Location: Pathunthanee Thailand

View user's profile Send private message

2 Interrupt for 2 ch rs232 not work
PostPosted: Tue Jun 29, 2010 4:29 am     Reply with quote

#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

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 4:31 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Jun 29, 2010 7:19 am     Reply with quote

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: 19338

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 8:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 8:44 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 9:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 9:48 am     Reply with quote

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: 19338

View user's profile Send private message

PostPosted: Tue Jun 29, 2010 10:09 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jun 30, 2010 5:12 am     Reply with quote

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

View user's profile Send private message

priority Interrupt
PostPosted: Thu Jul 01, 2010 6:24 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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