MPLAB C30

PIC24 Flashing LED

Microchips C compiler for PIC24 and dsPIC.

PIC24 Flashing LED

Postby Graham Mitchell » Sat Oct 16, 2010 3:47 am

I've been toying around with C on and off for some time (thanks to Hop) - though I'd like to press on with the language and better still, newer PICs such as the PIC24/dsPIC. I've also got a project to work torward - 64 bit Floating Point Coprocessor

My first program - flashing a LED. I've used a PIC24FJ64GA002 as its the latest model available in Proteus ISIS that's also a DIP package (for bread-boarding).

I'm making use of the internal 8Mhz oscillator, which will ensure the PIC operates at 4MIPS (PIC24 run a OSC/2, compared to PIC18 that are OSC/4). Here's the code:

Code: Select all
/*

Project Notes

Name: Flashing LED
Note: An introductory program that flashes an LED once every second

Author: Graham Mitchell http://digital-diy.com
Created: 16 Oct 2010

Version History
---------------
1.0 (16 Oct 2010)
- Initial release

1.1 (17 Oct 2010)
- Changed too "#include <p24fxxxx.h>" to accomodate any PIC24F selection
- Added project notes

1.2 (18 Oct 2010)
- Now using internal oscillator with PLL enabled (32Mhz, 16MIPS)
- Made a correction to FCY define (added LL to define 64-bit long, replacing UL)

*/

#include <p24fxxxx.h>               // PIC24 specific defines
#define FCY 16000000LL              // Define clock speed (16MIPS, LL = 64 bit long)
#include <libpic30.h>               // Used for __delay_ms

#define LED LATBbits.LATB6          // Alias LED for LATB0.6
#define LEDtris TRISBbits.TRISB6    // Alias LED for TRISB.6

_CONFIG2(FNOSC_FRCPLL)              // Config set for: Fast RC oscillator w/ divide and PLL

void initialise() {                 // Configures the PIC
    OSCCONbits.NOSC = 0b111;        // Fast RC Oscillator with Postscaler and PLL module
    CLKDIVbits.RCDIV = 0b000;       // Set clock div 1:1
    LEDtris = 0;                    // Make LED an output
    LED = 0;                        // Set LED low
}

void main() {                       // Main program loop
    initialise();                   // Intialise PIC
    while (1==1){                   // Infinite loop
    LED = 1;                        // Set LED high
    __delay_ms(500);                // Delay 500mS
    LED = 0;                        // Set LED low
    __delay_ms(500);                // Delay 500mS
    }
}

And a simulation of the project:

PIC24 Flashing LED.gif
PIC24 Flashing LED.gif (10.95 KiB) Viewed 2398 times

A simple program, though there were ~20 learning curves to pump that out. I'll post my progress (if any heh).
- the admin guy

Follow Digital DIY via Facebook | Twitter | Newsletter | RSS Articles | RSS Forum

For site related queries/issues, please contact me via (if you're logged in, PM is fine)
User avatar
Graham Mitchell
Site Admin
Site Admin
 
Posts: 1471
Joined: April 2009
Has thanked: 214 times
Have thanks: 78 times

Re: PIC24 Flashing LED

Postby be80be » Sun Oct 17, 2010 8:50 pm

If you don't have this you'll want it http://chungyan5.no-ip.org/open_data/el ... 51456c.pdf

Here a sample using portb as counter
Code: Select all
int counter; // for TRISB and PORTB declarations
int main (void)
{
counter = 1;
TRISB = 0; // configure PORTB for output
while(1) // do forever
{
PORTB = counter; // send value of ‘counter’ out PORTB
counter++;
}
return 0;
}
be80be
“No beard, no belly, no guru…”
User avatar
be80be
Valued Member
Valued Member
 
Posts: 1696
Joined: February 2009
Has thanked: 58 times
Have thanks: 71 times

Re: PIC24 Flashing LED

Postby be80be » Sun Oct 17, 2010 9:36 pm

Here maybe kick start the math

<FLOAT.H> FLOATING-POINT CHARACTERISTICS
The header file float.h consists of macros that specify various properties of floating-
point types. These properties include number of significant figures, size limits, and
what rounding mode is used.
DBL_DIG
Description: Number of decimal digits of precision in a double precision floating-
point value
Include: <float.h>
Value: 6 by default, 15 if the switch -fno-short-double is used
Remarks: By default, a double type is the same size as a float type (32-bit representation).
The -fno-short-double switch allows the IEEE 64-bit
representation to be used for a double precision floating-point value.
DBL_EPSILON
Description: The difference between 1.0 and the next larger representable double
precision floating-point value
Include: <float.h>
Value: 1.192093e-07 by default, 2.220446e-16 if the switch
-fno-short-double is used
Remarks: By default, a double type is the same size as a float type (32-bit representation).
The -fno-short-double switch allows the IEEE 64-bit
representation to be used for a double precision floating-point value.
DBL_MANT_DIG
Description: Number of base-FLT_RADIX digits in a double precision floating-point
significand
Include: <float.h>
Value: 24 by default, 53 if the switch -fno-short-double is used
Remarks: By default, a double type is the same size as a float type (32-bit representation).
The -fno-short-double switch allows the IEEE 64-bit
representation to be used for a double precision floating-point value.
DBL_MAX
Description: Maximum finite double precision floating-point value
Include: <float.h>
Value: 3.402823e+38 by default, 1.797693e+308 if the switch
-fno-short-double is used
Remarks: By default, a double type is the same size as a float type (32-bit representation).
The -fno-short-double switch allows the IEEE 64-bit
representation to be used for a double precision floating-point value.
be80be
“No beard, no belly, no guru…”
User avatar
be80be
Valued Member
Valued Member
 
Posts: 1696
Joined: February 2009
Has thanked: 58 times
Have thanks: 71 times

Re: PIC24 Flashing LED

Postby be80be » Sun Oct 17, 2010 10:09 pm

FNOSC_FRCPLL Fast RC oscillator w/ divide and PLL
be80be
“No beard, no belly, no guru…”
User avatar
be80be
Valued Member
Valued Member
 
Posts: 1696
Joined: February 2009
Has thanked: 58 times
Have thanks: 71 times

Re: PIC24 Flashing LED

Postby Graham Mitchell » Mon Oct 18, 2010 3:25 am

Cheers Burt for spotting the issue with the config file - as it turns out I was not operating the device with PLL enabled.

The code has been updated to allow the device to operate at 16MIPS with the internal OCS.
- the admin guy

Follow Digital DIY via Facebook | Twitter | Newsletter | RSS Articles | RSS Forum

For site related queries/issues, please contact me via (if you're logged in, PM is fine)
User avatar
Graham Mitchell
Site Admin
Site Admin
 
Posts: 1471
Joined: April 2009
Has thanked: 214 times
Have thanks: 78 times

Re: PIC24 Flashing LED

Postby jmessina » Mon Oct 18, 2010 4:50 am

C30's floating point representation is VERY non-standard (or at least atypical) ...

C30 also supports these Float types:
float: 32 bit
double: 32 bit***
long double: 64 bit

***To get true doubles one must specify the "-fno-short-double" compiler option.


In most implementations on 16 and 32-bit machines, the default is for 'double' to be 64-bit. A 'long double' is usually the same size as a 'double' (64-bit) since 128-bit would be pretty outrageous on a smaller cpu like this, and very few people need more than the ~15 digits you get with a 64-bit 'double'. Having a 'double' be the same size as a 'float' by default is dumb. Definitely something to watch out for.

http://www.microchip.com/forums/tm.aspx?m=217124
Random avatar
jmessina
VIP
VIP
 
Posts: 877
Joined: June 2010
Has thanked: 7 times
Have thanks: 174 times

Re: PIC24 Flashing LED

Postby be80be » Mon Oct 18, 2010 6:20 am

Why are you doing this in main
Code: Select all
 initialise(); // Initializes PIC

Initialization should be before main

you can save a lot of code toggling like this
Code: Select all
 
led =~led;
__delay_ms(500);
be80be
“No beard, no belly, no guru…”
User avatar
be80be
Valued Member
Valued Member
 
Posts: 1696
Joined: February 2009
Has thanked: 58 times
Have thanks: 71 times

Re: PIC24 Flashing LED

Postby Graham Mitchell » Mon Oct 18, 2010 7:03 am

That had me scratching my head for a while Jerry.. I'm not sure how to toggle switches in code, though I discovered the option in the Project>Build Options>Project>C30 Tab like so:

64 bit double.png
64 bit double.png (37.74 KiB) Viewed 2351 times

For other switches not listed above - how can you set them in code? Or are they done via the text box shown above?

be80be wrote:Initialization should be before main

I found that C works a bit different to SF (of course), for example: the following won't compile:
Code: Select all
#include <p24fxxxx.h>               // PIC24 specific defines
#define FCY 16000000LL              // Define clock speed (16MIPS, LL = 64 bit long)
#include <libpic30.h>               // Used for __delay_ms

_CONFIG2(FNOSC_FRCPLL)              // Config set for: Fast RC oscillator w/ divide and PLL

void initialise() {                 // Configures the PIC
}

initialise();                       // Initialise PIC

void main() {                       // Main program loop
}

.. and its the same with "initialise();" after main. This compiles fine however:
Code: Select all
#include <p24fxxxx.h>               // PIC24 specific defines
#define FCY 16000000LL              // Define clock speed (16MIPS, LL = 64 bit long)
#include <libpic30.h>               // Used for __delay_ms

_CONFIG2(FNOSC_FRCPLL)              // Config set for: Fast RC oscillator w/ divide and PLL

void initialise() {                 // Configures the PIC
}

void main() {                       // Main program loop
    initialise();                   // Initialise PIC
}

I like to have direct visibility of the PIC configuration - though I guess it *could* be included as a .c file. The initialisation is only called once anyhow - the while(1==1) loop is the main program loop.

While we're on the topic of 'main' - does anyone know how to suppress the error "warning: return type of 'main' is not 'int'"? Even with "void main(void)" C30 makes the warning...

be80be wrote:you can save a lot of code toggling like this

I was wondering about the toggle/not symbol (! in SF) - cheers Burt
- the admin guy

Follow Digital DIY via Facebook | Twitter | Newsletter | RSS Articles | RSS Forum

For site related queries/issues, please contact me via (if you're logged in, PM is fine)
User avatar
Graham Mitchell
Site Admin
Site Admin
 
Posts: 1471
Joined: April 2009
Has thanked: 214 times
Have thanks: 78 times

Re: PIC24 Flashing LED

Postby jmessina » Mon Oct 18, 2010 8:17 am

For other switches not listed above - how can you set them in code? Or are they done via the text box shown above?

Yeh, add the settings to the text box just like you would if you were using the command-line. They'll be passed to the compiler when it runs.

While we're on the topic of 'main' - does anyone know how to suppress the error "warning: return type of 'main' is not 'int'"? Even with "void main(void)" C30 makes the warning...

Normally, 'main' is declared with a return type like "int main(void)". In the embedded world, you normally never return from 'main', but this is done so that if you were running under an OS, you could return a success/error code to the operating system. To get rid of the warning, either change the declaration for 'main', or there's probably a tab somewhere that lets you turn off this warning.

Initialization should be before main

Burt's partially correct here, but unless there's some real reason to, I wouldn't bother at this point.

C works a bit different than SF (but not entirely so, in some respects). In C, there's a chunk of code that runs before control is transferred to 'main'. It's called the C run-time startup module. You don't normally see it, but it's there. This code does things like setup the heap, call any initializers required by the run-time package like stdio, and initializes all of the static data areas. It's almost always written in assembly, and I wouldn't recommend touching it. If you want to add code to run before 'main' executes, you can setup a function using the 'user_init' attribute like this

Code: Select all
   void __attribute__((user_init)) initialize_me(void) {
      // perform initalization sequence alpha alpha beta
   }

and it will automatically be called for you. For more details, check out chapter 4 "Run TIme Environment" in the C30 User's Guide. For info on "user_init", you may have to look in the C30 Compiler Help file.

SF does something similar to this when you have a statement in a Module that's outside any sub or function. It executes these before the statements in the main Program file, letting you set things up that may need to be done first.
Random avatar
jmessina
VIP
VIP
 
Posts: 877
Joined: June 2010
Has thanked: 7 times
Have thanks: 174 times

Re: PIC24 Flashing LED

Postby jmessina » Mon Oct 18, 2010 8:27 am

I was wondering about the toggle/not symbol (! in SF)


Keep in mind, in C there's the logical NOT operator '!', and the bitwise NOT operator '~'. They do two very different things.

You can also toggle something by 'exclusive-or'ing it with 1 like

Code: Select all
x ^= 1
Random avatar
jmessina
VIP
VIP
 
Posts: 877
Joined: June 2010
Has thanked: 7 times
Have thanks: 174 times

Next

  • Similar topics
    Replies
    Views
    Author

Return to MPLAB C30

cron