Writing to an LED in embedded C

Started by tuurbo46 December 4, 2004

Hi

Im quite a newbie to embedded C and im in a bit of a muddle. I
currently have a tri-led connected to 2 pins(RC4 and RC5) on portc of
a 16C773 pic chip(at this point we wont worry about the model of the
chip).
I have portc bits(RC4 and RC5) set to output mode and therefore
portc is set up to light led. If RC4 is sent high by the port the led
will light green, and if both RC4 and RC5 are sent high, the led will
light red.
Ok my problem is i dont know how to access these 2 ports
independently and together. I have included my code below: I
understand there is no timer, but will this code light the led?

void red_led(void)
{
char x = 0x01;
char y = 0x01;
RC4 = x;
RC5 = y;
}

void green_led(void)
{
char x = 0x01;
RC4 = x;
}





The manner in which you identify ports and bits is highly compiler
dependent. Which version of C are you using?

I would probably try a byte wide output:

void green_led(void) {
PORTC = 0x10;
}

void red_led(void) {
PORTC = 0x30;
}

The problem with this code is that it also clears the other bits.

Maybe your compiler accepts:

void green_led(void) {
PORTC |= 0x10;
}

void red_led(void) {
PORTC |= 0x30;
}

If you can actually address the bits as indicated in your post:

void green_led(void) {
RC4 = 0x01;
}

void red_led(void) {
RC4 = 0x01;
RC5 = 0x01:
}

Read the manual - it will give better information.

--- In , "tuurb46" <tuurbo46@y...> wrote:
>
> Hi
>
> Im quite a newbie to embedded C and im in a bit of a muddle. I
> currently have a tri-led connected to 2 pins(RC4 and RC5) on portc
of
> a 16C773 pic chip(at this point we wont worry about the model of
the
> chip).
> I have portc bits(RC4 and RC5) set to output mode and
therefore
> portc is set up to light led. If RC4 is sent high by the port the
led
> will light green, and if both RC4 and RC5 are sent high, the led
will
> light red.
> Ok my problem is i dont know how to access these 2 ports
> independently and together. I have included my code below: I
> understand there is no timer, but will this code light the led?
>
> void red_led(void)
> {
> char x = 0x01;
> char y = 0x01;
> RC4 = x;
> RC5 = y;
> }
>
> void green_led(void)
> {
> char x = 0x01;
> RC4 = x;
> }





Thanks for your reply. Im currently using the Hi-Tech 7.85
enviroment intergraded into mplab v5.
I dont want to clear all the bits, but i do require access to
those 2 port bits. How are these 2 bits accessed on there own?
--- In , "rtstofer" <rstofer@p...> wrote:
>
>
> The manner in which you identify ports and bits is highly compiler
> dependent. Which version of C are you using?
>
> I would probably try a byte wide output:
>
> void green_led(void) {
> PORTC = 0x10;
> }
>
> void red_led(void) {
> PORTC = 0x30;
> }
>
> The problem with this code is that it also clears the other bits.
>
> Maybe your compiler accepts:
>
> void green_led(void) {
> PORTC |= 0x10;
> }
>
> void red_led(void) {
> PORTC |= 0x30;
> }
>
> If you can actually address the bits as indicated in your post:
>
> void green_led(void) {
> RC4 = 0x01;
> }
>
> void red_led(void) {
> RC4 = 0x01;
> RC5 = 0x01:
> }
>
> Read the manual - it will give better information.
>
> --- In , "tuurb46" <tuurbo46@y...> wrote:
> >
> > Hi
> >
> > Im quite a newbie to embedded C and im in a bit of a muddle. I
> > currently have a tri-led connected to 2 pins(RC4 and RC5) on
portc
> of
> > a 16C773 pic chip(at this point we wont worry about the model of
> the
> > chip).
> > I have portc bits(RC4 and RC5) set to output mode and
> therefore
> > portc is set up to light led. If RC4 is sent high by the port the
> led
> > will light green, and if both RC4 and RC5 are sent high, the led
> will
> > light red.
> > Ok my problem is i dont know how to access these 2 ports
> > independently and together. I have included my code below: I
> > understand there is no timer, but will this code light the led?
> >
> > void red_led(void)
> > {
> > char x = 0x01;
> > char y = 0x01;
> > RC4 = x;
> > RC5 = y;
> > }
> >
> > void green_led(void)
> > {
> > char x = 0x01;
> > RC4 = x;
> > }






Using PIC C Lite (a derivative) the form PORTA |= 0x30 will work and
PORTA &= ~0x30 will probably turn them off.

Again, check the manual for your particular version. My manual for
PIC C Lite doesn't even touch on the matter. --- In , "tuurbo46" <tuurbo46@y...> wrote:
>
> Thanks for your reply. Im currently using the Hi-Tech 7.85
> enviroment intergraded into mplab v5.
> I dont want to clear all the bits, but i do require access to
> those 2 port bits. How are these 2 bits accessed on there own?





At 08:31 AM 5/12/04, rtstofer wrote:
>Using PIC C Lite (a derivative) the form PORTA |= 0x30 will work and
>PORTA &= ~0x30 will probably turn them off.
>Again, check the manual for your particular version. My manual for
>PIC C Lite doesn't even touch on the matter.

1st, if you use an OR to turn bits on then you should AND with the
complement to turn them off. Ie., |= 0x30 will turn on bits 4 and 5. &=
0xCF will reset bits 4 and 5.

2nd. You should assign a byte variable to hold the current port state. All
operations should be performed on this byte. After it is adjusted the byte
is then copied to the port.

ie;

BYTE x;
x = 0x00; // initialise
PORTA = x;
.... other processing
x |= 0x30; // switch on both LEDS
PORTA = x;
.... other processing
x &= 0xEF; // turn off LED 1
// (actually, you'd be better off using x &= ~0x10;
PORTA = x;
.... other processing
x &= 0xDF; // turn off LED 2
x |= 0x10; // turn on LED 1
PORTA = x; // assign new state
.... other processing

Having said all that it's better to assign the mask patterns to named
constants or create macros to make the code easier to read and
modify. Ie., here is a portion of some code I worked on a while ago; (B1
and B2 were defined elsewhere)

#define setLED PORTAmap |= B1; PORTA = PORTAmap;
#define rstLED PORTAmap &= ~B1; PORTA = PORTAmap;
#define setRLY PORTAmap |= B2; PORTA = PORTAmap;
#define rstRLY PORTAmap &= ~B2; PORTA = PORTAmap;


I would have thought that all embedded 'C' compilers would allow the
type of code below. As this would be a coding standard.

Addressing single bits though would be compiler specific. :: PORTA |= 0x30 will work and
::
:: PORTA &= ~0x30 will probably turn them off.

Colin --
cdb, on Sunday,5 December,2004

Web presence: www.btech-online.co.uk

Hosted by: www.1and1.co.uk/?k_idy88359

Light travels faster than sound. That's why some people appear bright
until they speak!





This is another case where you may also want to study the ASM output
of the compiler. The PIC C Lite documentation talks about
optimizing:

PORTA |= 0x10;

to:

bsf PORTA,4

That doesn't say anything about how the compiler might optimize:

PORTA |= 0x30;

Using an in-RAM mirror of the port contents and operating on that
copy is always a good idea. See section 9.10.1 of the Mid Range MPU
document for a very interesting discussion of the problems with BSF,
BCF and XORWF when used on ports.

Until recently I hadn't quite grasped the significance of using
these instructions. If I expected:

BCF PORTB,7
BCF PORTB,6

to result in PORTB containing 00xxxxxx when the external pin was
pulled high by a resistor or the internal weak pullup I would be
mistaken.

So, a word of caution: know what your compiler emits and what it
really means. The "optimization" above can cause weeks of debugging
when the hardware fails to function. --- In , cdb <cdb@b...> wrote:
> I would have thought that all embedded 'C' compilers would allow
the
> type of code below. As this would be a coding standard.
>
> Addressing single bits though would be compiler specific. > :: PORTA |= 0x30 will work and
> ::
> :: PORTA &= ~0x30 will probably turn them off.
>
> Colin > --
> cdb, cdb@b... on Sunday,5 December,2004
>
> Web presence: www.btech-online.co.uk
>
> Hosted by: www.1and1.co.uk/?k_idy88359
>
> Light travels faster than sound. That's why some people appear
bright
> until they speak!



> :: PORTA |= 0x30 will work and
> :: PORTA &= ~0x30 will probably turn them off.

If this gives unwanted side effects on the other pins of the same port
google for the read-modify-write problem. Better: use a shadow register.

Wouter van Ooijen

-- -------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu





--- In , "Wouter van Ooijen" <wouter@v...>
wrote:
> > :: PORTA |= 0x30 will work and
> > :: PORTA &= ~0x30 will probably turn them off.
>
> If this gives unwanted side effects on the other pins of the same
port
> google for the read-modify-write problem. Better: use a shadow
register.
>
> Wouter van Ooijen
>
> -- -------
> Van Ooijen Technische Informatica: www.voti.nl
> consultancy, development, PICmicro products
> docent Hogeschool van Utrecht: www.voti.nl/hvu

Hi

Thanks for your input, i have now solved the problem.

Thanks again.

Tuurbo46




Hi

Thanks for your input, i have now solved the problem.

Thanks again.

Tuurbo46 --- In , "Wouter van Ooijen" <wouter@v...>
wrote:
> > :: PORTA |= 0x30 will work and
> > :: PORTA &= ~0x30 will probably turn them off.
>
> If this gives unwanted side effects on the other pins of the same
port
> google for the read-modify-write problem. Better: use a shadow
register.
>
> Wouter van Ooijen
>
> -- -------
> Van Ooijen Technische Informatica: www.voti.nl
> consultancy, development, PICmicro products
> docent Hogeschool van Utrecht: www.voti.nl/hvu