![]() |
Software for a robotWe shall discuss only C for microcontrollers. It is much like ordinary C with a few significant differences. We shall discuss three major points that you must know before writing any useful robot software:
Input and outputMost of us start learing C with a "hello world" program like this:
#include <stdio.h>
main() {
printf("Hello world!");
}
This prints "Hello world!" on the monitor. Now, this program is
surely not going to work in a microcontroller, simply because
there is no monitor with it. So it should not come as a great
surprise that C for microcontrollers does not
have printf or scanf (because there is
no keyboard). And so there is no stdio.h to include either!
Microcontrollers communicate with the external world via its
pins. Most microcontrollers have 4 ports (a port being a
collection of 8 pins). We shall illustrate the concept with
ATMEGA8515. The ports here are called PORTA, PORTB, PORTC,
PORTD. Each pin of each port can be used as input or output.
An example will clarify things. Here is a microcontroller version
of "hello world":
Explanation of the code:
1: This, as you can guess, is the analogue
of
2: (255)10 = (1111 1111)2 .Since all the bits are 1's, all the pins of PORT B will become output pins. 3: This is the line that actually produces the output. To understand the output write 29 in binary (with 8 bits): (29)10 = (00011101)2 .Thus here pins 0,2,3 and 4 will have 5V, while the other pins of PORT B will be at 0V. Checking this with a voltmeter (or by connecting LEDs) is an exciting project for newbies! 4: The program terminates here. But the pins will retain their final status until the microcontroller is powered off. So now we know the analogue ofprintf. The next
thing of interest is the analogue of scanf. Here is
a code snippet that reads a value from PORTC.
Explanation of the code: 1: Usual C declaration. 2: This is the data direction register for PORTC.
3: This lines reads the current status of the pins of
PORTC into the variable main function will not work. For this we need to
employ a trick that is very characteristic of microcontroller
software, but rarely (if ever) used in usual programming. We
discuss this next.
Infinite loopsConsider the following program.
#include <stdio.h>
main() {
while(1) {
printf("Hello!");
}
}
This program will flood your PC screen with "Hello!"'s. The only
way to stop it is by some drastic measure (like
control-alt-delete). This is an example of an infinite loop, a
thing that is definitely undesirable in usual programs. On the
other hand, infinite loops are essential to writing software for
microcontrollers. To see this consider the following program to
read some buttons connected to PORTC and accordingly lights some
LEDs connected to PORTB.
#include <avr/io.h>
main() {
DDRB = 255;
DDRC = 0;
PORTB = PINC;
}
Let's walk through this simple code. The first couple of lines
sets the communication direction for PORTB and PORTC. The thirdl
line reads PORTC and writes the value to PORTB. Well, that's
sounds like what we wanted to do, but it is done just once (within
a fraction of a millisecond since powering up the
microcontroller)! You'll get no time even to look at the
buttons, let alone push them! By the time your fingers reach the
buttons, the program has terminated and PORTB is frozen at its
last value until power down.
We need an infinite loop to keep the superfast microcontroller in
pase with its sluggish human user.
#include <avr/io.h>
main() {
DDRB = 255;
DDRC = 0;
while(1) {
PORTB = PINC;
}
}
All robot software must have such an infinite loop built into
it.
DelaysA microcontroller runs too fast compared to human reflex. We often need to slow the microcontroller down a bit to keep up with it. This is done by using delay loops, loops that do nothing, just kill time. Here is a typical delay loop:int i; for(i=0;i<1000;i++);Sometimes we need longer delays:
int i, j;
for(i=0;i<1000;i++) {
for(j=0;j<500;j++);
}
The following program shows a delay loop in action. There are
LEDs connected with all the pins of PORTB. Our aim is to use
these to make a count up timer.
#include <avr/io.h>
main() {
unsigned char count = 0;
int i;
DDRB = 255;
while(1) {
PORTB = count;
count++;
for(i=0;i<10000;i++);
}
}
|
| Prev | ![]() | Next |