![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
M0KHZ
Joined: 14 Feb 2008 Posts: 18 Location: Cumbria
|
18F6722 serial interrupt problems. |
Posted: Sat Aug 16, 2008 9:03 am |
|
|
Any pointers as to what I'm doing wrong here!
I'm trying to populate a FIFO using a serial interrupt routine.
To prove the comms ports are set up the code below (without the ISR) works fine:
Code: |
#include <18F6722.h>
#device ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=COM2)
#use rs232(baud=9600,parity=O,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=COM1)
// Definitions
boolean serialHasData();
int8 serialRead();
char value;
/// Size of serial input port FIFO in bytes. Must be a power of 2, i.e. 2, 4, 8, 16, etc.
#define SERIAL_BUFFER_SIZE 128
/// Mask to wrap around at end of circular buffer. (SERIAL_IN_BUFFER_SIZE - 1)
#define SERIAL_BUFFER_MASK 0x7f
/// Index to the next free location in the buffer.
int8 serialHead;
/// Index to the next oldest data in the buffer.
int8 serialTail;
/// Circular buffer (FIFO) to hold serial data.
int8 serialBuffer[SERIAL_BUFFER_SIZE];
void serialInit()
{
serialHead = 0;
serialTail = 0;
}
// -----------------------------------------------------------------------------
// Determine if the FIFO contains data.
//
// & return true if data present; otherwise false
// -----------------------------------------------------------------------------
boolean serialHasData()
{
return true;
}
void main(){
serialInit();
while (serialHasData())
{
serialBuffer[serialHead] = getc(COM1);
fputc(serialBuffer[serialHead],COM2);
// Move the pointer to the next open space.
serialHead = (serialHead + 1) & SERIAL_BUFFER_MASK;
}
}
|
However as soon as I initiate the ISR (code below), the IRS isn't triggered and hence nothing is pushed to COM2
Code: |
#include <18F6722.h>
#device ICD=TRUE
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=COM2)
#use rs232(baud=9600,parity=O,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=COM1)
// Definitions
boolean serialHasData();
int8 serialRead();
/// Size of serial input port FIFO in bytes. Must be a power of 2, i.e. 2, 4, 8, 16, etc.
#define SERIAL_BUFFER_SIZE 128
/// Mask to wrap around at end of circular buffer. (SERIAL_IN_BUFFER_SIZE - 1)
#define SERIAL_BUFFER_MASK 0x7f
/// Index to the next free location in the buffer.
int8 serialHead;
/// Index to the next oldest data in the buffer.
int8 serialTail;
/// Circular buffer (FIFO) to hold serial data.
int8 serialBuffer[SERIAL_BUFFER_SIZE];
#INT_RDA
void serialISR()
{
// Save the value in the FIFO.
serialBuffer[serialHead] = getc(COM1);
// Move the pointer to the next open space.
serialHead = (serialHead + 1) & SERIAL_BUFFER_MASK;
}
void serialInit()
{
serialHead = 0;
serialTail = 0;
}
// -----------------------------------------------------------------------------
// Determine if the FIFO contains data.
//
// & return true if data present; otherwise false
// -----------------------------------------------------------------------------
boolean serialHasData()
{
if (serialHead == serialTail)
return false;
return true;
}
void main(){
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
serialInit();
while(true)
{
while (serialHasData())
{
fprintf(COM2,"\nCaptured something in the FIFO - progress at last!\n");
}
}
} |
Has anyone any thoughts?
Kevin - M0KHZ |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 16, 2008 11:37 am |
|
|
Quote: | #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=COM2)
#use rs232(baud=9600,parity=O,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=COM1) |
The first hardware UART is on pins C6 and C7. The 2nd UART is on
pins G1 and G2. You have named them the opposite way.
That may cause confusion. From the data sheet:
Quote: | The pins of EUSART1 and EUSART2 are multiplexed with the
functions of PORTC (RC6/TX1/CK1 and RC7/RX1/DT1) and
PORTG (RG1/TX2/CK2 and RG2/RX2/DT2), respectively. |
Here's where it caused a problem in writing your code.
Quote: |
#INT_RDA
void serialISR()
{
// Save the value in the FIFO.
serialBuffer[serialHead] = getc(COM1);
// Move the pointer to the next open space.
serialHead = (serialHead + 1) & SERIAL_BUFFER_MASK;
}
|
But the interrupt directives are associated like this:
#INT_RDA = pins C6, C7
#INT_RDA2 = pins G1, G2
If you give the 2nd UART the name "COM2", it would be more clear
that you should use #INT_RDA2 for its isr. It's easier to make the
correct choice when you're writing code.
Also, this fuse should be NOLVP. Hardly anyone uses a low voltage
programmer. All commerical programmers are the high voltage type. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Aug 16, 2008 11:41 am |
|
|
For extra stability add the ERRORS directive to the serial port setup. This causes the compiler to add code for clearing the error status bits at very getc call. Without this the UARTS will stall when the input buffer overflows (at 3 characters). |
|
![](templates/subSilver/images/spacer.gif) |
M0KHZ
Joined: 14 Feb 2008 Posts: 18 Location: Cumbria
|
|
Posted: Sun Aug 17, 2008 2:57 am |
|
|
THANKS guys, you've really helped sort out a big headache! the FIFO is now filling on interrupt
All I have to do now is sort out the rest of the code!
Kevin - M0KHZ |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|