Before we wrote any assembly code for our digital thermometer, we first aimed to describe
our device in a behavioral sense by writing pseudocode. This forced us to understand the
order and timing of various events that we wanted to occur. To accomplish this task, we
decided that the cleanest way to execute events was to have a main program loop which
scheduled a sequence of tasks every 50ms. The tasks to be executed would come in the following
order (in pseudocode):
-check if 50 ms reached....
// execute this code every 50 ms
-get the state of the push buttons (i.e. pushed, held, released...)
-reload 50 ms timer
-sample the current temperature
-update the extreme temperatures (max/min) if necessary...
-clear LCD (get ready to display)
-update various settings (as received by the push buttons)
-toggle between temperature scales (if called for)
-inc/dec max/min alarm temperatures (if called for)
-display the recorded max/min temperature (if called for)
-convert temperature value to appropriate scale
-display the temperature
-display °[F, C, K, or R]
-check to see if alarm temperature reached
From this behavioral model, we then began writing the assembly code, using the pseudocode as
a skeleton. We encapsulated each of the different tasks as a separate function to increase
the modularity of our program and to make the main loop clean and easy to follow.
To avoid possible register conflicts (or a lack of registers in general), we chose to
locally define the registers we needed within a given subroutine. Moreover,
we stored most of the variables that we use in our program in SRAM. String constants are stored
in FLASH. To make the program easier to read (and thus be modified later on) we chose to give
many memory locations the same name as the registers which would temporarily use the values
at these locations.
One interesting feature that we incorporated into our digital thermometer was a variable speed
increment/decrement of the alarm temperatures...a characteristic common among many digital
alarm clocks. Our works as follows: If one of the 4 buttons that control incrementation/
decrementation of the alarm temperatures is pressed (for less than 1 sec), then the
temperature value changes by steps of .1°F. If the button is held (for >1 sec), then
the temperature value changes by steps of .5°F. The coding for this feature was simplified
by having a well designed state machine (debouncer) within the button status procedure.
One additional goal of our device, in attempt to make something that would be small and
have a low cost overhead, was to have a compact code size. This forced us to look for
various ways to optimize our code, and if possible, share areas of common code. For example,
one section of code where this was possible was within the "ConvertTemp" procedure. We
shared the code which calculates °C = 5/9 (°F - 32) with the Kelvin conversion code
since °K = °C + 273. Also, in the "UpdateSettings" routine, there are 2
instances where both MinPrompt and MaxPrompt are called, but we only need a single
copy of each.
Finally, other characteristics of our source code include:
- 3 dedicated routines to display characters/strings on the LCD
- 1 routine, "Bin2ASC", which converts a binary temperature value stored in SRAM ("disptemp")
into ASCII in the form "xxx.x°[F, C, K, or R]" and stores the ASCII string into SRAM ("ASCIItemp")
- 1 timer overflow ISR (interrupts every 1 ms)
- 1 flag to indicate if a temperature is negative, "isneg"...this occurs for Celsius
temperatures where °F - 32 < 0.
In terms of hardware, our device makes use of all 4 ports on the Atmel chip.
- Port A interfaces with the LM34 temperature sensor.
- Port B interfaces with any "add-ons" such as a fan or heater (here's it's an LED)
- Port C interfaces with the LCD. We chose to use Port C as opposed to Port D (as was used
in the reference LCD code) because the push buttons are connected to Port D on the STK-200
- PortD is connected to the push buttons.
The wiring scheme for the LCD display is as follows:
2 +5 volts - from a port pin
3 trimpot wiper (trimpot ends go to gnd and +5)
7-10 no connection