Anda di halaman 1dari 10

egr345 lab guide - 3.

3.0.1 Lab 1 - Programming the Atmel Atmega32 Thumb Board

3.0.1.1 - Purpose

To use the Atmel Mega32 microcontroller boards to input and output digital, ana-
log, serial, and wireless data.

3.0.1.2 - Background/Theory

A method for generating variable analog outputs, called Pulse Width Modulation
(PWM), is shown in Figure 3.1. If the output is on all the time, the effective output voltage
is the maximum voltage of the output. If the output is only on half the time, the effective
output voltage is only half. By varying the ratio of on-time to off-time, the effective volt-
age is varied. The percentage of time that the signal is on is called the duty cycle. So, if the
voltage is only on half the time, the effective voltage is half the maximum voltage, and the
duty cycle is 50%. This method is popular because it can produce a variable effective volt-
age efficiently. (Aside: The frequency of these waves is normally above 20KHz, above the
range of human hearing.)

50% duty cycle


V max
50
V eff = --------- V max
0 100
t
20% duty cycle
V max
20
V eff = --------- V max
0 100
t
100% duty cycle
V max
100
V eff = --------- V max
0 100
t
0% duty cycle
V max
0
V eff = --------- V max
0 100
t

Figure 3.1 Pulse Width Modulation (PWM)


egr345 lab guide - 3.2

An analog to digital (A/D or ADC) converter converts an analog input voltage to a


digital value. A successive approximation A/D converter is shown in Figure 3.2. This
device is like the one in the AtMega. The main operation concept is based on the succes-
sive approximation logic. Once the reset is toggled the converter will start by setting the
most significant bit of the 8 bit number. This will be converted to a voltage Ve that is a
function of the +/-Vref values. The value of Ve is compared to Vin and a simple logic
check determines which is larger. If the value of Ve is larger the bit is turned off. The logic
then repeats similar steps from the most to least significant bits. Once the last bit has been
set on/off and checked the conversion will be complete, and a done bit can be set to indi-
cate a valid conversion value.

Vin above (+ve) or below (-ve) Ve

Vin
+
-
+Vref

successive 8
approximation D to A
clock converter
logic Ve

reset done

-Vref 8
data out

Figure 3.2 Analog to digital converter

In the ATMega 32, the A/D converter is 10 bit, and there are up to eight 0-5V
inputs available on port A. To operate the A/D converter the following steps must be used.
Once the analog input value has been read it can be converted back into a voltage using
equation (2).
egr345 lab guide - 3.3

R = 2
N (1)

VI
V C = ⎛ ------------⎞ ( V max – V min ) + V min (2)
⎝ R – 1⎠

where,
N = number of bits
R = resolution of A/D converter
V I = the integer value from the A/D conveter
V C = the voltage calculated from the integer value

Microcontrollers are often used in real-time applications. Real-time systems must


respond to events with time constraints. In other words they must always respond to inputs
and cannot ’go to sleep’ as normal desktop computers do. To achieve this responsiveness
interrupts are used. An interrupt can be generated by an external event, such as input
change, or by an internal timer. When an interrupt occurs the computer will stop whatever
it is doing and store its current state. It then runs a designated interrupt subroutine. The
interrupt subroutine should run briefly and then allow the computer to restore its previous
state and return to normal operations. In a realtime controller the interrupt routine typi-
cally runs 100 to 1000 times per second to check motor positions and update outputs to
control the motors.

Serial communication typically involves sending bytes between devices. These


bytes are often ASCII encoded characters. Multiple bytes make up a string. For our pur-
poses we will use serial communication to send commands to the microcontrollers, and to
get responses (including data) back. Serial communications can be done multiple ways.
The simplest method will be over the USB port, using a virtual serial port under windows.
We may then use a program such as Hyperterminal to interact with the microcontroller.

Communications may also occur without wires. Many wireless communication


standards are already in use, however the boards we are using include hardware for a new
wireless networking method called Zigbee. This is meant for consumer products with low
power consumption and slower data rates. One interesting difference between simple
communication and networking is that there may be multiple clients able to talk at one
time. And, each client on the network will have a unique identifier, known as a network
address. For Zigbee this will be a value between 0 and 255.

3.0.1.3 - Prelab
egr345 lab guide - 3.4

1. Review C programming using previous course materials.


2. Review the EGR 226 course materials from EGR 261 and 226..
3. Review the analog I/O chapter in the textbook.
4. Skim the Atmel Mega32 manual (www.atmel.com) to become familiar with the
processor.
5. Review the fundamentals of ASCII strings, including end-of-line and carriage-
return characters.
6. Investigate Zigbee networks on the internet.

3.0.1.4 - Equipment

Computer with an Internet connection


Assembled controller thumb board
10K potentiometer
Multimeter
Oscilloscope

3.0.1.5 - Experimental Procedure

1. Boot your PC and login to the network. (Note: don’t forget to use a browser first
to login to the campus network first.) Plug the board into a USB port. At this
point windows (XP) should recognize that new hardware has been inserted and
look for a driver. If not already installed you will need to do the following --> A
message "Welcome to the Found New Hardware Wizard" should appear. For
the prompt "Can Windows Connect to Windows Update to search for soft-
ware?" use "Yes". Select "Install the Software Automatically". You should see
something that says "USB->Serial". This process will be repeated for "USB
Serial Port". An LED should flash indicating that the board has power.

2. Open "Start/Control Panel" then "System/Hardware/Device Manager". Open the


"ports" item and find the com port number.

3. Install the following software packages in the order shown. These packages are
available on the course home page (http://claymore.engineer.gvsu.edu/~jackh/
eod/egr345.html), or on the C2D2 web page. Note: Be careful to install the
packages in the order shown below.
WinAVR 3.5 or newer - a basic set of tools and the C compiler.
Megaload 5.0 or newer - a tool for downloading programs.
Gvim 6.1 - (on C2D2) an editor for modifying programs.
AVR C Compiler Update - (on C2D2) to provide a shell for compiling
GVim Editor Update Installation - (on C2D2) adds some shortcuts
test.hex - a test program for the thumb board

4. Run megaload and select the com port found in step 2. In Megaload set the "File
egr345 lab guide - 3.5

to be program in the flash" to be "test.hex", and set the baud rate to 38,400. You
should then be able to push the reset button on the board and load the program.
If all was successful you will see a few lines of text in the "messages" window
and the last line will be "Flash Prog Done!".

6a. (Using Gvim) Open the AVR folder on the desktop, and double click on the
’Gcc AVR DOS Prompt’. Start Gvim with ’gvim simple.c’ and enter the pro-
gram in Figure 3.3. When done press the function key <F9> to compile the pro-
gram. If the compilation is successful there should be a new file called
simple.hex in the same directory. If there are no significant errors or warnings
then proceed to the next step. (Please note that this uses the C:\temp directory
by default. When done all programs should be copied to your removable
media.)

6b. (Using Notepad) Start Notepad and input the ’simple.c’ program in Figure 3.3.
Open the AVR folder on the desktop, and double click on the ’Gcc AVR DOS
Prompt’. Compile the program in the DOS window using .....
/* A Simple Test Program */

#include <avr/io.h>

void delay(void)
{
volatile int i,j;

for (j=0; j < 10; j++)


for (i=0; i < 0xFFFF; i++) ;
}

int main(void)
{
unsigned char i = 0;
DDRB = (unsigned char)255; // set port B to outputs

while (1) {
delay(); // wait for about 1 second
PORTB = i++; // keep changing values
}

return 0;
}

Figure 3.3 Test program (simple.c)


egr345 lab guide - 3.6

Note: This program is complex and you will have to debug it. There are some basic rules
that will shorten the debugging process.
1. Don’t debug by making changes and seeing if they work. DEBUGGING BY TRIAL
AND ERROR DOESN’T WORK.
2. If your program doesn’t work, and the problem is not obvious - review the program
and make sure you understand how it works. Then, determine where the program is
not doing what you expect - print statements help here. Determine why the program
is not doing what you expect and then change the program to make it work.
3. Use a multimeter to check outputs to see if they are actually set.

7. Start the Megaload program and make sure that the ’File to be programmed in
the flash’ is pointing to the ’C:\temp\simple.hex’ file. Press the reset button on
the board to download the program. A message will appear if the download was
completed successfully. The program will now be running.

8. The program will count in a binary sequence and output the values on port B.
Port B outputs from 0 to 4 are located beside the ’PB’ symbol. Connect the pos-
itive side of a multimeter to one of the outputs. Connect the negative side of the
multimeter to one of the grounded terminals. For lower order bits the multime-
ter should switch values about once per second, higher order bits will switch
more slowly. Note: You may also connect LEDs in series with 220 ohm resis-
tors for the outputs for a visual output - the LEDs are direction sensitive and if
connected in reverse will not light.

9. Enter, compile, and download the program in Figure 3.4. Test it by changing
inputs on port A and verifying that the same output changes on port B. Note: if
egr345 lab guide - 3.7

an input is not connected, it will tend to assume a random value.

#include <avr/io.h> // define ports such as DDRB

void delay(void)
{
volatile int i,j;

for (j=0; j < 10; j++)


for (i=0; i < 0xFFFF; i++) ;
}

int main(void)
{
DDRB = (unsigned char)255; // set port B to outputs
DDRA = (unsigned char)0; // set port A to inputs

while (1) {
PORTB = PINA; // keep changing values
}

return 0;
}

Figure 3.4 Digital inputs

10. Enter, compile, and download the program in Figure 3.5. Test the program by
setting an analog input with a variable power supply connected to PA0. The 5
most significant bits of the outputs will be on port B. Set the input voltage to
different voltages and measure the digital outputs. Convert the binary values to
a decimal value and plot the results.

#include <avr/io.h>

void AD_setup(){
ADMUX = 0xC0; // set the input to channel 0
ADCSRA = 0xE0;// turn on ADC and set to free running
}

int AD_read (){


return ADCW;
}

int main(void)
{
AD_setup(); // enable the AD inputs
DDRA = (unsigned char)0; // set port A to inputs
DDRB = (unsigned char)255; // set port A to outputs

while (1) {
PORTB = (AD_read() >> 5) & 0x1F; // output the value to port A
}

return 0;
}
egr345 lab guide - 3.8

Figure 3.5 Analog inputs

11. Enter, compile, and download the program in Figure 3.6. The program will
accept the input voltage on PA0 and output a corresponding voltage on PD7.
Use a DMM to verify that the input and output voltages match. Use an oscillo-
scope to verify that the output wave is PWM and trace a few examples at differ-
ent duty cycles.

#include <avr/io.h>

void PWM_setup(){
//using OCR2
DDRD = 0xFF; //set as output
TCCR2 = _BV(WGM21)|_BV(WGM20)|_BV(COM21)|_BV(CS20); //fast PWM
OCR2 = 0xFF; //100% duty cycle
}

void PWM_write(int val){


OCR2 = val; // duty cycle
}

void AD_setup(){
ADMUX = 0xC0; // set the input to channel 0
ADCSRA = 0xE0;// turn on ADC and set to free running
}

int AD_read (){


return ADCW;
}

int main(void)
{
AD_setup(); // enable the AD inputs
PWM_setup(); // setup the PWM outputs
DDRA = (unsigned char)0; // set port A to outputs

while (1) {
PWM_write(AD_read() >> 2); // output the value to the PWM
output
}

return 0;
}

Figure 3.6 Analog Outputs with Pulse Width Modulation (PWM)

12. Enter, compile and download the program in Figure 3.7. The outputs on port B
will change in a binary pattern.
egr345 lab guide - 3.9

#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>

#define CLK_ms 10// set the updates for every 10ms


unsigned int CNT_timer1; // the delay time
volatile unsigned int CLK_ticks = 0; // the current number of ms
volatile unsigned int CLK_seconds = 0; // the current number of seconds

SIGNAL(SIG_OVERFLOW1){
CLK_ticks += CLK_ms;
if(CLK_ticks >= 1000){ // Number of interrupts between output changes
CLK_ticks = CLK_ticks - 1000;
CLK_seconds++;
}
TCNT1 = CNT_timer1;
}

void CLK_setup(){
TCCR1A = (0<<COM1A1) | (0<<COM1A0)| (0<<COM1B1) | (0<<COM1B0)
| (0<<WGM11) | (0<<WGM10) | (0<<FOC1A) | (0<<FOC1B);
// disable PWM and Compare Output Modes
TCCR1B = (0<<WGM12) | (0<<WGM13)
| (0<<ICNC1) | (0<<ICES1)
| (1<<CS12) | (0<<CS11) | (1<<CS10); // set to clk/1024
CNT_timer1 = 0xFFFF - CLK_ms * 16; // 16 = 1ms, 160 = 10ms
TCNT1 = CNT_timer1; // start at the right point
//SFIOR &= PSR10; // reset the scaling bit
// use CLK/1024 prescale value
TIFR1&=~(1<<TOV1); // set to use overflow interrupts
TIMSK1 = (1<< TOIE1 );// enable TCNT1 overflow
sei(); // enable interrupts flag
}

int main(void){
int seconds = 0;

DDRC = 0x40; // PortC bit 6 is output


CLK_setup();

for (;;) {
if(seconds < CLK_seconds){
PORTC = (PORTC & 0xBF) | ~(PORTC & _BV(6));
seconds = CLK_seconds;
}
}
return 0;
}

Figure 3.7 A system clock using interrupts

13. Download the files sio.c and sio.h to your working directory. Enter, compile
egr345 lab guide - 3.10

and download the program in Figure 3.8. You will then need to close ’mega-
load’ and start hyperterm. Choose ’com1’ with 9600baud, 8 data, 1 stop, no par-
ity and Xon/Xoff handshaking. You should see text messages on the screen.

#include <avr/io.h>
#include <avr/signal.h>
#include "sio.c"

void delay(int ticks){


volatile inti, j;
for(i = 0; i < ticks; i++){
for(j = 0; j < 1000; j++){
}
}
}

int main(){
volatile int i = 0;
int c;
DDRB = 0xFF;
sio_init();
delay(1000);
for(;;){
for(i = 0; i < 10; i++){
outln("a little test");
delay(1000);
}
for(i = 0; i < 10; i++){
outstr("a little test = ");
output('a' + i);
EMIT_CR();
delay(1000);
}
for(i = 0; i < 10; i++){
outln("press a key (q to quit)");
while((c = input()) == -1){}
if( c == 'q') break;
outstr("---> you pressed ");
output(c);
EMIT_CR();
}
}
sio_cleanup();

return 1;
}

Figure 3.8 ASCII Communications

14. Put a Zigbee program to exchange bytes ---------------------------

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx

Anda mungkin juga menyukai