Electronics > Beginners

Microcontroller programming tutorial

(1/3) > >>

Rdx:
Being a mechanical engineer with electronics as a hobby I mainly got into it by Dave's EEVBlog Fundamental Fridays or general other explanations of his.
I mean Dave just can show stuff in exactly that way to entertain, but also transmitting the required info in a way that makes a lot of sense to me.

Just recently I got more into microcontroller programming as well, and I have some experience with Arduinos (and compatibles).
For diving deeper into C or C++ programming on a micro I am lacking some knowledge and experience though. Especially when looking into using serial communication or for example, but also more C-related stuff like pointers.

Is there any useful resource of tutorials that not only teach you the C related stuff, but also the hardware close stuff like buffers in serial comm, etc?
Some I saw were really very focused on C itself (on a PC), but those just dont really cover a lot of relevant stuff when it comes to micros.

Maybe Dave/David could post a series on programming micros, as I think it would really help to see some practical programming and best practices.

Lookin forward for any input in this regard

rstofer:
You have two distinct issues:  C programming and low level programming.  They are separable...

There must be thousands of tutorial on the C language on the Internet.  If nothing else, maybe one of the courses at Udemy.  Get a copy of "The C Programming Language" ANSI Edition (you should also have the classic edition at some point).  Pointers are both the worst and the most powerful concept in C.

Want to learn C programming?  Start writing C code.  Write lots of C code.  Thousands and thousands of lines of C code.  Then you will know C programming.  The path isn't short.

Then there is the matter of low level programming.  Jumping past the Arduino library stuff and heading toward bare metal.  The other day I was looking at this Instructable and while the result is not especially interesting, to me, what is presented seemed to be an excellent tutorial.  At least it shows what is involved:

https://www.instructables.com/id/Girino-Fast-Arduino-Oscilloscope/

One of the things you should see at first glance is the reliance on the datasheet.  Users of Arduino libraries are shielded from the necessity to actually read and understand a datasheet.  No longer!  Look at all the bit-twiddling in the registers.  You get this information from the datasheet.  Exercise:  Match up the code and comments to the related section in the datasheet until you actually understand what is happening and why.

Buffers, in this case circular queues, are covered in EVERY book on data structures and keeping the pointers straight is critical.  There MUST be examples of receive data queues on the Internet.  They all work the same.  There is a HEAD pointer, a TAIL pointer and an array that is conceptually wrapped into a circle.

A character comes in, the UART generates an interrupt, the interrupt code fetches the character and stuffs it into the queue and maybe sets a flag or count variable.  The mainline code eventually wants to process the character so it extracts it from the queue, updates the tail pointer and the count (if any).  The counter idea is in addition to what is usually taught - it is simply a way to find out if there are chars in the queue without have to do arithmetic on the pointers.

https://www.studytonight.com/data-structures/circular-queue

Here's a free HINT:  Disable interrupts in the mainline code before trying to extract a char.  You don't want the head pointer changing in the middle of the extraction.

Here's another free HINT:  Make the queue length a power of 2.  2, 4, ..., 64, 128 and like that up to whatever size you want.  It makes doing the wrap-around arithmetic on the pointers as easy as an AND operation to kill the overflow when the pointer runs off the end.

Good luck!

There are better forums here at EEVblog for programming related issues.

rstofer:
You have two distinct issues:  C programming and low level programming.  They are separable...

There must be thousands of tutorial on the C language on the Internet.  If nothing else, maybe one of the courses at Udemy.  Get a copy of "The C Programming Language" ANSI Edition (you should also have the classic edition at some point).  Pointers are both the worst and the most powerful concept in C.

Want to learn C programming?  Start writing C code.  Write lots of C code.  Thousands and thousands of lines of C code.  Then you will know C programming.  The path isn't short.

Then there is the matter of low level programming.  Jumping past the Arduino library stuff and heading toward bare metal.  The other day I was looking at this Instructable and while the result is not especially interesting, to me, what is presented seemed to be an excellent tutorial.  At least it shows what is involved:

https://www.instructables.com/id/Girino-Fast-Arduino-Oscilloscope/

One of the things you should see at first glance is the reliance on the datasheet.  Users of Arduino libraries are shielded from the necessity to actually read and understand a datasheet.  No longer!  Look at all the bit-twiddling in the registers.  You get this information from the datasheet.  Exercise:  Match up the code and comments to the related section in the datasheet until you actually understand what is happening and why.

Buffers, in this case circular queues, are covered in EVERY book on data structures and keeping the pointers straight is critical.  There MUST be examples of receive data queues on the Internet.  They all work the same.  There is a HEAD pointer, a TAIL pointer and an array that is conceptually wrapped into a circle.

A character comes in, the UART generates an interrupt, the interrupt code fetches the character and stuffs it into the queue and maybe sets a flag or count variable.  The mainline code eventually wants to process the character so it extracts it from the queue, updates the tail pointer and the count (if any).  The counter idea is in addition to what is usually taught - it is simply a way to find out if there are chars in the queue without havimg to do arithmetic on the pointers.

https://www.studytonight.com/data-structures/circular-queue

Here's a free HINT:  Disable interrupts in the mainline code before trying to extract a char.  You don't want the head pointer changing in the middle of the extraction.

Here's another free HINT:  Make the queue length a power of 2.  2, 4, ..., 64, 128 and like that up to whatever size you want.  It makes doing the wrap-around arithmetic on the pointers as easy as an AND operation to kill the overflow when the pointer runs off the end.

The head and tail pointers are actually indices into an array, not usually actual address pointers.  Suppose your queue had 16 entries (0..15).  Then when you wanted to update an index, say tail, the math looks like

tail = (tail + 1) & 0x0f;

Notice how, if tail was already 15 (0x0f) when it is incremented to 0x10, it is out of range but that's ok because the AND operation throws out the high bit and the result is 0x00 and that's exactly what we want.

If your queue had 256 entries the math would be

tail = (tail + 1) & 0xff;

As soon as the value increments to 0x100, it is brought back into range.

https://www.programiz.com/c-programming/c-operators

Good luck!

There are better forums here at EEVblog for programming related issues.

rstofer:
First exercise:  Write the 'enqueue' and 'dequeue' for a queue of size 16.  Detect when it is full and when it is empty.  Keep a running count of chars in the queue.

Test it by trying to insert as many chars as it is supposed to hold.  Then see if it pops an error when you try to add another.  Note that, conceptually, this would be inside an interrupt handler, how do you proposed to deal with the error?  Ignoring it might be acceptable because the queue should have never overflowed.  Something else is wrong in the program.  Set a permanent "oops" flag and call it a day.

Try to remove as many chars as it is supposed to hold - they should be there, you just filled the queue.  Then try to remove one more.  You should see that the 'count' is zero and return something (0xff?) that indicates the queue is empty.

You can write these functions and play with them inside the loop() function of a standard Arduino sketch.

You might start with this:
https://electrofriends.com/source-codes/software-programs/c/data-structures-c/c-program-to-implement-circular-queue-operations/

admiralk:
As rstofer said, C/C++ is C/C++, it really is not any different whether it is for an MCU or PC. At a low level, which Arduino hides from you, you are mostly just flipping or reading bits. The datasheet is your best friend, but @~ 300 pages it is hard to figure out where to look.

I like this playlist for reference.

Unless you are using the same MCU, the registers will likely be different, but he points you to right place to look instead of just saying do it this way.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod