Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

EEET2256  INTRODUCTION TO EMBEDDED SYSTEMS

LABORATORY 3

INTERFACING WITH HARDWARE - KEYPAD CONTROLLER

1     AIMS

(i)        To develop an appreciation of the design workflow when writing code (firmware) for  the  ATmega32A  microcontroller  using  the  Microchip  Studio  7.0  Integrated Development Environment (IDE).

(ii)        To design, simulate, build and test both a hardware and software interface between

the ATmega32A (OUSB-IO Board) and an external matrix keypad.

(iii)      To construct an interface (via simulation / physical hardware) that displays the digits

entered on the keypad and then perform a basic mathematical operation.

(iv)       To  build  and  contrast  an  application  written  in  both  Assembler  and  C  and  then

deploy it to a physical target board after a successful simulation. (Deployment for face-to-face students only).

2     INTRODUCTION

In this laboratory you will use Microchip Studio 7.0 to develop and deploy a series of programs written in both Assembler and C to a physical ATmega32A microcontroller. Marks will be awarded for  developing  fully  functional  programs  and  comparing  the  results  between  the  alternate implementations. This laboratory accounts for a total of 13% of the overall course grade. Face-to- face students are required to deploy the developed applications to a physical OUSB-IO Board, whilst for those students completing the laboratory component online, an extensive discussion and review of the simulation outcomes is required.

You will work individually, and your progress will be assessed via a written laboratory report (report and code submission) which is due Friday, Week 8 at 11:59pm. A late penalty of 10 marks per 24-hour period will apply for submission past the due date / time. The knowledge gained during this laboratory will form part of the second Lectorial Quiz content which will be held later in the semester.

The aim of this laboratory is to construct both a software and physical interface to a matrix keypad as illustrated in Figure 1. The matrix keypad used in this course consists of 16 individual switches of which the control signals are multiplexed (shared between) onto individual I/O (Input / Output) lines. By applying various logic levels to the control lines in a particular manner it is possible to read the individual switches with just eight lines rather than the full sixteen (one for each button). As this is quite an involved task the first part of the laboratory will focus on careful planning of the underlying algorithm. Note that additional material will be provided in the lecture series describing the actual I/O characteristics of the ATmega32A microcontroller.

One of the more important functions of an embedded microcontroller is to provide monitoring and control functions for the product it is embedded in. In this laboratory, we are looking at the digital I/O system of the ATmega32A microcontroller.

 

Figure 1 - Matrix Keypad  Left Image Reproduced from [1]

To begin our discussion on how to use I/O devices with a microcontroller consider one of the simplest digital interface devices such as a switch. These come in many configurations, but all can be used to generate a binary signal at the I/O port of the microcontroller. One simple scheme is illustrated in Figure 2a (left). Here, a switch is connected to a single port bit. A resistor is used to pull up the port line to the supply (VCC). When the switch is pressed the line is pulled down to ground. The second diagram (Figure 2b - right) shows a variation on this - here, a double-throw switch is used to select between the supply and ground potentials.

 

 

 

 

Figure 2 - Pull-up Resistor Configuration - Normally Open (left) vs. Normally Closed (right)

One of the problems with this configuration is that each switch uses a complete port line. In a system where there are lots of switches it is likely that all the microprocessor ports will be used just on switches. Consider a typical PC keyboard - inside a keyboard there is a variation of a small 8-bit Intel processor monitoring more than 100 keys, plus the additional combinations using the Shift, Ctrl,  Alt  and  function  keys.  The  signal  obtained  via  the  individual  keyboard  switches  are multiplexed (shared) together and then sent to the motherboard over a serial connection such as

USB.

Therefore, switches are very often multiplexed and a key scanning process is used to find the switch that has been pressed. This is especially useful where one or at most two keys are likely to be pressed at any one time. This is a time-space trade-off - we can trade off space (number of port pins) for the time it takes to scan and find the specific key.

Keypad Scanning

An example of a multiplexed keypad is shown Figure 3. In this circuit, 12 push button switches are multiplexed onto 7 lines and connected to one of the 8-bit ports on the microcontroller (Port B in this example and note that PB3 is unused). You can see that each of the  12 the pushbutton switches are positioned at the intersection of a grid formed using three output bits and 4 input bits. The keypad operation is based on these connections. Note that the actual port used on the OUSB- IO Board and the keypad is different.

 

Figure 3  Simplified Matrix Keypad - Port Interface

At idle, with no key pressed the pull-up resistors keep the four input lines PB7..4 pulled up to VCC—the inverters (NOT gates) turn these into logic 0 at the port. When a button is pressed, for example, at the bottom right grid position (key ‘#’), two lines (in this case PB0 and the inverter connected to PB7) are shorted together. If logic 0 is written to output PB0, the corresponding inverter input will be pulled low as a result. We can tell:

a)   if a key is pressed (sending a line low results in a port line high)

and

b)   which particular key is pressed (each key sits at a unique input / output pair).

keypad scanning process can be set up as follows (in this particular instance):

•    Set up the port (Port B) so that bits 0..2 are outputs and bits 4 to 7 are inputs. We only need to do this once at the very beginning as the keypad is hardwired and will not change.

•    Send one of the output lines low e.g., PB0.

•   Read  the  four  upper  bits  and  test  to  see  if any  of them  have  been  pulled  high.  If so, determine which one.

•    Repeat this for the other output port bits PB1 and PB2.

•   Keep doing this while the power is on.

Note that when we detect a key press, there is still one more step to go. The scanning algorithm finds the key in terms of its grid coordinates given by PB[7..4] for each PB[2..0] combination. For example, from the diagram above we can see that a scan-code of PB[7..0] = 1000x110 indicates that the ‘# ’ key has been pressed. Have a look at the diagram and confirm this. Part of the laboratory will require you to find the scan-codes for all other keys.

You will see that each code is unique - we can tell them apart - and each relates one-to-one with a particular key. However, these code values are not particularly useful as they don’t correspond to any conventional number system - they are hardware specific. You could invent a huge number of variations on the hardware configuration we have used. All of these would be still correct - just different.

The final step is to convert the hardware specific scan-code into a more user-friendly” code. The specific target will depend on your application: an ASCII code is a good choice for a keyboard controller (what is ASCII? Why is it a good choice here?). If you are designing a calculator, an integer might be a better choice. If the system is an embedded alarm system, it might be sufficient to simple set a particular bit in a status byte. Finally, if the number is to be displayed, then we might want to convert to a seven-segment driver code. As the embedded system designer, it’s your choice.

ATmega32A I/O Ports

Before connecting the keypad to the ATmega32A there are several steps that need to be undertaken. The first is to develop an understanding of the underlying I/O ports and how they need to be configured for a particular application. In the lecture series a basic example of how to configure Port B as a single-bit output was demonstrated. To interface with the matrix keypad the concepts covered need to be extended.

The full block diagram of a single I/O port pin appears in Figure 4.

 

Figure 4 - ATmega32A I/O Port Structure [2]

The basic concept of an I/O port pin is as follows:

•    Ports can be set up to be either inputs or outputs (or both).

•    They therefore have two registers for each pin:

o The Data Directions Register  (DDR)  controls whether the pin  is  an  output  or an input. The default on reset is input. Writing a ‘1’ to the DDR sets up the bit as an output. Note: Even though the device may have been reset it is prudent to set the DDR to '0' if an input is required.

o The second (output) register holds the output value sent to the port.

•   Ports in the ATmega32A have their own I/O  space.  This means that they respond to  a specific  address  range  in  the  I/O  locations  of the  microprocessor.  The  IN  and  OUT instructions transfer data between the 32 general purpose working registers and this I/O space. For example, Port A is located at Address 0x1B. Executing the Assembler instruction IN R1, 0x1B will read all 8 bits of this port location into R1. Note that the C compiler will allow the developer to use pointer operations using memory address 0x3B (data space).

•   At reset (or power-up) ports are set into read mode. To write to a port requires that port to be first set up as an output. Typically, this is only done once in an initialisation routine at the start of the program. Writing a ‘1’ to the DDR register will set this mode. For example, remembering that there are 8 DDR and 8 data bit registers for each 8-bit port, writing the number 0x01 to location 0x1A (DDR address for Port A), will cause bit 0 in Port A to become an output and bits 1-7 to be inputs.

•   Once the DDR is configured each write to a Port location will load the output register, but this will reach the output pin only on those bits set as output (see the block diagram above to make sense of this). For example, writing the number 0x55 to Port A will load its output register but only bit 0 will change as this is the bit we previously set up as an output.

So, in summary, your task is to set up the port bits as outputs (or inputs) by writing to the DDR, then reading or writing to the port as required by the program.

OUSB-IO Board Mapping

As you already know, the OUSB-IO Board has some built-in connections to onboard LEDs (Light Emitting Diodes) and DIP  (Dual  Inline Package)  switches.  The diagram in Figure  5 has been extracted from the OUSB schematic [3] available on the subject Canvas website and shows that Port C is connected to a set of 8 DIP switches and Port B drives a set of LEDs . You will use these in the first part of the laboratory then replace the 8 DIP switches with a 16-key multiplexed keypad in second portion.

 

Figure 5 - USB-IO Board Port Mapping [3]

3     DESIGN AND IMPLEMENTATION - SECTION A

This laboratory is split into three sections of which all need to be successfully completed to be awarded full marks. The first step in the process is to examine and extend the provided Assembler code to read the switches and drive the LEDs.

You will start with a template program and enhance so that (eventually) it:

1. reads a value from the 16-key scanned keypad;

2. converts the value from a scan-code to hexadecimal and,

3. displays the results on the LEDs on the OUSB board.

Do not lose sight of these objectives when you are stuck with writing code for the core of the program. The general program flow is illustrated in Figure 6.

 

Figure 6 - Section 3A Flowchart

One complication is that humans deal in decimal numbers but computers work with binary (or, equivalently, hexadecimal). Therefore, part of the task will involve writing conversion routines. There are various ways to do this but in this laboratory you will use a variation on the table look-up you used in Laboratory 1.

The overall process is broken into many small steps. This is intended to provide practice with editing, assembling, loading and running programs. It also duplicates how a real program should be developed and / or debugged - one small step at a time. Newcomers to microcontrollers should not expect to be able to write many lines of code and have it work first time. You need to proceed carefully and use the debugger / simulator to check it at each stage.

a)  Begin a new Assembler level project within Microchip Studio. From the course Canvas website download  the  template  'lab3a_template.asm'  and  include  it  into  the  project.  (This  can  be achieved by opening the .asm file in a text editor and then pasting it into the newly created project). Build the program and then launch the code within the Simulator. Note that you will need to enable the simulator as a target before launching the debugger. This can be configured by opening the 'Project Properties' window -> Tool option, select 'Simulator' as the 'Selected debugger /programmer'.

b)  Single step the program and determine what functionality it currently contains. What is the purpose of the .equ directive and how is it used in this instance? In terms of the overall aims, what  functionality  does  the  provided  template  program  current  have?  Using  dot-points, describe the basic operation of the template code in your report.

c)  Based on Figure 5 it can be seen that the DIP switches are connected to Port C, whereas the LEDs are connected to Port B. To use all eight DIP switches and LEDs what value should the respective  Data  Direction  Registers  (DDRs)  contain?  Verify  this  using  the  ATmega32A datasheet  (available  on  subject  Canvas website)  and briefly  explain the reasoning  in your report. Modify the Assembler code to configure the DDRs correctly for both ports and place a

screenshot  of the  simulator  I/O  port  values  to  demonstrate  that  the  port  has  been  setup correctly.

d)  Using the simulator, determine whether the program is functioning correctly. Once the code has been explored deploy it to the OUSB-IO Board (or via the simulator for online only students). Change the position of the switches and observe the output - is it what you expect?

e)  At this point the procedure  "ReadSw" returns a test value  "0x03". Is this the value that is currently displayed on the LEDs? In reality, the value to be displayed on the LEDs should be updated  in  the  procedure  "Display".  Modify  the  code  such  that  the  LEDs  are  updated accordingly.

f)   Whilst the code may now deploy correctly it may not perform as expected. Update the routine “ReadSw” so that it does something sensible (like reading the switches). Using the simulator test the overall program by iterating through the various switch combinations. Place a copy of your tested values and the corresponding output of the simulator in your report with a brief discussion.    Document    your    code    (with    comments)    and    submit    the    file    as s1234567_sectionA_f.asm, where s1234567 is your student number.

g)  Although the developed code functions successfully in Assembler it can be quite difficult to maintain should the underlying hardware change. Redevelop the solution in C (by creating a new project). If you decide to use functions what do you notice about the disassembled code? How many Assembler level instructions (with full optimisation enabled (-O3)) are required to complete the  same task? Briefly describe how your program  functions in C  (what are the differences  in  the  Assembler  and  C  versions)  and  submit  your  code  (with  comments)  as s1234567_sectionA_g.c, where s1234567 is your student number.

4     DESIGN AND IMPLEMENTATION - SECTION B

The second part of the laboratory extended the currently designed system to use a 16-digit matrix keypad in place of the Port C switches. Figure 7 depicts a simplified view of the keypad that will be used in the practical component of this laboratory. Note that it does vary from Figure 3 as the inverters are not included.

 

Figure 7  4 x 4 Membrane Keypad  Physical Connection (Left), Switch Connection (Right)

When designing a program to interface with the matrix keypad there are two important features to note:

•   The keypad structure used in this laboratory is simpler than the one depicted in Figure 3 as the  inverters  are  not  included.  The  pull-up  resistors  are  internal  to  the  ATmega32A microcontroller  as part  of the port  structure  (noted  on  the  schematic).  Page  57  of the ATmega32A datasheet [2] manual describes how this works as: “If PORTxn is written logic one when the pin is configured as an input pin, the pull-up resistor is activated. How will this be handled by the program? Can you see how this works in hardware (look at Figure 4)?

•   The I/O is now via Port C and the lines are different to the previous example. This makes it identical  to  the  units  you  can  buy  online,  which  simplifies  the  scanning  routine.  The reference datasheet for the Keypad has also been uploaded to the subject Canvas website.

You can see that each of the 16 keys still sit at the intersection of two port lines on Port C. The actual outputs and inputs are as shown.

a)  Begin a new Assembler level project within Microchip Studio. From the course Canvas website download  the  template  'lab3b_template.asm'  and  include  it  into  the  project.  (This  can  be achieved by opening the .asm file in a text editor and then pasting it into the newly created project). Build the program and then launch the code within the Simulator. Note that you will need to enable the simulator as a target before launching the debugger. This can be configured by opening the 'Project Properties' window -> Tool option, select 'Simulator' as the 'Selected debugger /programmer'.

b)  Figure 8 is a general flowchart for the numeric portion of the keypad scanning process. You can see that the sequence involves setting each column low in turn to see if a corresponding key has been activated. If a row signal is detected, this indicates that a key has been pressed. How do we detect this? Hint: The row inputs default to high (based on the pull-up resistors being enabled). If you read Port C when no key is pressed you will read the same value you placed there. Conversely, a different value indicates that a key has been pressed. Once that happens, we need to find out which one it is.

 

Figure 8 - Keypad Scanning Algorithm

c)   You now need to develop code to perform the following tasks. Firstly, modify the routine ReadKP to:

•   assert the required column.

•   wait a suitable time (why wait? Look at the synchronizer’ circuit in the port diagram).

•   reads the rows to determine if a key is pressed;

•   exits if a key has been pressed, otherwise loops back.

Design the additional routines via flowcharts and the corresponding pseudocode and place this in your report. Furthermore, outline how the code was tested and proved to be functional.

d)  Create a table of 256 values which determines the value of the key pressed. Base your code on the table scanning algorithm you developed in Laboratory 1. This time it is the scan-code you are searching for and the location gives the hex value. Once you have coded the column scan (1, Figure 8), you should have a working system. Document your code (with comments) and submit the file as s1234567_sectionB_d.asm, where s1234567 is your student number.

e)  Plug in the keypad as  shown in Figure 9. Note the position and orientation. You need to connect pin 1 of the keypad to PortC0. Download and run your code on the OUSB-IO Board. Don’t forget that the DIP switches are still hardwired onto Port C, so turn them all off to prevent the possibility of interference with the keypad operation. For online students, you will use the simulator rather than interfacing with the actual keypad.

 

Figure 9 - OUSB-IO Board and Keypad Connection

f)   Once a key has been successfully decoded write the value from the scan-code table to the LEDs on Port B. The value should remain present until a new key is pressed. What should be the output if either the asterisk (*) or hash (#) key is pressed? In your report compare the simulated results to the actual final hardware implementation. You can use a series of photographs (face- to-face  students) /  screenshots  (online  students) to  demonstrate that the  implementation  is working correctly.

g)  Once the code has been completed in Assembler redevelop the solution in C and display it to your  Laboratory  Demonstrator.  Each  individual  key  press  should  result  in  the  LEDs representing the entered number until the next key press is detected. Document your code (with comments) and submit the file as s1234567_sectionB_g.c, where s1234567 is your student number.

You can stop here for half marks for this section of the lab i.e., 75% total if you have completed all sections to this point.

5     DESIGN AND IMPLEMENTATION - SECTION C

The routine covered is an example of a brute force” approach. The scan code is used as an offset into an 256  entry table in which only  16 codes result in relevant hex values  (considering the numbers and * / # and letters A, B ,C and D). Look at what will happen if for some reason you don’t get one of the scan-codes you expect (e.g., if two keys are pressed simultaneously)? What if the hardware changed and therefore the scan codes were different. How would the code change?

a)   The objective of this section is now to read two sequential keystrokes from the keypad and arrange them in the upper and lower 4 bits (nibbles) of the LED display - first digit in the upper nibble, second in the lower. To your C implementation add a function called "ReadTwo" that uses pointers to temporarily store two sequential keypad reads.

b)  Once the two values have been obtained combine these two values. You need to think about where  this  new  routine  will  fit  into  your  existing  program.  In  your  report  document  the necessary changes to your code with a flowchart / diagram.

c)   The aim is for the first number pressed to go into the upper nibble (4 bits) of the result and the second into lower nibble. The combined result is returned in one 8-bit register (How do you write to a register in C?). This is equivalent to the calculation: RD = 16* RS1 + RS2. Note that multiplication by 16 is equivalent to a left shift of 4 bits when zeros are shifted into the lower bits. Adding the other register will merge the two digits. Recompile and test your code. You should now be displaying the two numbers. Document your code (with comments) and submit the file as s1234567_sectionC_c.c, where s1234567 is your student number. In your report place a photograph (face-to-face students) / screenshot (online students) and briefly describe how you proved that the system is working correctly.

6     ASSESSMENT PROCESS

When you have finished all the assessable items please place your findings in a brief laboratory report (no more than 7 pages of content). Ensure that you have described the outcomes of your code and provided clear screenshots of the register window (or other sections) to support your discussion. The  code  samples  are  to  be  uploaded  to  the  Canvas  website  as  per  the  naming  conventions specified. A rubric can be found in the remaining pages of this document and on the subject Canvas website.

Your report should clearly analyse the difference between the Assembler and C implementations and succinctly explain any differences identified. If you are completing the laboratory component online (and are in a dedicated online session) a greater emphasis will be placed on the simulation outcomes.

The laboratory is an individual assessment. No other libraries or source code (apart from your own or those directly specified) are to be incorporated into the submission. Furthermore, a penalty of 10 marks per 24-hour period reduction will be applied to all late submissions (inclusive of weekends).

7     REFERENCES

[1] ProtoSupplies,          Membrane          Keypad          4X4          Matrix,          Available          Online:

https://protosupplies.com/product/membrane-keypad-4x4-matrix/, Accessed: 17/08/2022

[2] Microchip,   Atmel   8-bit   AVR   MCU   FLASH   Microcontroller,   "ATmega32A-DataSheet- Complete-DS40002072A", Available Online, 2021, Figure 13.2, pp. 57.

[3] Radcliffe,  P.J.,  "Open  USBIO  Schematic",  -  Revision  1.1.  Available  on  EEET2256  Canvas

Website.