I was having a bit of a think about what to do with the sixth installment of this course. So what better than to add a keypad so that we can control what is displayed on the seven segment display.
What you can expect to learn:
- How to interface a keypad to the microcontroller
- More of an explanation of the retlw instruction
- How to modify the PROGRAM COUNTER to jump to a certain line of code
- Some more interesting programming techniques
Okay so first up, let’s get some background on how the keypad works:
You can see in the image above, that each of the 12 keys are multiplexed. that means that there arent simply 24 outputs (I.E. two connections for each button) but they are connected together in rows and columns (4 rows and 3 columns)
So to get this thing to work we have to add a few resistors and then program a unique piece of code to ‘scan’ the keypad. This is how we are going to connect the keypad to our existing seven segment display circuit:
So this is how it will work. Our four rows are all connected to ground through the 10k resistors. So our four inputs to the microcontroller namely – PORTA pin 3 PORTA pin4 PORTA pin 7 and PORTA pin 6, will all have logic zero’s on their inputs.
When we start the scan routine (which you will soon see in the sourcecode) we want to check one column at a time and check if any of the four buttons in the column has been pressed. If one has been pressed then we will copy that number into the working (w) register for use after the scan is completed. if NO key has been pressed then we don’t copy anything into the w register and we just keep scanning the keypad. So what do i mean by scan the keypad?
You can download the source code from the bottom of this page.
We start the scan by sending a logic 1 to PORTA pin 0 – this means that the entire left hand column of the keypad has a logic one waiting on one side of each key. now the other sides of all keys are connected to ground through the resistors. If we then press key 1 at this stage, then we have now placed a logic 1 (+5v) ontop of the top row resistor, this means that the resistor is now dropping +5v and since PORTA pin 3 is connected to the top of the resistor, we now have a logic one on PORTA pin 3. so we have now sensed that key 1 has been pressed and at this point – we would copy decimal 01 into the working register.
once we have scanned all four buttons in the first column, we then send a logic 0 to PORTA pin 0 because we are no longer scanning it anymore. We then want to scan the middle column – so we send a logic 1 to PORTA pin 1. Now we repeat exactly the same process – does PORTA pin 3 have a logic 1? if yes then key 2 has been pressed but if not the check to see if we have a logic 1 on PORTA pin 4 – if we do then key 5 has been pressed and so on…
The sourcecode for scanning the keypad should be quite straight forward and hopefully you can see the need for doing it this way.
Once we have scanned the entire 12-keys, what ever number that we copied into the w register, we will now copy that for use a little later into ‘what_button’ variable. We will use this number to tell the program what number to display on the seven segment display. now we have finished the scan routine – we return to the main routine.
The next sub routine is quite a small one and is dedicated to displaying the desired digit on the seven segment display.
When we first call the display_digit routine, the first thing it does is call another routine (call digit_data) This is where we will grab our byte of data to send to our seven segment display – we do this by altering the program counter and by using retlw statements.
I think i mentioned it before, but the program counter is a special counter inside the pic that lets the pic know what line of code it is upto. if we alter the number stored in the program counter – we can jump to any line of code within our program. So you can see that we copy our number stored in what_button into the w register. We then ADD this number to the program counter – which means we immediately jump to whatever line of code it is that the number represented.
I.E. if we had pushed the 0 key on the keypad, then we would have copied ’00’ into the what_button variable. this number ’00’ is then added to the program counter (which in effect does not change the program counter) so the program just goes to the very next line, which is a retlw statement containing the byte of data the represents a zero to be displayed on the seven segment display.
OR if we had pressed the 7 key on the keypad, then we would have had ’07’ in the what_button variable. This would have then been added to the program counter which means we would immediately jump seven spaces down and would run the retlw statement at that location (which would have the byte of data the represents a 7 on the seven segment display. and so on…
Now we touched briefly on the retlw instructions in the last module. retlw statements are just like the return statement (in that it will return to from where it was called) but the unique thing about retlw is that it returns WITH A BYTE OF DATA IN W so in this case, we will return back to the display_digit routine with the relavent data for the digit we want to display. This data is then placed on PORTB and since our seven segment display is connected to PORTB – it will display that digit.
Some things to think about:
- can you see how the program holds onto the last digit pressed even though we don’t press any buttons when the keypad is scanned again?
- can you see how handy it can be to modify the program counter?
- can you see how retlw statements can be very handy when you have alot of data that you may want called at different times or in different situations?
Thankyou all so much for looking – God Bless.