Lecture 4 - More on GPIO, Keypad
Strike Info
This Friday we're doing lecture of Timers and Interrupts as it's pretty important. Further, there's some videos that are alright (COVID era) so we can keep up on the schedule.
We'll cover C Embedded Programming using the ISR (like from CPE 233).
You also, after today, will be able to start on P1, the electronic lock, so if you want feel free to start that soon...
The BSRR
and BRR
We've been using:
// set Port A's MODE on Pin
GPIOA->MODER &= //...
GPIOA->MODER |= //...
The various modes are seen in Lecture 2 - (cont.) GPIO, Reset and Clock Control (RCC)#GPIO Revisited.
There's two other registers we should look at, the BSRR
(bit set-reset register) and the BRR
(bit reset register):
BSRR
: set or reset any of the pins in theODR
register. It says the top 16 bits;BRR
: ONLY reset theODR
register. Just has 16 bits, all of reset in orderPA15...0
.
BSRR
For example:
GPIOA->MODER = 0x55555555; // set A MODE, all pins to output mode
// say you want to set the BSRR...
GPIOA->BSRR = 0x0000FFFF; // set A BSRR all pins to SET..., PA15..0 is high
GPIOA->BSRR = 0xFFFF0000; // reset all PA15...0 pins back to 0's
Note that if lines 2-3 are done at the same time via:
GPIOA->BSRR = 0xFFFFFFFF;
The the set takes precedence over the reset (so then 1's are written). Notice also that:
GPIOA->ODR = 0;
Also does the same job, just clearing the data of all PA15..0
all back down to 0's. So then why use the BSRR
at all? Notice that:
GPIOA->ODR |= (0x1 << 5); // sets PA5
/* or just do */
GPIOA->BSRR = (0x1 << 5); // sets PA5, but it's JUST a write. It's really a forced operation that takes more precedence over writing to ODR.
BRR
The BRR
is the same as the BSRR
except it has less priority from the BSRR
while still being able to override the ODR
when it has values:
GPIOA->BRR = (1 << 5); // clear PA5
/* or just do */
GPIOA->BSRR = (1 << 5) << 16; // reset PA5. Equivalent expression.
Quizzes
Take the GPIO 1 Quiz here. You should feel prepared to do it now. Remember you have 4 tries, and you need 90%. Take it once you feel ready (after doing a couple assignments).
The Keypad
This is a 4x4 keypad (sometimes 4x3) with numbers on it:
The rows are inputs, and the columns are outputs. We need to turn on one of the rows as high for our read, then read the column and programmatically determine what key is pressed.
Thus, we do the following:
- Have
PA0,1,2,3
for eachR0, R1, R2, R3
, and poll over all the rows all the time. - Read the current value from
C0, C1, C2
ChatGPT unironically actually has a good method of doing it. Here it is:
#include <Keypad.h>
const int ROWS = 4;
const int COLS = 3;
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; // connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3}; // connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup(){
Serial.begin(9600);
}
void loop(){
char key = keypad.getKey();
if (key){
Serial.println(key);
// Handle the key press here
}
}
Clearly this isn't what we do for the SMT32, but it'll get you started!
Another note is that they keypad is just a bunch of buttons, hence you need to implement some debouncing, via:
- Make a Low-Pass Filter (RC Circuit)
- Make a Schmidt Trigger
- Make a SW debouncer
It is recommended to use port C for these assignments A2 and A3.