CSE466 Lab 2: “Interrupts”

advertisement
CSE466 Lab 2: “Interrupts”
Objectives
The goal of this lab is to introduce various features and modules of the ATmega16 while
introducing how to program the microcontroller using C. In this lab you will learn the
following:




how to operate an oscilloscope;
how to program a timer interrupt;
how to debounce a button in software;
how to use the A/D converter and its interrupt features.
This lab assignment has 3 required sections and 1 optional section that can be completed
for extra credit. Some of the sections have multiple graded parts so make sure to save
ALL the graded parts so they can be turned-in and/or shown to the TAs for grading. The
deliverables section below outlines exactly what will be graded.
Section A: Introduction & Tutorial
1. Setup the C programming environment
2. Complete the Oscilloscope tutorial
3. Add additional hardware to your breadboard
Section B: Timers
1. Reimplement your “One Minute Counter” from Lab 1 in C (instead of assembler)
and compare the code sizes.
2. Reimplement the counter (again) but use a timer interrupt to control counting rate
instead of a delay loop. In addition, the counter should also be able to start, stop,
and change direction based on the two added buttons. (GRADED DEMO)
Section C: Analog to Digital Converter
1. Read the analog value coming from the potentiometer or photoresistor and output
the most significant 8-bits in hexadecimal notation to the two 7-segment LED
displays. Use a button to toggle between displaying ADC values from the
potentiometer and the photoresistor. (GRADED DEMO)
2. Use the potentiometer to create an adjustable light sensor that turns on an LED
when the light level drops below the value of the potentiometer. (GRADED
DEMO)
Section D: Create a light meter (EXTRA CREDIT)
See Extra Credit Page
Suggested Reading / Helpful Hints

The following sections of the ATmega16 datasheet might be helpful for this lab
o Interrupts
o 8-bit Timer2
o Analog to Digital Converter

Here is a reference on bypassing, a technique to reduce noise in your circuit:
http://www.seattlerobotics.org/encoder/jun97/basics.html.

Even though the ATMega16 is an 8-bit processor, an int is 16 bits.

Debouncing a button is essentially an averaging or smoothing of the input value.
This is often referred to as low-pass filtering because only the long-term
variations (at low frequency) are used (passed) and rapid changes (at high
frequency) are discarded. A good way to do this in software is to sample a button
several times and take the average or mode (the most common value across all the
samples – this is like voting for Boolean values).
Resources
Lab 2 Schematic
Brief introduction to AVR Programming
avr-gcc manual
Application notes section for the AVR 8-bit RISC family
Suggested Steps
Section A: Introduction & Tutorial
1. The recommended program for development for this class is Programmers’
Notepad. We have provided a sample project that will copy a constant from
program memory and displays it on PORTB. When the sample program is
uploaded to your breadboard an “8” should appear on the 7-segment display
attached to PORTB. If you would like more information on the makefile,
programmers notepad, and winAVR please refer to install_config_WinAVR.pdf .
To make Programmers’ Notepad easy to use for 466 the lab staff has added 3
useful commands to the tools menu:



“Tools -> Make All” – build all the possible output files for the project
“Tools -> Make Clean” – delete all output files from the project
“Tools -> Program” – launch MegaLoad
2. Go through the entire Oscilloscope Tutorial (consult the Oscilloscope Manual as
needed)
3. Add two buttons (pins 18 and 19), a potentiometer (pin 40), a LED (pin 21), a
wire to Vcc (pin 32), a photoresistor (pin 39) and bypass capacitors to complete
the circuit shown in the schematic on your breadboard. Again, before powering
your circuit back up, you should confirm that you don't have any shorts between
Vcc and ground with the multimeter.
Question 1: What is the appropriate range of values for the two button pullup resistors? (Refer to datasheet)
Question 2: What is the purpose of the bypass capacitors? Why might they
be useful for this lab?
Section B: Timer
PART 1:
1. Rewrite the last lab in C. Try to mimic the original behavior as much as possible
since the idea is to compare the code size of your hand-generated assembly to the
code size of what the compiled code generated by the C compiler. Use the
oscilloscope to confirm that your board is counting at or very close to 1Hz.
Question 3: Record the code size of the two hex files (assembly and C). Both
of these numbers will show up in the compiler output. For the assembler, it is
listed as "Code" in the program memory usage. It is listed as ".text" in the
gcc output. Which one is larger?
PART 2:
1. Reimplement the 1Hz counter by eliminating the delay loop and replacing it with
code that uses the output compare interrupt from timer2 to do the timing.
Documentation for the avr-gcc compiler is available at
http://www.nongnu.org/avr-libc/user-manual/index.html From that link, go to
the modules section and then the Interrupts and Signals entry. Remember, when
writing the interrupt handler routine, you'll want to minimize the amount of code
in it. Interrupt handlers are meant to be very fast, and do only the work that is
critical to do right at that instant. There is no way that anyone will be able to
notice if your LEDs update even a few milliseconds late, so the LED update code
should not be in the handler. Documentation on timer2 including all the related
registers is available in the datasheet in the course pak.
2. Implement the stop-start button so that pressing the button will cause the counter
to toggle between counting or halting. The left (tens digit) decimal point should
indicate whether the counter is running by being on when the counter is running
and off when the counter is stopped. It would probably be a good first step to get
the switch debounced (see the hint on debouncing). You can either use timer0 for
debouncing or figure out a way to use timer2 for both the counting and
debouncing. Remember that if you push the button and hold it for a long time, it
should still only register as a single push.
3. Implement the up-down button so pressing the button will change the direction of
counting. The decimal point on the right (ones digit) should be on when counting
up and be off when counting down. Note that even when the counter is stopped,
the system should still process an up-down button press by immediately updating
the direction and decimal point state.
Question 4: Why debounce a button?
Section C: ADC Suggested Steps
PART 1:
1. Create a hexadecimal display that can properly output an 8-bit value on the two 7segment LED displays that combine to make the 8-bit value (one 7-segment LED
will represent the high 4-bit nibble and other will represent the low 4-bit nibble).
You should implement a lookup table in program memory to convert a 4-bit
nibble (in binary) to a hexadecimal number. The hexadecimal letters should all be
uppercase except for the letters ‘b’ and ‘d’ which should be lowercase to avoid
repeated symbols. The easiest way to ensure that you can properly output all of
the 8-bit values properly in hex is to create a simple hexadecimal counter that
counts from 00 to FF. (NOTE: Displaying an 8-bit value will be useful this
quarter as a debugging mechanism so the code will most likely be reused.)
2. Implement a program that continually displays the analog value of the
potentiometer on the two 7-segment LED displays. You should read the section in
the datasheet on the Analog to Digital Converter to find out how to obtain the
analog value. You'll want to use the interrupts to tell you when the conversion is
complete. Also note that the ADC has 10-bit resolution but only 8-bits are needed
for the display, so you can throw away the 2 least significant bits. Note that the
datasheet describes a nice way to get the 8 most significant bits.
3. Use a button to toggle between the system displaying 8-bit analog values from the
potentiometer or the photoresistor. The two 7-segment displays should either
show the 8-bit value of the potentiometer (decimal points off) or photoresistor
(decimal points on).
Question 5: Does brighter light or dimmer light give you a higher analog
value? What is happening to the resistance?
PART 2:
1. Use the potentiometer and photoresistor to create an adjustable light sensor that
will turn lights on when it becomes dark. The photoresistor will be used to
monitor the current light level of the surrounding environment. The potentiometer
will be used to adjust the level at which the sensor will trigger the lights to come
on. This will allow the user to customize their home so the lights turn on and off
at the desired darkness. Once the photoresistor reports that the level of darkness
specified by the potentiometer has been reached, the ATmega16 should turn on
the lights. (In this case the light is an LED attached to pin 21.) Once it becomes
light enough the ATmega16 should turn off the LED.
2. To determine the voltage difference between the potentiometer and photoresistor
you should use an ADC differential channel. The potentiometer should be the
positive differential input and the photoresistor should be the negative differential
input. The ADC will return a signed number (in two’s complement) that
represents the voltage difference between the two differential input channels. The
two 7-segment displays should display this signed 8-bit value by using the tens
digit decimal point to represent the negative sign.
NOTE: You might want to average some of the ADC values to prevent the light
from flickering on and off. A weighted moving average might be a good idea for
smoothing. Below is an example formula for a weighted moving average where a
larger value for x will cause “new value” to have a smaller affect on the average.
average = ((previous average * (x -1)) + new value) / x
3. We may want to set a slower sample rate if we want the part to be low-power. We
can use the timer to wake-up the processor and trigger a sampling. You can safely
assume that updating the light state (on or off) can take place a second after the
ambient light level has changed. This means that you should design your system
to sample at a reasonable rate so that it could be put into low power.(NOTE: You
are NOT required to put it into a low power mode). If you sample approximately
every 100-500 ms (depending on the amount of smoothing) your system should
still be very sensitive to changing light levels. For this lab you need to sample the
ADC on the order of milliseconds.
Deliverables
For all files turned in, the comments at the top of the file should contain:


Both partners' full name, login and student number.
The lab number and the part of the lab (e.g. “Lab 2, Section B, Part 1” for the
counter that is a rewrite of your assembly counter).
Answers to the Five Lab Questions.
Section B, Part 1:
1. Turn in a hard copy of your code
o It should count upwards from 0 to 59 and start over at 0 after it reaches 59.
o
The tens digit of the current count value should be displayed on the left 7segment display, and the ones digit should be displayed on the right 7segment display.
o
The count rate should be 1 Hz.
Section B, Part 2:
1. Demonstrate your counter to a TA. You can either do this during this lab, or
during the first 1/2 hour of the next lab.
o It should have a reasonable user-interface. (i.e. make sure buttons are
responsive but not overly sensitive).
o
Changing counting direction should work properly and the decimal points
should represent the current state of the counter. The low decimal point
should be lit when counting upwards, and off when counting downwards.
The high decimal point should be lit when the counter is running and off
when the counter is stopped. The low decimal point should still change
state even when counting is stopped but the up-down button is pressed.
o
Counting should happen at 1 Hz.
2. Turn in hardcopy of your commented C code.
o Make sure that your interrupt handler is as minimal as possible. Points will
be docked for updating the displays inside of the interrupt handler.
Part C, Part 1:
1. Demonstrate your light/potentiometer reader to a TA. You can either do this
during this lab, or during the first 1/2 hour of the next lab.
o The display should be able to range from very close to 0 when the pot is
turned all the way one way to very close to 0xff when the pot is turned the
other way.
o
The decimal point should show whether the values being displayed are
from the potentiometer or the photoresistor.
o
It should be reasonably responsive to changes of the potentiometer or in
the level of light.
2. Turn in hardcopy of your commented C code.
Part C, Part 2:
1. Demonstrate your light sensor to a TA. You can either do this during this
lab, or during the first 1/2 hour of the next lab.
o
The decimal point should show whether the value being displayed is
positive or negative.
o
The LED should not flicker excessively and the readings should be
somewhat stable when the surrounding light is staying constant.
2. Turn in hardcopy of your commented C code.
o
Should sample the ADC on the order of milliseconds
Download