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

RS232 ISR problem

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








RS232 ISR problem
PostPosted: Mon Mar 14, 2005 10:14 am     Reply with quote

Hi,

I'm returning to using a PIC again for a test application. I'm using compiler version 2.728 and am having a problem with a comms ISR.

I've effectively got the following code:


#include <16F877.H>
// DDRs
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte TRISC = 0x87
#byte TRISD = 0x88
#byte TRISE = 0x89

// Port registers
#byte PORTA = 0x05
#byte PORTB = 0x06
#byte PORTC = 0x07
#byte PORTD = 0x08
#byte PORTE = 0x09

#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define CSTX ('?')
#define CETX ('!')
#define BUFFER_SIZE 32

byte rx_buffer[BUFFER_SIZE];
byte rx_index;
byte rx_message_in;

void main(void)
{
InitPorts();

enable_interrupts(global);
enable_interrupts(int_rda);

rx_index = 0;
rx_message_in = 0;

while(1)
{
output_high( PIN_E1 );
output_low( PIN_E1 );

if( rx_message_in )
{
rx_message_in = 0;
}
}
}

#int_rda
void serial_isr(void)
{
byte inchar;

inchar = getc();

switch(inchar)
{
case CSTX :
rx_index = 0;
break;
case CETX:
rx_message_in = 1;
break;
default:
rx_buffer[rx_index] = inchar;
rx_index = (rx_index + 1) % BUFFER_SIZE;
break;

}
}

void InitPorts(void)
{
TRISA = 0x00;
TRISB = 0xC0;
TRISC = 0xC0;
TRISD = 0x00;
TRISE = 0x00;
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
}



This is just test code to obtain a string under interrupt and to set a flag once the ETX char is obtained.

Now, if I only perform the TRISA and PORTA actions, everything works fine and I can rx chars under interrupt ok.

As soon as I set TRIS for ports B/C, I start to get frame errors in the comms.

I've checked the SFRs and everything looks to be ok but clearly something is amiss.

I've even tried repeating the "#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)" declaration at the end of initialising the ports but that didn't work either.

I'm running the code on an advanced transdata parallel ICD so I suspect that TRIS operations either upset the ICD..or the comms I/O...or both.

As I can't see what CCS does with the port for the comms, it's hard to know what might be wrong.

Anyone help, please? And don't just say, 'upgrade your compiler' (unless, of course, it IS a bug in the compiler).

Regards,
Dan
Ttelmah
Guest







PostPosted: Mon Mar 14, 2005 10:44 am     Reply with quote

If you are going to set TRIS for a port, add the specification #use fast_io(x) where 'x' is the port letter. This is necessary to tell CCS to leave the TRIS register alone.
There was a bug with the ICD core from Microchip for the 877 chip, which applies to any ICD unit, that uses their core in this version (most ICD's use the MicroChip core), which required the TRIS settings for the comms to differ from those in the data sheet. On units affected, the TRIS bits have to be 10, not 11. This caused me no end of hassles in the past...
Add 'NOLVP' to your fuses. Though it probably should not apply with the ICD, if this is enabled, RB3 is the serial programming pin, and can cause problems...

Best Wishes
Guest








PostPosted: Tue Mar 15, 2005 2:07 am     Reply with quote

Hi,

Thanks for the quick reply. Initially, I thought you'd cracked it but it still will not work properly. The code is now:



#include <16F877.H>

#use fast_io(B)
#use fast_io(C)

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define CSTX ('?')
#define CETX ('!')

#define BUFFER_SIZE 32

byte rx_buffer[BUFFER_SIZE];
byte rx_index;
byte rx_message_in;

void main(void)
{
SET_TRIS_B( 0xFF ); // not 0xC0 due to ICD bug
SET_TRIS_C( 0xFF );

enable_interrupts(global);
enable_interrupts(int_rda);

rx_index = 0;
rx_message_in = 0;

while(1)
{
output_high(PIN_E1);
output_low(PIN_E1);
}
}

#int_rda
void serial_isr(void)
{
byte inchar;

inchar = getc();

switch(inchar)
{
case CSTX :
rx_index = 0;
break;
case CETX:
rx_message_in = 1;
break;
default:
rx_buffer[rx_index] = inchar;
rx_index = (rx_index + 1) % BUFFER_SIZE;
break;
}
}



Now, if I set both TRISB and TRISC to 0xFF respectively, as shown, then the comms works ok.

If I set them to 0xC0 and 0x80 respectively, it doesn't work.
If I set them to 0xC0 and 0xC0 respectively, it doesn't work.

I even tried 0x80 and 0xC0 respectively and it still doesn't work.

The only other thing I can think of is an intermittant fault somewhere but it's too consistent for that, IMO.

Also, I had thought it might be a problem with WinXP and the advanced transdata IDE because the programming front end gets so far with counting up the locations flashed but then appears to hang (the window isn't updated)...before resuming normally when I suspect it's programmed everything. If I check the program memory, all the code is there. Besides, again, it seems too consistent to be this. i.e. if I swap back to working code, it always works.

Also, if I set TRISC to 0xFF, it has changed to 0xBF following me break pointing on rx of the '?' in the isr.

If I set TRISC to 0xC0 and TRISB to 0xFF, it doesn't work. When I check TRISC, the port is set to 0x80 anyway.

If I set TRISC to 0xBF and TRISB to 0xFF, it works.

It's a strange one. Oh well, that's embedded systems for you.

Cheers,
Dan
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 15, 2005 8:50 am     Reply with quote

You're using the Advanced Transdata parallel ICD. Their chart
says they do use RB6 and RB7 when in debug mode, which is the
mode that I suspect you're using.
http://web.archive.org/web/20020619162228/www.adv-transdata.com/ICD_comparison.htm

Also, in their data sheet, they reserve certain areas of ROM and RAM.
It could be that your program is using those areas. You should use
the #org and #reserve statements to prevent the compiler from using
those areas. See the READ.ME file, which will be in the c:\Picc folder.
http://web.archive.org/web/20030423192149/www.adv-transdata.com/Data_Sheets/DS_ICD87XP.pdf
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Tue Mar 15, 2005 8:52 am     Reply with quote

Following is a piece of text posted by PCM programmer in the
Old Forum at October 22, 2000 at 17:23:31:

Quote:

Posted by PCM programmer (209.85.139.111) on October 22, 2000 at 17:23:31:

I found a problem with the compiler. It fails with
vs. 2.693, and vs. 2.727 (and probably a lot of others).

I had a local variable in my #int_rda function, called "temp".
The compiler assigned this variable to the same address as
several other locals in other functions.
...............
...............


In those days I remember a lot of interminables discusions regarding the
UART dedicated pins and TRISC overlaping that were solved after.

For your sanity I strongly recommend try to get a new and more stable
version. Wink

Best wishes,

Humberto
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