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

Strange behavior when NOT using ICD=TRUE

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



Joined: 09 Jun 2004
Posts: 52

View user's profile Send private message

Strange behavior when NOT using ICD=TRUE
PostPosted: Fri Sep 17, 2010 12:27 pm     Reply with quote

I am wanting to use a PIC to receive Binary data over an RS232 line. To test this, I have wired up a LED Bargraph (cathodes to Port D, anodes to +5v) so that I can display what the UART actually received.

When the UART receives a byte, I do a bit-invert, then write that out to Port D. The inverted bits are now '0' out of the port, turning on the LED segment.

I am using the PIC 16F877A Development kit, PCW v4.069, CCS's ICD-U40, and the SIOW program that comes with PCW.

The SIOW has a screen that allows you to send hex data to the serial port. Entering '0' and hitting 'send' sends a data byte of 0 across, and none of the LED segments should light. Sending 'FF' should light all of the LED segments.

With #device ICD=TRUE set, the system behaves as expected. However, when I remove the ICD=TRUE directive it does NOT work correctly. Up through maybe 7F things work as expected, but if I enter 'FF' I see the LEDs flash on, then immediately off. I also get this odd behavior on some other values, which doesn't seem to have any logic to the pattern.

What's going on here with ICD=TRUE?????

Here is the entire code:
Code:


#include <16F877A.h>
//#device ICD=TRUE
#device *=16
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


BOOLEAN rd_ready;
BYTE received_data;

#int_rda    //receive data is available
void serial_isr()
   {
   if(rd_ready == false)
      {
      received_data = getc();
      rd_ready = true;
      }
   }


void main()
   {
   enable_interrupts(int_rda);
   enable_interrupts(global);
   do {
      if(rd_ready == true)
         {
         received_data ^= 0xff;  //invert received data, to drive LEDs
         output_d(received_data);
         rd_ready = false;
         }
      }
      while (TRUE);
   }


Cheers,
Steve
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 12:48 pm     Reply with quote

Quote:
#int_rda //receive data is available
void serial_isr()
{
if(rd_ready == false)
{
received_data = getc();
rd_ready = true;
}
}

This is bad design. If you get an RDA interrupt, then you have a byte
in the hardware UART's receive buffer. It must be read, or you'll
keep on getting the interrupt constantly. Don't put a condition on calling
getc() inside the isr. Just get it.

In fact, if more than 2 bytes come in to the hardware UART and you
don't get them, the UART receiver will get an overrun error and it will
lock up. You won't be able to get any bytes until you clear the error.
This is why it's a good idea to add the ERRORS parameter to your
#use rs232() statement. Then the compiler will insert code to
automatically clear any overrun errors that may occur. You'll still lose
the chars, but at least the UART's receiver won't remain locked up.
eyewonder300



Joined: 09 Jun 2004
Posts: 52

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 1:05 pm     Reply with quote

PCM,

I changed the ISR to the following, as per your suggestion;

Code:
#int_rda    //receive data is available
void serial_isr()
   {
   received_data = getc();
   rd_ready = true;
   
   }

This had no effect on the problem of strange behavior when compiled WITHOUT the ICD=TRUE. I still get the (??chip reset??) problem.

Other thoughts?

Cheers,
Steve
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 2:20 pm     Reply with quote

Hopefully some series resistors to the bargraph. Otherwise you are overloading the chip, and potentially resetting it....

Best Wishes
eyewonder300



Joined: 09 Jun 2004
Posts: 52

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 2:28 pm     Reply with quote

Good suggestion on the resistors - I will add them.

BUT.... that is not my problem - the system is not behaving the same when I delete the #device ICD=TRUE statement, as it does when I DO include the statement.

Cheers,
Steve
eyewonder300



Joined: 09 Jun 2004
Posts: 52

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 2:36 pm     Reply with quote

Well, I sure don't understand it, but putting the resistors in line with the LEDs has allowed the board to work as expected, without the ICD=TRUE directive - which is how it would be programmed eventually.

Thanks for the help.

Cheers
Steve
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 2:47 pm     Reply with quote

I did a file comparison (using ExamDiff) between the .LST files with
ICD=TRUE enabled, and with it commented out.

There is a difference in the fuses:

With ICD=TRUE enabled:
Quote:
Word 1: 373A HS NOWDT NOPUT DEBUG NOPROTECT NOBROWNOUT NOLVP NOCPD NOWRT


With ICD=TRUE commented out:
Quote:

Word 1: 3F72 HS NOWDT PUT NODEBUG NOPROTECT BROWNOUT NOLVP NOCPD NOWRT

Other than NODEBUG, two other differences are that ICD=TRUE disables
the PUT fuse and the BROWNOUT fuse. They are enabled when ICD=TRUE
is commented out. What if your bargraph is heavily loading down the
power supply ? What if the Vdd voltage for the PIC is drooping below
the Brownout voltage ? With ICD=TRUE enabled, there is no Brownout
fuse, so the PIC would keep on running (probably) as the Vdd drooped
down to say, 4.0 volts. But without ICD=TRUE, you will have a Brownout
reset. The Vbor voltage for the 16F877A is typically 4.0v, but can be
as high as 4.35 volts.

Solution: Add the series resistors, and/or beef up the power supply.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sat Sep 18, 2010 8:08 am     Reply with quote

With ICD=TRUE I believe the ICD-U40 controls MCLR. If you have not got a say 47k pull up on MCLR then when running without ( icd=true) the ICD-u40
frees MCLR to whatever you have as external circuitry. You probably have a good pull up on MCLR so this advice is just in case you forgot.
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