Path: Home =>
Keys and switches on an ADC =>
Keyboard => avr_sim matrix
Diese Seite in Deutsch:
||AVR-Single-Chip-Processors AT90S, ATtiny, ATmega
of ATMEL in practical examples.
Calculating a keypad resistor matrix with avr_sim
12/16-keypad calculation with avr_sim's matrix calculator
There are many possible ways to calculate a resistor matrix to connect a keypad to
an ADC input pin. Here is an additional opportunity to do this, and to devellop
assembler software for reading the keys: the AVR Assembler Simulator avr_sim from
version 2.7 upwards offers a tool to do that in a convenient way. You'll find
avr_sim here for download and
as source code.
This text provides a step-by-step description on how-to-do-that.
First of all we need avr_sim. It is available either as pre-compiled Linux- or
Windows-executable for 64-Bit versions of those operating systems or as source
code for the Pascal-Compiler Lazarus. If you download the executable, you only
need to unzip the file and to start it. If you prefer compiling it: see the
version-related handbook provided for your downloaded source code version on
hints how to do that.
Don't be surprised that avr_sim on its first start asks you for a folder for
AVR assembler source code. If you have such a folder, just navigate to that.
If you don't have one: it is a good idea to create such a folder. You'll never
be asked that again.
The first entry in the "Project" menu is "New". If you
start, select this. Later on the once started project will be available
under "Open previous".
Then this window opens. We enter a project name, e.g. "resistor matrix",
by clicking into the editor field for the project location we select a folder
for that and we click on the two fields to get a "Short version" and
a "Linear program". We can then enter the target device either by
selecting it with the two drop-down fields to the left, if we already know
which AVR type we like to have, or by clicking on "Device selector"
on the right if we are unsure which types can do what we need.
With the device selector we mark a one on the ADC drop-down field, to which
the resistor matrix shall be connected to.
From the large variety of potential devices, we can click on one of it in
the window in the list. We see that device with its package and connectors
in the right window. The ADC channel to connect the matrix to is converted
to Adc_, where _ means a number between 0 and 7. Here, in an ATtiny13A, it
is Adc1 on pin 7.
The button "Save" saves this hardware and "Ok" selects
it for simulation.
Several AVR types ares available in more than one package type. We are
now asked to select from one of these types. The three radio buttons
(or two or four depending from the type) select one of those packages.
The button "Show picture" shows us the type in the selected
package as picture.
With "Ok" we leave the package selection dialog.
Now avr_sim has constructed a short template of an Assembler program.
The editor shows this, and allows to add or change the source code.
By pressing the key F2 we can add the hardware of the device as ASCII
We can now assemble the source code via the Assemble menu entry.
If that was succesful, the menu entry "Simulate" appears.
When selecting this, the simulator window opens. Here we mark, in the
section "Show internal hardware", the field "ADC".
The ADC window offers the following possibilities for entries:
When entering numbers in an entry field, this is colored in yellow, as
long as it is not really entered. Press Enter to really enter the number.
Use numbers in anglosaxony format. If the number has an illegal format,
the entry field turns red.
- The ADC's reference voltage can be adjusted.
- The operating voltage can be entert.
- If you select an ADC channel from the drop-down field, you can
enter its voltage in the editor field.
- If you enable "Show R-Matrix" you'll get the resistor
matrix window. If that is not visible, disable the differential
The resistor matrix window shows this here. You can click on lots of
selections, most the entries are self-explaining. Those who want more
detailed information can consult the avr_sim-handbook's chapter on the
resistor matrix. There you'll find detailed explanations on what is
behind the selector "Use int. VRef", what you'll get with
"View data table" enabled, what "View voltages"
does and what happens if you click onto one of the resistors of the
To read a voltage from the ADC's input pin
To read an ADC pin's voltage we replace the Main: line in the source
code by the following lines:
If we assemble and start the simulator, we can set a breakpoint
to the line with "rjmp loop" by clicking into the gutter
area of this line. This allows to use "Run/Go" instead of
single stepping through the code. With this, the active conversion
field in the ADC window moves faster than with single steps.
; Set the ADLAR bit to enable 8-bit conversion,
; note that the ADLAR bit in a tiny13 is in the ADMUX
; port register, other devices place this bit elsewhere
ldi rmp,(1<<ADLAR)|(1<<MUX1) ; 8-bit ADC, select ADC channel input
; Enable the ADC, start conversion, AD prescaler = 128
sbic ADCSRA,ADSC ; Wait for ADSC bit to get clear
rjmp WaitAdc ; ADSC bit not yet cleared, continue waiting
in rmp,ADCH ; Read the MSB of the result
Because the ADC's clock is divided by 128, the conversion needs
1.39 Milliseconds. The result appears in the ADC window as
left-adjusted byte (ADCH) and in register R16: a zero. Just because
we didn't set the channel's voltage to a more interesting value yet.
If we display the R-matrix, we can set it to 16 keys, the vertical
resistors as single, and the 1% entry has already been set. Now we
press "Optimize" several times, and hopefully end with
zero overlaps (if not: restart the iteration), and if we click on
the key 1 in the schematic, we'll get the 571.1 mV onto our
ADC channel (in the ADC window). The table says that the key '1'
produces an 8-bit ADC value of 29.
Indeed: the correct result of the conversion appears. The only
question left is: how can we get the "1" from the 29?
For this we click on one of the eight resistors in the table and
we'll get the message that an include file has been saved, which
can be included into our source code with the line ".include
"resistormatrix.inc" behind the line "rjmp loop".
This brings us two tables to the source code. The first one is
"KeyTable:", consists of the lower and upper bound
of each of the 16 keys and ends with the label
The second table named "Keys:" has all the key's
ASCII characters in the correct voltage row.
With these two tables a conversion program can be written that
converts the 29 to the "1". This conversion program
is 34 lines long and can be found here.
It needs a functioning include file "keymatrix.inc"
in the project folder. The associated flow diagram can be found
in avr_sim's handbook.
Using the program for another AVR type should not be too
complicated. Attention Arduino-socialized C freaks: in an
ATmega328 most of the ADC's port registers are beyond the
scope of the IN/OUT instructions! Use LDS/STS instead for
instructions that produce an error message when assembling
(and only for those, not for all!).
Equally simple should be to replace the long-lasting polling
procedure by interrupt-driven AD conversion.
A little bit more complicated is the debouncing of the keys.
Here one profits from the long conversion time of a few milli-
seconds. If you'll get the same key over, e.g. eight, times,
you can take it for serious. The next key is then to be blocked
until the keyboard routine returns at least eight times with
a result of zero.
And now: Good luck with sukcessive approach procedures!
An den Seitenanfang
©2022 by http://www.avr-asm-tutorial.net