DC Motor Control Tutorial
The goal of this tutorial is to show you how your board can be used to drive a DC motor. The resulting program will enable the motors and turn on and off motor 1 about every 2 seconds. The PRG is setup to change the direction of the motor when toggled.
1) Get started by opening AVR studio and select "new project". In the "Project type" box choose "AVR GCC" and then give the project a meaningful name. I find it helpful to have it create a folder for the project. Make sure that "Create initial file" is selected and set the path for where the project should be stored.
2) A good habit to get into is to add a comment at the start of the program describing what it does:
// This is a simple program that enables motor 1 // and switches its direction about every 2 secondsThe "//" tells the compiler to ignore everything to the right of this when compiling the code. This is call a "comment" and I would encourage you to add them generously throughout your code to remind you or inform others of what the heck is going on.
3) Next we'll tell the compiler what other files to look at when generating the program:
#include <avr/io.h> #include <stdlib.h> #include <avr/delay.h>You will most likely always start by including these files when making a new project.
- The first, "io.h", contains a list of functions and definitions that provide abstract access to the input and output capabilities of the uController.
- "stdlib.h" provides access to the "standard library" in C code where many common functions can be found.
- "delay.h" has a handy set of functions for generating precise delays in your code.
4) "#define"s often follow the "#include"s and are generally used to tell the compiler how to configure pieces of your code. For this program we only need one:
// F_CPU defines the speed of the microcontroller to the _delay functions. #define F_CPU 1000000ULThe above #define lets the compiler set up the delay functions in delay.h with the expected clock speed of the uController (in this case it's 1 MHz). Note that if you set this wrong then the delay functions will not behave as expected (e.g. delay for too long or short). A later example program will explain #define in greater detail.
5) Now we'll create the main function that will contain the commands we want the uController to execute as it runs.
int main(void) { }Everything from here on out will be placed inside the main function (between the curly braces).
6) Next lets set up the uController ports to behave the way we need them too. By default, all io pins are set to inputs upon reset. To change the direction of a pin we set the corresponding bit in the DDRx variable. For this uController, a 0 sets it to an input, and 1 for output. The following code sets the 4th pin on port B to be an output as well as a few pins on port C:
DDRB |= 1<<PIN4; // set PB4 to output DDRC |= 0b00001111; // set PC0,1,2,3 to outputsLook at the schematic for the Tekpet board to understand why these pins are being used.
7) Now it nice to set the pins you care about to a known state so we'll set the pins we care about (0 and 1) to 0:
PORTC &= 0b11111100; // set PC0,1 to low
7) Finally we enable one of the motors and set the mode pins to 1 (check the datasheet for the motor driver to see what the mode pins do) :
PORTC |= 0b00001100; // set PC2,3 to high (the "mode" pins) PORTB |= 0b00010000; // set PB4 to high (enable motor 1)
8) Because the main function is only called once and we want our program to never stop, we need to add an infinite loop:
while(1) { }While-loops are a basic loop that will continue to execute the code contained inside their curly braces as long as the condition inside the parentheses is met. In this case 1 is always 1 so the loop never ends.
9) Here is the final piece to the program that resides in the while loop. This is what actually makes the motor turn on and off every two seconds:
PORTB ^= (1<<PIN4); _delay_ms(1000); _delay_ms(1000);The first line sets pin 0 on port C to the opposite of its last value (i.e. toggles it). As you may guess, the last two lines delay the program by 1000ms each.
10) Finally, we add the code that checks the state of the switch and changes the motor direction:
if (PINE & (1<<PIN2) == 0) { // if pin 2 on port E is 0.... PORTC &= ~(1<<PIN0); // set pin 0 on port C to 0 } else { PORTC |= (1<<PIN0); // set pin 0 on port C to 1 }
11) Now that the code is complete, we need to compile it. Click on Build->Build in the menus of AVR studio (or press F7 like a pro) and cross your fingers. If a problem is reported, the attempt to decipher the error and compare your code to what has been presented in this guide.
12) The compiled code is contained in a file named after your project with a .hex extension added. By default, it is placed in a folder called... default located in the project directory. Open up FLIP and go to File->Load Hex File and load up the hex file for your project. Click on the icon the resembles a microchip (far left) and choose "AT90USB646" from the menu and hit OK. Now click on the icon that appears to be a USB cable and choose USB. Flip the switch on the uController to "program" and press the reset button. Give it a second and then select "open" in the USB port dialog box. If all is well then make sure Erase, Program and Verify are checked and click on Run.
After the bars go away, select the "Start application" button to see if things work! Be sure to set the switch back off of programing mode so that your program will start when power is cycled or the system reset. You will also need to attach the 9v battery to power the motors (USB only can power the uController and servos).

