الجمعة، 10 يوليو 2015

Microcontroller Basics - How to Program an MCU for Turning ON an LED

Of course we are now ready to implement our first program inside the MCU, but before that it would be interesting to summarize quickly what we did in the course of our previous tutorials:


We procured the AVR Atmel microcontroller as per our required specification; here we have used the ATMega32 for the illustrations.

Next, we learned about microcontroller basics and the programmer unit which is responsible for transferring a program into the MCU chip.

Further on, we built the SP interface connector which is essential so that your computer could be linked with the microcontroller for the programming actions.

After this we confirmed whether the drivers were installed correctly in the computer for a 32-bit as well as a 64-but operating system.

Next, we installed the programming environment called Win AVR for facilitating easy writing ad transferring of the codes into the microcontroller, followed by the implementation of the avrdude for verifying the programmer with your PC and the microcontroller interconnected.



Finally in the previous chapter we finished building the LED/ resistor circuit and connected it with the relevant MCU outputs.

That’s a lot of work indeed; nevertheless it’s time to head right away into some real programming stuff!

To begin with we would want to divide the microcontroller into three categories; this would simplify our understanding a lot:

Control, Detection, and Communication

It would be interesting know that the above functions could be programmed in many different ways.

In our first program we would try to order the microcontroller to “control” an external parameter, yes you are right it would be the LED that we built recently.

To be precise, we’ll tell the MCU to switch ON the connected LED, yep I know this looks quite primitive, but the starting phase always needs to be easy.

Moving ahead with the present job, making the MCU control the LED is actually pretty simple:

For this we instruct pin#0 on PORT B to produce the required 5V for the LED.

Recall from the previous tutorial, we connected the anode of the LED to the above mentioned pin of the MCU.

There are two essential things required to be addressed to this pin of the MCU: 1) output and 2) 5 volts

We’ll learn a way through which we ca instruct the particular pin to become the output of the MCU.

Once it’s set to be the output of the chip, we may instruct it to be either “high” (5V) or “low” (0V) as desired for an application.

Since the any logic circuit such as a MCU the pins could be wither an output or an input and could be configured to produce either a logic high or logic low, the pins only need to be assigned either to be a logical high or a logical low, there aren’t any intermediate or undefined states other than these couple of states for microcontrollers or for any digital IC for that matter. Also the same applies for each and every pin of the MCU.

As for the input and output pin assignments, the inputs would be positioned to accept signals from external analogue stages, while the outputs would be responsible for interpreting these into the specified logical states, or a frequency.

Although the above assignments could be done in many different methods, we would be discussing one of them for the sake of simplicity. However it must be noted that although the one which would presented right now looks easy and interesting, it’s not so viable and not a recommended type for all MCU applications, for the same reason you would be introduced to more popular programming methods later in the course. These programs will allow only the desired pins to be assigned as per the specs without affecting the other adjoining which could be possibly already assigned to do some other functions.

However right now we won’t be bothering about the other pins so much and would use only the relevant pins of interest, avoiding complications to some extents.

For assigning a pin as an output we need to employ the Data Direction Register (DDR). If you are wondering what register here means, it’s simply a space in the MCU that enables the microcontroller to respond in some specified manner.

Using the DDR we can set the pin to either send a data that is like an “output”, or accept data that is in the form of an “input”.

However you may be confused regarding the word, what does this imply? A data adds a third dimension to the pins which may be assigned to be continuously at logic zero (0V) or logic high (5V), but what about the signals which could vary quickly such as a frequency of pulses. A frequency would be accompanied with high and low logics (5V and 0V) oscillating with some specified intervals or periods, thus it becomes time oriented and may be adjusted with respect to time, that’s why we identify as “data” meaning a parameter which indicates a function relative to another function (logic states and time).

One method of assigning pin0 as an output is by writing the following code:

DDRB = 0b00000001;

In the above program, DDRB signifies Data Direction Register for PORT B; 0b instructs the compiler regarding the following binary expression of a number; while the “1” at the end of the expression indicates the position of the pin0, that is it’s location in the form of the first pin of PORT B.

If you remember we learned that PORT B associates 8 pins with it (from 0 to pin7), and if you notice the above code also has 8 digits in it, meaning each digit signifies these 8 pins of PORT B.

Now the next procedure would be to assign 5V to this pin (pin0). Again the principle of operation is identical to DDR as above expressed through the following binary code:

PORTB = 0b00000001;

As can be seen, the only difference between the above code and the earlier one is that in this code we have made use of the PORT register. This register specifically handles the pin assignments of that particular port for which it’s been positioned inside te MCU. Thus it enables us to assign the real data logics (0 or 1) for those pinouts.

Now we may be interested to discuss some regarding the approximate details of our program. As we know all programs require a particular space to initiate the execution, this can be compared to a chef who knows all the ingredients regarding a particular recipe but is not instructed from where to begin.

The “main” function here is the location where each of the C/C++ programs initiates the execution. Therefore the main may be created as:


int main(void)
{
}

However to enable the program to interpret the DDR and PORT register details and their functioning inside the MCU chip, an additional statement needs to be included which may consist of all the data regarding the AVR MCU. Perhaps we would want to add this inclusion in all of our programs.

#include <avr/io.h>
int main(void)
{
}


As soon as the compilation initiates, the pre-processor section of the compiler focuses on the AVR directory to identify the “io.h” file. The extension “.h” here indicates it to be a header file, and that this code inside the file would be introduced at the start (head) of the source file that’s being created, hence the name “header”.

Here on we can introduce the DDR and PORT statements into our code, because the addition of the io.h header file would have directed the compiler regarding them.


#include <avr/io.h>

int main(void)

{

DDRB = 0b00000001; //Data Direction Register setting pin0 to output and the remaining pins as input

PORTB = 0b00000001; //Set pin0 to 5 volts

}

The above fixes the orientation of the pin0 as the output, having a magnitude of 5V. However there’s still one issue which isn’t determined for this pin, that is this pin is yet to be instructed to be switched ON indefinitely as long as the MCU is powered. This infinite feedback loop would ensure that this pin from the MCU does not switch OFF, rather continues with the 5V output indefinitely.

Although there are many different methods of applying a loop instruction for a pin, we would try employing the “while” loop here. As the name suggest, the “while” loop tells the microcontroller that “while” the power is available you need to stay activated with the assigned 5V for the assigned pinout.


#include <avr/io.h>

int main(void)

{

DDRB = 0b00000001; //Data Direction Register setting pin0 to output and the remaining pins as input

PORTB = 0b00000001; //Set pin0 to 5 volts

while(1)

{

//Code would be in here if it needed to execute over and over and over ... endlessly

}

}

You might want to note that, here we have used ‘1’ in the form of an argument for the “while” loop, since everything except ‘0’ could be considered a logical “true”.

That implies, the “while” loop consideration would never be responsible for anything except a logical “true”, which means that the particular pin would latch on with the specified state indefinitely.



The LED can be witnessed to be ON across the assigned pin permanently as long as the MCU received power across its Vdd and Vss.

That’s it, now we have the result that we desired to get and finally can see it happening after so much of hard work, but nevertheless to view the sweet result of our hard work is so satisfying. 

Within the next tutorials we’ll learn how to add a “time” dimension to the above LED, that is how to make it blink at certain specified rate.

Actually, in the above implementation, the LED is actually blinking but the loop rate is so quick that it’s almost like a permanent switch ON over the LED illumination.

We’ll see how this loop can be added with a delay as desired in order to make the LED blink at that delayed rate.

ليست هناك تعليقات:

إرسال تعليق