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 CCS Technical Support

How to use #INT_RDA with PIC18F with 2 EUSARTs inside?

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



Joined: 06 Dec 2010
Posts: 25

View user's profile Send private message

How to use #INT_RDA with PIC18F with 2 EUSARTs inside?
PostPosted: Wed Jun 01, 2016 7:52 pm     Reply with quote

I have a PIC18F MCU that has 2 EUSART inside.

I have written this code:

Code:
#include <main.h>

volatile unsigned int16 bcount = 0;
volatile bool brx = FALSE;

#INT_RDA1
void  RDA_isr(void)
{
   bcount++;
   brx = TRUE;
}

void main()
{

   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

   setup_uart(9600, PORT1);
   putc(XON);

   set_tris_b(0);

   while(TRUE)
   {
      if (brx==TRUE)
      {
         getc();
         brx = FALSE;
      }
      //TODO: User Code
      if (bcount==64)
      {
         putc(XOFF);
      }
      output_b(bcount);
   }
   
}


It is clear that the interrupt is not being launched. I am sending characters from the PC. Testing demonstrates both above statements to be true.

I am using EasyPIC Pro board with PIC18F87K22 and CCS compiler. The second EUSART of the PIC (pins G1 and G2) is connected to the MAX232 in this case.

When I try to use #INT_RDA0 or #INT_RDA1, my program does not compile even though the documentation does say that there are things called #INT_RDA0 and #INT_RDA1. What nonsense is this?

Note that in the main.h, I have written:
Code:

#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=PORT1)

typedef unsigned int8 bool;

#define XOFF 0x13
#define XON  0x11


Finally, I must say that when I use kbhit() in the while loop in main routine, IT WORKS! But not with interrupt!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 01, 2016 9:47 pm     Reply with quote

Quote:

When I try to use #INT_RDA0 or #INT_RDA1, my program does not
compile even though the documentation does say that there are things
called #INT_RDA0 and #INT_RDA1. What nonsense is this?

Look at the end of the 18F87K22.h file. It lists all the correct names for
the interrupts.
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Wed Jun 01, 2016 11:06 pm     Reply with quote

PCM_programmer has given you the first key piece of data.

As a further comment though the names must be the same everywhere you use them. INT_RDA, enables INT_RDA, and the routine to handle this must use #INT_RDA as it's name.
Each interrupt is separate. So INT_RDA enables the interrupt for UART1 _only_. You seem to be thinking that this will enable both UART's it doesn't.

Then to use more than one port at the same time, you need to be using streams. So two #use rs232 declarations, one for the first UART, and one for the second, with different stream names. (Perhaps PORT1, and PORT2). Then in the INT_RDA, you must read from the stream corresponding to this UART (fgetc(UART1)....). Similarly if using kbhit, you again use the stream name so it tests the right port. (kbhit(UART1)). Similarly for sending data, you use fputc, and fprintf.
matrixofdynamism



Joined: 06 Dec 2010
Posts: 25

View user's profile Send private message

Note using UART1
PostPosted: Thu Jun 02, 2016 4:09 am     Reply with quote

I am only using the UART2 since I am forced to do so. UART1 of the PIC is not connected to the MAX232 chip.

Also, it seems rather unfortunate that both the UARTs are to be serviced via #INT_RDA, very strange. I will check the header file and see what it says.

Do I understand correctly that the reason the program does not even compile when I use #INT_RDA0 or #INT_RDA1 is because they are not defined in the header file?
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: Note using UART1
PostPosted: Thu Jun 02, 2016 4:43 am     Reply with quote

matrixofdynamism wrote:
Also, it seems rather unfortunate that both the UARTs are to be serviced via #INT_RDA, very strange.


No. The first uart, UART1, is serviced by #INT_RDA (no 0, no 1 or anything else - this is for backwards compatiliblty reasons with/when PICs had only one UART). The second, through #INT_RDA2.


Quote:
Do I understand correctly that the reason the program does not even compile when I use #INT_RDA0 or #INT_RDA1 is because they are not defined in the header file?


No. It would not work even if you defined them in the header file - and please DO NOT edit or add to those headers.

#INT_RDA - receive interrupt for the first UART
#INT_RDA2 - receive interrupt for the second UART
#INT_RDA3 - receive interrupt for the third UART
etc.

The interrupt routine MUST read the character. The interrupt tells the code that a character is available to be read. The ISR will be continually re-entered if it is NOT read. Your ISR doesn't read the character, so would not work even if it was correctly called.

When using more than one UART, or when using one that is NOT the first, as you re doing, it is best to use stream names. The compiler can't read your mind; it doesn't know that when you call getc(), without a stream name, that you want it to read the second UART. Instead it will/may try to get a character, which isn't there, from the first UART. As your code stands, you DO define a stream name for the UART, which is good, but you don't use that in your getc() and putc() calls, which is not so good.
matrixofdynamism



Joined: 06 Dec 2010
Posts: 25

View user's profile Send private message

Re: Note using UART1
PostPosted: Fri Jun 03, 2016 7:12 am     Reply with quote

Quote:
The interrupt routine MUST read the character.


Really? This means that if I set a flag in the interrupt and use the main subroutine to read the character (similar to using kbhit for polling), the program will not function as expected?
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

PostPosted: Fri Jun 03, 2016 7:48 am     Reply with quote

What happens on most microcontrollers is if you don't read the byte in the ISR, then even if you manually clear the interrupt condition, the hardware will re-assert it, triggering the interrupt to fire again immediately as soon as you leave it...putting you in an infinite loop of ISR calls.
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

Re: Note using UART1
PostPosted: Fri Jun 03, 2016 7:52 am     Reply with quote

matrixofdynamism wrote:
Quote:
The interrupt routine MUST read the character.


Really? This means that if I set a flag in the interrupt and use the main subroutine to read the character (similar to using kbhit for polling), the program will not function as expected?


Why bother using interrupts at all? Just poll for received characters in main().

Sort of like saving for years to buy a vehicle, finally being able to afford the one you want, purchasing it, then parking it in the garage so you can continue to ride the bus. ....Why did you bother buying it?
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Fri Jun 03, 2016 8:15 am     Reply with quote

Have a look at ex_sisr.c

This shows how to use the interrupt to give an interrupt driven software buffer. You then use 'bkbit' to see if a character is waiting.

Key point is that the UART has just under two characters of buffering. One 'buffered' character, and one 'in transit' (being assembled in the receive buffer). If you don't handle a character before these overflow, then a character is lost. Add the interrupt buffer and you can extend buffering by another 4, 8, 16, 32 characters (binary values are slightly better - search here for 'why').

Then if your code can poll for a few mSec, the date gets buffered and is waiting for you when you do reach the poll point.

If you want to poll without buffering, then having the interrupt is a waste of code, and time.
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