• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Learning C

Status
Not open for further replies.

dr pepper

Well-Known Member
Most Helpful Member
I'm well used to pic micro, particularly the 16 series, all my code till now has been assembler.
C isnt totally new to me I did learn a little, I have adapted C to asm before.
However I think its time to learn C properly.
I use mplab 8.6 as my development environment, any suggestion on what compiler to use, I've heard of microchips xc8, hitec c, and proteus.
Also ordered a couple of embedded C books.
Once I get past getting a led to flash I think I'll be well on the way.
 

killivolt

Well-Known Member
I can't add anything; I'm just curious will you stay with the 16series or move to 18 or something else?

I'm also trying c; lucky you already have assembler. I'm straight out of the box with no knowledge of either.
 

DerStrom8

Super Moderator
Personally I use XC8 (I don't think Proteus is a compiler--it is a circuit simulator, afaik) and the 18F chips. My first micro was a PIC18F1330 and it was a great learning platform.

I definitely recommend you stick with MPLab 8. Stay away from X -- I've had nothing but trouble with it. It has its uses, but 8 is easier to use in my opinion.

The great thing about XC8 is that there is a lot of support out there, and documentation that will get you on your way. The most important thing you can ever do is read the datasheet for the micro, and the corresponding library files for XC8. They'll help you understand what instructions do what. Here's a simple LED flasher program to get you started:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 16000000
#endif
#pragma config WDTE=OFF, MCLRE=ON, CP=OFF, FOSC=INTOSC
void main(int argc, char** argv) {
  TRISA = 0b00000000;
  OSCCONbits.IRCF = 0b1111;
  while(1) {
    LATAbits.LATA0 = 1;
    LATAbits.LATA2 = 0;
    __delay_ms(100);
    LATAbits.LATA0 = 0;
    LATAbits.LATA1 = 1;
    __delay_ms(100);
    LATAbits.LATA1 = 0;
    LATAbits.LATA2 = 1;
    __delay_ms(100);
  }
}
Just note this code may have to be tweaked slightly depending on the actual micro you use and how you run it (crystal frequency, etc).

Starting with ASM is actually a great way to learn microcontrollers, if you ask me. It really helps you understand how they work on a hardware level. For the most part, it's all downhill from here!

Good luck!
Matt
 

Pommie

Well-Known Member
Most Helpful Member
The one bit of advice I give to anyone starting out learning C is to pay attention to indenting as this makes it very easy to see silly mistakes.

The other thing is curly braces. In all the tutorials I've seen they don't mention what they do. They group commands together as things like for and while loops only execute 1 command after them but if you group them in curly braces then they are classed as 1 command and all get executed.

C will let you type and run nonsense code. I.E.
Code:
    while(1)
        lata0=1;
        delay_ms(500);
        lata0=0;
        delay_ms(500);
This will compile and run. However, only the first two lines get executed due to the lack of curly braces. Putting a semicolon on the end of the while line will make only the while line run.

The correct code should be,
Code:
    while(1){
        lata0=1;
        delay_ms(500);
        lata0=0;
        delay_ms(500);
    }
There is a very good tutorial at http://www.tutorialspoint.com/cprogramming/index.htm that allows you to try out code on line.

Mike.
 

DerStrom8

Super Moderator
I second the statement about indentation. Too often I see incredibly sloppy code that's impossible to read simply because the writer couldn't be bothered to pay attention to indentations.

Anything between an opening curly brace and a closing curly brace should be indented once. You can nest these "blocks", just make sure you indent once per nested block. Therefore, code inside one block that's inside a second block should be intended twice.
 

dr pepper

Well-Known Member
Most Helpful Member
Nothing there that I dont understand, or seen before, except for the ifndef and pragma.

One of the things I;m going to find tricky is remembering the operators, I think I need to make up a little card with the everyday stuff on, I've seen these credit card sized.

A mate of mine is a system administrator and this language is his mainstay.

I havent used mplab x much, but whn I did it behaved strangly, I could run an in circuit debug sometimes, not others.
 

DerStrom8

Super Moderator
"ifndef" means "if not defined". It basically says that if you haven't previously defined the crystal frequency, then define it as 16MHz (Think I counted the zeros properly :p ).

"pragma" is a directive to the processor. It tells it how to behave. Therefore, "#pragma config" is a directive that tells the processor to set the following "fuses" (defined in the datasheet).

Code:
#pragma config WDTE=OFF, MCLRE=ON, CP=OFF, FOSC=INTOSC
does the following:

  • Disables the "Watchdog Timer" (WDTE stands for WatchDog Timer Enable). This timer restarts the chip if it hits an infinite loop. However, in many cases you want a micro to run continuously, so you want to disable this option
  • Enables the "Master Clear" (MCLRE stands for Master CLeaR Enable). When enabled, it allows you to reset the chip via a pushbutton or other external signal source.
  • Disables "Code Protection" (CP). Often when you write code for production, you'll want to protect the code to make sure it doesn't get changed. However, when programming as a hobby or for prototyping, you usually want to turn off the code protection.
  • Sets the "Oscillator Frequency" to use the internal oscillator (FOSC stands for Frequency of OSCillator). You could instead set it to use an external oscillator, like a crystal.
You'll want to read the datasheet and the XC8 documentation to ensure you're using the right fuses for your particular micro.
 
I second the statement about indentation. Too often I see incredibly sloppy code that's impossible to read simply because the writer couldn't be bothered to pay attention to indentations.

Anything between an opening curly brace and a closing curly brace should be indented once. You can nest these "blocks", just make sure you indent once per nested block. Therefore, code inside one block that's inside a second block should be intended twice.
Well said. I had to debug some code for a friend of mine the other day and could hardly understand what was going on due to a total lack of indentation :) Took me hours just to indent....
 

misterT

Well-Known Member
Most Helpful Member
About indentation and structure.. I use curly braces sometimes (often) to just structure my code.

Just an example.. the code itself is nonsense.
C:
void main(void)
{
    int foo;
    int table[16];

    initialize_uart(B38400);

    /* Initialize IO */
    {
        PORTD = 0x00;
        PORTE = 0xFF;
    }

    /* Initialize table */
    {
        int number;

        number = 3; /* Initialize variables just before you use them */
        for(int i=0; i<16; i++)
        {
            table[i] = number;
            number = number*number;
        }
    }

    while(1)
    {
        /* */
    }
}
Opening curly brazes allows you to define variables that are only available (scope) within those curly brazes.. this allows better optimization for the compiler. And it is easy to break that piece of code to its own function, if needed.

You can see from all the posts so far that C is about structure and readability. That is the motivation for moving from asm to C. Compilers today are good, so focus on writing well structured code.. the kind of code that documents itself. Code lasagne, not spaghetti. But, in embedded code, it is ok to break "good practice" -rules when necessary.
 
Last edited:
  • Like
Reactions: 3v0

misterT

Well-Known Member
Most Helpful Member
... will you stay with the 16series or move to 18 or something else?
What does this mean? Should I move from cocaine to heroine? I do not understand the significance.. do you have to replace your complete toolset if you move from 16 series to 18 series?
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Don't know why I missed this thread.. As far as C compilers go you have several options

XC8 from microchip ( this was Hi-tech, microchip bought it from them )
MikroC from MikroElectronica..
SDCC from the sourceforge code depository
CCS from CCS inc
SourceBoost from sourceboost technologies

Most of these have a lite version apart from SDCC which is completely free.

I have tried all of them I have ended up with XC8 for the small micro's and MikroC for the pic32's
To learn C you would be better off with XC8 for the same reason I used in the tutorials... It seems to be the closest to ANSI C and expects you to learn more about the low level manipulation... SDCC is the same, but you need to be more experienced as its a bit hard going..

MikroC is the easiest as it does everything for you....
Sourceboost is the cheapest..

But as XC8 has tons of people ( and those migrated from hi-tech ) on this forum it has the greatest support..
If you go through the tutorials in my signature ( As I'm sure you have ), the code doesn't even need modifying as it works with XC8 straight off the bat!!
 
Last edited:

misterT

Well-Known Member
Most Helpful Member
I think it is more about the Integrated Development Environment (IDE) than the compiler. Then again.. in many cases compiler and IDE are closely related. Good documentation is important. You need to know your compiler etc.
Just try out the options. You need to see some s**t to know what is good..
 
Last edited:

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
I think it is more about the Integrated Development Environment (IDE) than the compiler. Then again.. in many cases compiler and IDE are closely related. Good documentation is important. You need to know your compiler etc.
Just try out the options. You need to see some s**t to know what is good..
True... Most documentation seems to be written for the "tefal" heads..... but all the information is normally there.
XC8 has great documentation... within the "docs" folder they produce the "chip info" files.. This is excellent for newbies as it contains vital stuff to each processor...

I believe that XC8 also has "Linear" memory control so data structures are easier to deal with...
 

killivolt

Well-Known Member
.....................................................................What does this mean? Should I move from cocaine to heroine? I do not understand the significance.. do you have to replace your complete toolset if you move from 16 series to 18 series?
Finally the cats out of the bag; embedding code is addicting. I should have listened to my parents. :rolleyes:
 
  • Like
Reactions: 3v0

Mosaic

Well-Known Member
This is useful to me as my experience is abt the same as the OP's.
I did recently acquire MikroC 8 & 16bit/dsp compilers along with prototyping boards.
XC8/16 seemed a bit costly compared to the MikroC hardware & s'ware bundles.
I don't like the idea of non optimized code with deliberate 'nop' and 'do nothing' loops forcing a performance hit in the free Xc8/16.
 

dr pepper

Well-Known Member
Most Helpful Member
Thanks.
I'm well on the way, a lot of this is covering old ground.
A book I have goes on about ccs, however I'd allready decided to use xc8.
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Thanks.
I'm well on the way, a lot of this is covering old ground.
A book I have goes on about ccs, however I'd allready decided to use xc8.
Not a great deal of difference between them... Only thing to watch is the way each compiler defines identifiers..

But as you have access to the .h files, all the stuff you need is in there.... The one thing I like about XC8 is that all the bits are defined..

PORTAbit.RA0... can just be written RA0.. Same with status bits like the serial port or the CCP module

while(!TXSTAbits.TRMT); can just be
while(TRMT);
 

3v0

Coop Build Coordinator
Forum Supporter
While I am not telling anyone what to do or what is right: I like the placement of the { in the example misterT has posted. One ends up getting a few less 'code' lines on a page but with modern monitors that is not the concern it used to be. The ability to see a missing curly brace is a very good thing.

Others will disagree and it is their right to do so. But I suggest people start out this way at least until they come up to speed.

About indentation and structure.. I use curly braces sometimes (often) to just structure my code.

Just an example.. the code itself is nonsense.
C:
void main(void)
{
    int foo;
    int table[16];

    initialize_uart(B38400);

    /* Initialize IO */
    {
        PORTD = 0x00;
        PORTE = 0xFF;
    }

    /* Initialize table */
    {
        int number;

        number = 3; /* Initialize variables just before you use them */
        for(int i=0; i<16; i++)
        {
            table[i] = number;
            number = number*number;
        }
    }

    while(1)
    {
        /* */
    }
}
 

dr pepper

Well-Known Member
Most Helpful Member
Note heeded.
I have met a similar messup in assembler by forgetting to type return, the effect no doubt will be very similar.
Putting {}'s on their own line also will improve using a text search, in fact if the tab is set to 10 then then the block no. is just the editor column number/10.
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top