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

weird problem with simple LED output

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



Joined: 25 Feb 2006
Posts: 23

View user's profile Send private message

weird problem with simple LED output
PostPosted: Thu Nov 27, 2008 12:17 pm     Reply with quote

I'm running this code
Code:
#include <16F676.H>
#DEVICE ADC=8
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT
#use delay(clock = 4000000)
setup_oscillator(OSC_4MHZ);
//#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1)

#include "debug.h"
#include "io_init.h"

int test;
main()
{
set_tris_c (0);
   initialization();

//test
enable_interrupts(GLOBAL);
setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_256    );
enable_interrupts(INT_RTCC);
//
set_tris_c (0);
   while(1)
   {

         output_high(PIN_C5);
         delay_ms(1000);
         output_low(PIN_C5);
         delay_ms(1000);
       
   }

}
#INT_TIMER0
void timer0_test(){

if (input(PIN_c1))
{
   output_low(PIN_c1);
}
else
   output_high(PIN_c1);
}


When I probe pin c1 without an LED connected, I could see a square wave. When I connected an LED with series 200ohm resistor, C1 stops oscillating and the voltage drops to a constant 3.0V. Why in the world would it stop oscillating and the voltage drops to 3.0V?

Normally I would expect the LED to blink but it doesn't. The LED connected to C1 stays solid because C1 stops oscillating with voltage a constant 3V.

Why does C1 stop oscillating when I connect an LED to it?

Thanks.
david90



Joined: 25 Feb 2006
Posts: 23

View user's profile Send private message

PostPosted: Thu Nov 27, 2008 12:36 pm     Reply with quote

just an update. PIN C1 work like I expected if I change my code to this
Quote:
#include <16F676.H>
#DEVICE ADC=8
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT
#use delay(clock = 4000000)
setup_oscillator(OSC_4MHZ);
//#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1)

#include "debug.h"
#include "io_init.h"

int test;
main()
{
set_tris_c (0);
initialization();

//test
enable_interrupts(GLOBAL);
setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_256 );
enable_interrupts(INT_RTCC);
//
set_tris_c (0);
while(1)
{

output_high(PIN_C2);
delay_ms(1000);
output_low(PIN_C2);
delay_ms(1000);

}

}
#INT_TIMER0
void timer0_test(){
disable_interrupts(GLOBAL);

output_low(PIN_c1);
delay_ms(1000);
output_high(PIN_c1);
delay_ms(1000);
enable_interrupts(GLOBAL);
}


So there must be something wrong with this code
Code:
if (input(PIN_c1))
{
   output_low(PIN_c1);
}
else
   output_high(PIN_c1);


I have this problem with 16F676 TSSOP package but not with the DIL. The 16F676 DIL runs fine with the same code on a dev board. Wierd. Question Question Question Question
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 27, 2008 1:09 pm     Reply with quote

Quote:
#include <16F676.H>
#DEVICE ADC=8
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT
#use delay(clock = 4000000)
setup_oscillator(OSC_4MHZ);
//#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1)

The line in bold above doesn't do anything. It must be inside a function
to work. Normally you would get an error for this, but in some older
versions of the compiler it won't give an error.


Quote:
#INT_TIMER0
void timer0_test(){
disable_interrupts(GLOBAL);
output_low(PIN_c1);
delay_ms(1000);
output_high(PIN_c1);
delay_ms(1000);
enable_interrupts(GLOBAL);
}

Don't enable/disable global interrupts inside an isr. The PIC and the
compiler handle this completely for you. What you are doing is in fact
dangerous. If you had another interrupt running (such as #int_rda, etc)
then you could get an interrupt while inside your ISR. Nested interrupts
are not support in the PIC16, so your program would crash. Delete both
lines in bold.


Also, if you have warnings enabled, you would get a message about
"interrupts disabled to prevent re-entrancy". Normally we don't put
delays in an isr. If you want to do this (for a test program) then you
should create another instance of the CCS library code for delays.
This is done by adding another #use delay() statement above the isr.
Example:
Quote:

#use delay(clock = 4000000)
#INT_TIMER0
void timer0_test(){
output_low(PIN_c1);
delay_ms(1000);
output_high(PIN_c1);
delay_ms(1000);
}



Quote:
output_low(PIN_c1);

Also, most C compilers are case sensitive. CCS has case sensitivity
disabled by default, so your Pin constant will compile OK with it.
But it's a good idea not to get into a bad habit. Use the correct name
of PIN_C1.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Nov 27, 2008 2:16 pm     Reply with quote

Referring to the original problem, that is unrelated to the other points mentioned by PCM prorammer:

You should try input_state(PIN_C1) instead of input(PIN_C1) and also may want to consult the manual about operation of input() function with default #use standard_io in effect.

Everything is correct! Just consider, that input() first sets the port to tristate and then (after a fraction of a microsecond) reads the input state. With a strong load, the state can change in between.
Ttelmah
Guest







PostPosted: Thu Nov 27, 2008 3:26 pm     Reply with quote

A pin will only _read_ as high or low, if the signal actually reaches the logic thresholds for high and low respectively.
Depending on what series resistance you have feeding the LED, voltage levels around the chip, and the Vf needed for the LED, it may be 'borderline' for the driven pin to actually get to the required levels. A tiny difference in the threshold voltage between the two PICs, and you have 'it works on one, but not the other'...

Best Wishes
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Fri Nov 28, 2008 12:02 am     Reply with quote

You may be the victim of the Read-Modify-Write problem, inherent in 16 series PICs. This is a good link to understand what the RMW problem is:

http://www.marcansoft.com/subidos/readmodifywrite.pdf

(Don't remember who posted this link - Ttelmah or PCM - but thanks for sharing it! Very Happy )

Rohit
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Nov 28, 2008 12:53 am     Reply with quote

I don't think it's a read-modify-write problem here. It's rather a problem of unintentionally setting the port to tristate by input() in standard_io mode.

But it can happen when stressing the port outputs up to 25 mA maximum current. You can, by the way, also use TRIS to switch the LED. It can be read back unaffected from the port voltage level.
david90



Joined: 25 Feb 2006
Posts: 23

View user's profile Send private message

PostPosted: Fri Nov 28, 2008 7:33 pm     Reply with quote

FvM wrote:
Referring to the original problem, that is unrelated to the other points mentioned by PCM prorammer:

You should try input_state(PIN_C1) instead of input(PIN_C1) and also may want to consult the manual about operation of input() function with default #use standard_io in effect.

Everything is correct! Just consider, that input() first sets the port to tristate and then (after a fraction of a microsecond) reads the input state. With a strong load, the state can change in between.


Your suggestion works. My LED now blinks but there is still a voltage level problem on that pin. The waveform osc. from 3V to 5V instead of 0V to 5V.

update: I tried to decrease the output current by using a 10kohm instead of 200ohm and that made the pin osc from 0V to 5V. Why does this happen?

The resistor that I usually use in series with my LED is 200 OHm

5-1.7V = 3.3V
3.3/200 = 16.5mA

16.5mA is way under the abs. max so I don't think I'm overloading the pin .
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Fri Nov 28, 2008 8:13 pm     Reply with quote

Quote:
Without the LED, the oscillation is from 0V to 5V. Why?
The pin output driver has some output impedance. Think of this as the internal resistance of a battery. When you draw a large current from the pin, some volts will be lost across the driver impedance. Without the LED, there is no current draw, therefore no voltage drop; you read 5 volts.
Quote:
I tried to decrease the output current (I use 10k) and that made the oscillation go from 0 to 5V. Why does this happen?
The voltage you measured must have been at the pin-resistor junction, and not at the resistor-LED junction. The pin will always show you close to 5 volts (as long as you don't overload it), while the voltage at the resistor-LED junction will be the forward drop of the LED.

Rohit
david90



Joined: 25 Feb 2006
Posts: 23

View user's profile Send private message

PostPosted: Fri Nov 28, 2008 9:52 pm     Reply with quote

Rohit de Sa wrote:
Quote:
Without the LED, the oscillation is from 0V to 5V. Why?
The pin output driver has some output impedance. Think of this as the internal resistance of a battery. When you draw a large current from the pin, some volts will be lost across the driver impedance. Without the LED, there is no current draw, therefore no voltage drop; you read 5 volts.
Quote:
I tried to decrease the output current (I use 10k) and that made the oscillation go from 0 to 5V. Why does this happen?
The voltage you measured must have been at the pin-resistor junction, and not at the resistor-LED junction. The pin will always show you close to 5 volts (as long as you don't overload it), while the voltage at the resistor-LED junction will be the forward drop of the LED.

Rohit


I don't think it is because of internal resistance. It has something to do with the statement` input_state().

If I get rid of this code

Code:
#INT_TIMER0
void timer0_test(){
if (input_state(PIN_C5))
{
   delay_us(500);
   output_low(PIN_C5);
}
else
{
   delay_us(500);
   output_high(PIN_C5);
}
}


and just put this in my main loop

Code:
   output_high(pin_C5);
         delay_ms(50);
         output_low(pin_C5);
         delay_ms(50);


C5 would oscillate from 0V to 5V just fine.
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Fri Nov 28, 2008 10:07 pm     Reply with quote

True, the reason why the output wasn't toggling initially was because of the faulty code. But even now, with
Code:
output_high(pin_C5);
         delay_ms(50);
         output_low(pin_C5);
         delay_ms(50);
you will see that the output is much lower than 5V with an LED attached. Without the LED the output will swing from 0 to 5v.

Rohit
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Nov 29, 2008 2:28 am     Reply with quote

input_state() in contrast to input() is not manipulating the TRIS register and thus should not have any influence on the output state. As previously discussed by Ttelmah and Rohit de Sa, the voltage drop due to a heavy load may be so high, that input_state() is reading a wrong level (said RMW problem). In this case, the output would stop blinking rather than showing an intermediate level.

There's apparently a misunderstanding of absolute maximum ratings. Keeping these limits can avoid damaging the chip, not guarantee normal operation:
Quote:
This a stress rating only and functional operation of the device at those or any other conditions above those indicated in the operation listings of this specification is not implied.


Normal operation of output ports is specified with maximum VOL of 0.6V at 8.5 mA output current. As a rough estimation, you can expect a linear, resistive behaviour below this corner. Somewhere above 8.5 mA, the output may show current limited (saturated) behaviour, thus it's not possible to extrapolate VOL above 8.5 mA.

When designing a circuit that operates above specified parameters, you should also consider possible exemplar and temperature dependant variations.
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