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

PIC 16F1615 (RDA interrupt) not firing

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



Joined: 19 Jun 2017
Posts: 27

View user's profile Send private message

PIC 16F1615 (RDA interrupt) not firing
PostPosted: Mon Jun 19, 2017 5:00 pm     Reply with quote

I have a 16F1615 I'm trying to receive commands on the chip through rs232 but the RDA interrupt won't fire by any means. I hear that the soft UART can't handle RDA interrupt but in the data sheet it states that it has one UART port. But I'm not sure how to check in the datasheet if it's hardware or software. I'm using it on port C4 for Tx and C5 for Rx(CK). Not sure why this chip doesn't have Rx pin. For some reason in the datasheet it states the port as EUART (no idea why).

My questions are how do i know if the chip really has UART hardware? And if else how could i get rid of the incoming characters without using fgetc, because it disrupts the program by having to wait for characters.

Help and Guidance Appreciated. I'm really new regarding MCUs as you can notice.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 19, 2017 9:19 pm     Reply with quote

Alphada wrote:

The RDA interrupt won't fire by any means.

Try this. If it doesn't work, then post your CCS compiler version.
Code:
#include <16F1615.h>
#FUSES INTRC_IO, NOWDT, BROWNOUT                     
#use delay(clock=4MHz)
 
#pin_select U1TX=PIN_C4
#pin_select U1RX=PIN_C5

#use rs232(baud=9600, UART1, ERRORS)


#int_rda
void rda_isr(void)
{
char c;

c = getc();
putc(c);

}

//==============================
void main()
{

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

while(TRUE);   
}


Alphada wrote:

My questions are how do i know if the chip really has UART hardware?

Set the .LST file in Symbolic mode in the compiler options window.
Then compile and look at the .LST file. See below. The rs232 library
code is clearly talking to the UART's hardware registers. So the compiler
is using the hardware UART:
Code:
........... #use rs232(baud=9600, UART1, ERRORS)
0021:  BTFSS  PIR1.RCIF
0022:  GOTO   021
0023:  MOVLB  03
0024:  MOVF   RC1STA,W
0025:  MOVLB  00
0026:  MOVWF  rs232_errors
0027:  MOVLB  03
0028:  MOVF   RC1REG,W
0029:  MOVWF  @78
002A:  MOVLB  00
002B:  BTFSS  rs232_errors.1
002C:  GOTO   031
002D:  MOVLB  03
002E:  BCF    RC1STA.CREN
002F:  BSF    RC1STA.CREN
0030:  MOVLB  00
*
0034:  BTFSS  PIR1.TXIF
0035:  GOTO   034
0036:  MOVLB  03
0037:  MOVWF  TX1REG


Alphada wrote:

how could i get rid of the incoming characters without using fgetc,
because it disrupts the program by having to wait for characters.

Call kbhit. If it returns true, then call fgetc(). If it returns false, then
don't call it. kbhit() will accept a Stream as the parameter. If you
are using streams, then do that.
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 5:26 am     Reply with quote

re:

Not sure why this chip doesn't have Rx pin. For some reason in the datasheet it states the port as EUART (no idea why).

...EUART means 'Enhanced' UART, it has several features that a 'regular' UART doesn't. Chapter 25 or 26, explains this.

That PIC is one of the newer generation that has PPS (Peripheral Pin Select). As the programmer YOU get to choose (within limits..) what pin has which peripheral attached to it. While there is a default configuration of these special pins they probably are not what you need them to be. Mr. T's program shows the code necessary to set them up as required.

The EUART section (25 or 26) does detail that is it a HARDWARE UART and yes, reading 30-40 pages can be, yawn, boring.. BUT...there is a wealth of important information in there ! Also the UART is a very common peripheral amongst PICs so once you understand one version, the others are easy (well, easier..)

One thing about CCS is that even though there is a HW UART, they may code for a SW UART. Again Mr. T. shows that the listing will detail where the data goes... Just remember that the HW UART MUST be a certain pair of pins ! You cannot use any 2 pins so read the datasheet BEFORE laying out the PCB !

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 9:10 am     Reply with quote

This is an area where we need to expand on CCS's manual.

On a chip without PPS, if you select the hardware UART pins in #USE RS232, the compiler 'defaults' to selecting the hardware UART.
On a chip with PPS, even if the manual shows 'default' pins, the compiler will not assume the hardware UART is there. On these you must always use the #PIN_SELECT statements to tell it where the peripheral physically 'is'.

The peripheral is actually a EUSART, not a EUART. Most of the PIC UART's are in some ways 'enhanced' over the most basic types, but this one supports wake up, 13bit mode, and quite a few other extras.
Alphada



Joined: 19 Jun 2017
Posts: 27

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 1:59 pm     Reply with quote

Thx a lot for your answers, I'm gonna check them.

Compiler version is 5.070

Thx PCM programmer I'm gonna test your code, I tried almost anything but not that directive

#pin_select U1TX=PIN_C4
#pin_select U1RX=PIN_C5

I'm looking forward to it.

Btw I'm using kbhit in the main loop, as you stated, is a workaround but I feel like wasting processor cycles I'm not feeling that quite efficient over the interrupt but it solves the problem at least.

Will post results as soon as I get home.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 2:13 pm     Reply with quote

The 'kbhit' call for a UART, codes as a single bit test instruction. Not exactly a waste....
Alphada



Joined: 19 Jun 2017
Posts: 27

View user's profile Send private message

PostPosted: Wed Jun 21, 2017 12:53 am     Reply with quote

Ttelmah wrote:
The 'kbhit' call for a UART, codes as a single bit test instruction. Not exactly a waste....


You are right not a great waste but if there are delays in code wouldn't it miss keys?

Just wondering.
Alphada



Joined: 19 Jun 2017
Posts: 27

View user's profile Send private message

PostPosted: Wed Jun 21, 2017 12:56 am     Reply with quote

PCM programmer wrote:
Alphada wrote:

The RDA interrupt won't fire by any means.

Try this. If it doesn't work, then post your CCS compiler version.
Code:
#include <16F1615.h>
#FUSES INTRC_IO, NOWDT, BROWNOUT                     
#use delay(clock=4MHz)
 
#pin_select U1TX=PIN_C4
#pin_select U1RX=PIN_C5

#use rs232(baud=9600, UART1, ERRORS)


#int_rda
void rda_isr(void)
{
char c;

c = getc();
putc(c);

}

//==============================
void main()
{

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

while(TRUE);   
}


Alphada wrote:

My questions are how do i know if the chip really has UART hardware?

Set the .LST file in Symbolic mode in the compiler options window.
Then compile and look at the .LST file. See below. The rs232 library
code is clearly talking to the UART's hardware registers. So the compiler
is using the hardware UART:
Code:
........... #use rs232(baud=9600, UART1, ERRORS)
0021:  BTFSS  PIR1.RCIF
0022:  GOTO   021
0023:  MOVLB  03
0024:  MOVF   RC1STA,W
0025:  MOVLB  00
0026:  MOVWF  rs232_errors
0027:  MOVLB  03
0028:  MOVF   RC1REG,W
0029:  MOVWF  @78
002A:  MOVLB  00
002B:  BTFSS  rs232_errors.1
002C:  GOTO   031
002D:  MOVLB  03
002E:  BCF    RC1STA.CREN
002F:  BSF    RC1STA.CREN
0030:  MOVLB  00
*
0034:  BTFSS  PIR1.TXIF
0035:  GOTO   034
0036:  MOVLB  03
0037:  MOVWF  TX1REG


Alphada wrote:

how could i get rid of the incoming characters without using fgetc,
because it disrupts the program by having to wait for characters.

Call kbhit. If it returns true, then call fgetc(). If it returns false, then
don't call it. kbhit() will accept a Stream as the parameter. If you
are using streams, then do that.



Thanks a lot it worked the #pin_select directive enforced hardware UART and RDA its working now, i was stuck there for like 3 days. Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Jun 21, 2017 3:02 am     Reply with quote

That's why it's a sticky at the top of the forum. Twisted Evil

Problem is that it's very 'non obvious' if you are used to PIC's without the relocatable peripherals and there is no warning from the compiler....

On the timing thing, it's an attitude of mind in programming. As an example, currently on a project. Just passed 30000 lines of code. It only contains two 'delays', and both of these are inside CCS routines. These though are short (a few uSec only). All the main delays are handled by 'ticks'. Every sub operation (handling GSM, Bluetooth, data logging, reading external peripherals etc., has it's own 'tick', and the master loop sequences through calling each operation in turn. The operations each have a state machine, and if they want to delay, they set their 'tick', and return immediately. The tick then updates at an interval (on the GSM for example 1/10th second), and the GSM code then gets suspended, till it's tick==0, or an 'event' triggers. The events are things like 'a line has been received', flagged by the interrupt code. So for instance If I send a message, which the data sheet says should reply within 2 seconds, I just send this to an interrupt driven transmit, set the tick to 21 (to allow for the actual transmission), and exit. The routine will then get called back, when either the reply arrives (so will come back with tick!=0, and a line in the buffer), or with tick==0 if the command timed out. The 'idle' state is called if is not doing anything, and this again will receive event flags if for example an unsolicited SMS arrives.
The only operations that suspend the main loop are things like a full system reset if the master configuration file on the server gets changed, and it is sent an SMS to trigger a re-configure, when it'll load the new data, and restart.
Alphada



Joined: 19 Jun 2017
Posts: 27

View user's profile Send private message

PostPosted: Wed Jun 21, 2017 8:45 am     Reply with quote

Ttelmah wrote:
That's why it's a sticky at the top of the forum. Twisted Evil

Problem is that it's very 'non obvious' if you are used to PIC's without the relocatable peripherals and there is no warning from the compiler....

On the timing thing, it's an attitude of mind in programming. As an example, currently on a project. Just passed 30000 lines of code. It only contains two 'delays', and both of these are inside CCS routines. These though are short (a few uSec only). All the main delays are handled by 'ticks'. Every sub operation (handling GSM, Bluetooth, data logging, reading external peripherals etc., has it's own 'tick', and the master loop sequences through calling each operation in turn. The operations each have a state machine, and if they want to delay, they set their 'tick', and return immediately. The tick then updates at an interval (on the GSM for example 1/10th second), and the GSM code then gets suspended, till it's tick==0, or an 'event' triggers. The events are things like 'a line has been received', flagged by the interrupt code. So for instance If I send a message, which the data sheet says should reply within 2 seconds, I just send this to an interrupt driven transmit, set the tick to 21 (to allow for the actual transmission), and exit. The routine will then get called back, when either the reply arrives (so will come back with tick!=0, and a line in the buffer), or with tick==0 if the command timed out. The 'idle' state is called if is not doing anything, and this again will receive event flags if for example an unsolicited SMS arrives.
The only operations that suspend the main loop are things like a full system reset if the master configuration file on the server gets changed, and it is sent an SMS to trigger a re-configure, when it'll load the new data, and restart.


Thanks for taking time to respond on my problem too, I checked and it its in fact a sticky but to be honest I'm new with pic have never read about pin select. I was just following examples and none of them were following that practice. That's why I did not take it in to account.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Jun 21, 2017 9:00 am     Reply with quote

Key now is to move on. Smile

You will find that several of the CCS examples do show #PIN SELECT being used, but 90% of the examples posted here in the forum, date to chips before this capability was launched....
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: PIC 16F1615 (RDA interrupt) not firing
PostPosted: Thu Jun 22, 2017 4:24 am     Reply with quote

Alphada wrote:
I hear that the soft UART can't handle RDA interrupt but in the data sheet it states that it has one UART port. But I'm not sure how to check in the datasheet if it's hardware or software.

My questions are how do i know if the chip really has UART hardware?


Just to go back to the original question: if its in the datasheet it's hardware - the datasheet doesn't deal with anything implemented in software.

CCS C deals with all the various types of hardware UART/EUART/EUSART/whatever and makes them look pretty much all the same. This is a good thing as you, the programmer, doesn't have to worry about the differences, its all handled for you.

CCS C implements software UARTs when there is not suitable hardware, not enough hardware (e.g. requesting two UARTs when there's only one in hardware), or the requested parameters are not supported by hardware, or when the user requests it, e.g. by FORCE_SW. It is easy to inadvertently get a soft UART when you think it should be using hardware by making some request that the hardware connot support, such as incompatible pins.

The software UARTs implemented by CCS are blocking and do not in any sense run "in parallel" with other code, they run as part of and in line with other code. There is no need for interrupts and as far as I am aware there is no way of calling interrupt routines from software in PICs (there is on many other processors, but not PICs I think).

One important thing to remember with this is that when using a soft UART you can only receive characters when the soft UART is actively waiting for them. getc() and it's relatives, must have been called and will wait until a character arrives. kbhit() is pointless as there is no hardware to have received and buffered a character while the code was doing other things. This also means it is far easier to miss incoming characters with a software UART than with hardware: if your code is not waiting in getc() when a character arrives, it will be lost.

Summary:

Kbhit and interrupts are only useful and only work with hardware UARTs.

Receiving data with software UARTs in much more restricted than when using hardware.

Be careful: software UARTs might be used when you don't expect it.

If its in the datasheet, its hardware.

The capabilities of the hardware UARTs can be quite varied. CCS C deals with all that for you.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu Jun 22, 2017 5:54 am     Reply with quote

The way to call an interrupt from code, is to set the interrupt flag....
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