Blinking LED
In the previous section, we saw how to turn on a LED. In this tutorial we will learn few more terminologies and concepts in C which can make life easier. The first amongst them is : typedef. The syntax for typedef is:
typedef unsigned long u32;
Those from the C background should already recognize typedef. If not, typedef is a keyword in C which is used to assign an alternative name or a synonym to existing data type. In this example we have assigned "unsigned long" to "u32". Now we can easily write "u32" whenever we need "unsigned long". Note that this is not a new data type but just an alias for existing data type or a combination of existing data types.
void Delay (u32 count); //Function declaration or Function Prototype
To make a LED blink, we turn it on, wait (delay for a while) and then turn it off. This wait or delay can be achieved by calling a new function called Delay(). We know that functions in C are blocks of code with a specific name. They make programs easy to manage and read. All functions need to be declared before they can be used. This declaration includes number of arguments, type of arguments, and the return type. The above line just does that. It declares Delay() function before using it.
Now the functional part of Delay(). When this code is executed, it waits for some time and then the next line of code is executed. How? While loop in delay decrements 1 count at a time until it is 0, and then returns.
void Delay(u32 count) { while(count--); }
If we call Delay() function between turning on and turning off the LED.
PORTC = 0x00; // Set all Pins as Input Delay(500); // Call delay function PORTC = 0xff; // Set all Pins as Output Delay(500); // Call delay function
If we combine all these lines together, compile, and upload it into our microcontroller, we have a blinking LED. Yes we have achieved what we wanted to. You are free to download blinkled_1 program along with other supporting files.
C basics & Bitwise Operators
In the previous section we called a Delay() function to pause for a while and continue. Now we will see another way to accomplish the same result by turning ON and OFF individual bits. Also the LED was turned on and off by turning all pins in the port to either Output or Input. In this section we will see how to manipulate individual bits.
Writing a Delay() function is fine. But why recreate the wheel when there is already a function provided by avr-gcc for the same purpose which is <delay.h>, available in util directory (<install>\avr\include\util). This function can be used to make the program wait in milliseconds or even microseconds. Download blinkled_2 program which utilizes delay.h file.
The function prototype for using delay is:
void delay_us(unsigned int n) //For milliseconds void delay_ms(unsigned int n) //For microseconds
If you were to include this file, include the following line before your main().
#include <util/delay.h>
Once we have a delay, we need to try to make our program more robust and at the same time complicated. For this, we will understand another concept in C known as macros. C provides a feature where we can define a fragment of code with a unique name. Whenever this name is called in the program, it is replaced by the contents of the macro. This is a powerful feature which minimizes the length of code and also improves readability.
Examples of macros are:
#define LEDON PORTC &= ~(0x20) #define LEDOFF PORTC |= (0x20)
You are already aware of macros. But what are these weird characters: |=(0x20), &=~(0x20) and all that?
Love it or Hate it, they are the most confusing, yet powerful Bitwise operators. I suggest you to take a deep dive and understand this theory and not just a "touch & go" concept.
Tutorial index:
Do you have anything to say?
Visit the Forum to discuss, learn and share anything related to robotics and electronics !!