CSEP567 Lab 3: “Counting in C”
Objectives
The goal of this lab is to introduce 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;
Reading / Helpful Hints
-
The following sections of the ATmega16 datasheet might be helpful for this lab
-
Interrupts
-
8-bit Timer0
-
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
Suggested Steps
Section A: Introduction & Tutorial
-
The supported 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 in this class 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
-
Go through the entire Oscilloscope Tutorial
(consult the Oscilloscope Manual
as needed)
-
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.
Section
B: One Minute Timer
-
Implement a counter in C that counts at 1Hz from '00' to '59'
using Timer 1's output compare interrupt for 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.
-
Implement the stop-start button (pin 18) 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. We have provided
some sample code in the prelab for debouncing a button. You should setup the
timer to sample the button at 5ms intervals. Remember that if you push the
button and hold it for a long time it should only register as a single push.
-
Implement the up-down button (pin 19) 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. We have provided some
sample code in the prelab for debouncing a button. 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.
Demonstrate
your One Minute Timer to a TA. Make sure you have debounced both buttons and
implemented the specification listed in Section B.
Question
1: Why debounce a button?
Section
C: Hex Counter
-
Create
a hexadecimal display that can properly output an 8-bit value on the two
7-segment 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.)
-
Implement
a counter in C that counts at 1Hz from '00' to 'FF' using Timer
1's output compare interrupt for timing.
Demonstrate
your Hex Counter to a TA.
Delieverables
Turn
in a copy of your commented C code from Part B and your answer to the question.