add projects
This commit is contained in:
45
labW3barnestr/Src/delay.c
Normal file
45
labW3barnestr/Src/delay.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* delay.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "delay.h" //include declaration header file
|
||||
|
||||
void delay_ms(uint32_t n){
|
||||
|
||||
// 1ms = 16,000 ticks
|
||||
for (int i = n ; i > 0 ; i--) {
|
||||
// Clear value register
|
||||
*STK_VAL = 0x0000;
|
||||
// Store 16,000 in STK_LOAD
|
||||
*STK_LOAD = 16000;
|
||||
// Enable clock, no prescaler, no interrupt
|
||||
*STK_CTRL |= CLKSOURCE;
|
||||
*STK_CTRL |= EN;
|
||||
// Loop n times: Wait for countflag high
|
||||
int flag;
|
||||
do {
|
||||
flag = ((*STK_CTRL & (1<<16))>>16);
|
||||
} while (flag != 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void delay_us(uint32_t n) {
|
||||
// 1us = 16 ticks
|
||||
for (int i = n ; i > 0 ; i--) {
|
||||
// Clear value register
|
||||
*STK_VAL = 0x0000;
|
||||
// Store 16 in STK_LOAD
|
||||
*STK_LOAD = 16;
|
||||
// Enable clock, no prescaler, no interrupt
|
||||
*STK_CTRL |= CLKSOURCE;
|
||||
*STK_CTRL |= EN;
|
||||
// Loop n times: Wait for countflag high
|
||||
int flag;
|
||||
do {
|
||||
flag = ((*STK_CTRL & (1<<16))>>16);
|
||||
} while (flag != 1);
|
||||
}
|
||||
}
|
||||
99
labW3barnestr/Src/keypad.c
Normal file
99
labW3barnestr/Src/keypad.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* keypad.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "keypad.h"
|
||||
#include "delay.h"
|
||||
|
||||
|
||||
void keypad_init(){
|
||||
//Enables the port
|
||||
*RCC_AHB1ENR |= (1<<GPIOCEN);
|
||||
|
||||
//Sets KEY0 - KEY7 as Pull-Ups
|
||||
*GPIOC_PUPDR &= ~(0xFFFF);
|
||||
*GPIOC_PUPDR |= 0x5555;
|
||||
}
|
||||
|
||||
uint8_t keypad_getKeyNoBlock(){
|
||||
|
||||
uint8_t value = 0;
|
||||
uint8_t keycode = 0;
|
||||
|
||||
//COLS to Inputs and ROWS to Outputs
|
||||
*GPIOC_MODER &= ~(0xFFFF);
|
||||
*GPIOC_MODER |= 0x5500;
|
||||
|
||||
//Clears Rows in ODR
|
||||
*GPIOC_ODR &= ~0xFF;
|
||||
//Reads COLS in IDR
|
||||
value = (*GPIOC_IDR & 0xF);
|
||||
|
||||
//if a button is pressed decode the key
|
||||
if (value != 0xF){
|
||||
//Copy COLS pattern from IDR to ODR
|
||||
*GPIOC_ODR &= ~0xFF;
|
||||
*GPIOC_ODR |= (*GPIOC_IDR & 0xF);
|
||||
|
||||
//COLS to Output and ROWS to Inputs
|
||||
*GPIOC_MODER &= ~(0xFFFF);
|
||||
*GPIOC_MODER |= 0x0055;
|
||||
|
||||
//Small delay (ensure you have this function)
|
||||
delay_us(5);
|
||||
|
||||
//Read ROWS from IDR
|
||||
value |= *GPIOC_IDR & 0xF0;
|
||||
|
||||
//Decode Key
|
||||
switch (value){
|
||||
case 0b11101110 : keycode = 1; break;
|
||||
case 0b11101101 : keycode = 2; break;
|
||||
case 0b11101011 : keycode = 3; break;
|
||||
case 0b11100111 : keycode = 4; break;
|
||||
|
||||
case 0b11011110 : keycode = 5; break;
|
||||
case 0b11011101 : keycode = 6; break;
|
||||
case 0b11011011 : keycode = 7; break;
|
||||
case 0b11010111 : keycode = 8; break;
|
||||
|
||||
case 0b10111110 : keycode = 9; break;
|
||||
case 0b10111101 : keycode = 10; break;
|
||||
case 0b10111011 : keycode = 11; break;
|
||||
case 0b10110111 : keycode = 12; break;
|
||||
|
||||
case 0b01111110 : keycode = 13; break;
|
||||
case 0b01111101 : keycode = 14; break;
|
||||
case 0b01111011 : keycode = 15; break;
|
||||
case 0b01110111 : keycode = 16; break;
|
||||
|
||||
default: keycode = 255;
|
||||
}
|
||||
}
|
||||
|
||||
return keycode;
|
||||
}
|
||||
|
||||
|
||||
uint8_t keypad_getKey(){
|
||||
|
||||
uint8_t key, keycode;
|
||||
|
||||
keycode = 0;
|
||||
|
||||
while (keycode == 0){
|
||||
//Check status of keypad
|
||||
key = keypad_getKeyNoBlock();
|
||||
if (key != 0) {
|
||||
//if key is pressed save which key
|
||||
keycode = key;
|
||||
//wait for the release of the key
|
||||
while (key != 0){
|
||||
key = keypad_getKeyNoBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
return keycode;
|
||||
}
|
||||
|
||||
120
labW3barnestr/Src/lcd.c
Normal file
120
labW3barnestr/Src/lcd.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* lcd.c
|
||||
*
|
||||
* Created on: Dec 17, 2020
|
||||
* Author: Trevor Barnes
|
||||
*/
|
||||
|
||||
#include "lcd.h"
|
||||
#include "delay.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
void writeInstruction(uint8_t inst) {
|
||||
// Reset RS, RW, E
|
||||
*GPIOC_ODR &= ~(RS);
|
||||
*GPIOC_ODR &= ~(RW);
|
||||
*GPIOC_ODR &= ~(E);
|
||||
// Set E
|
||||
*GPIOC_ODR |= (E);
|
||||
// Clear databus
|
||||
*GPIOA_ODR &= ~(0xFF<<4);
|
||||
// Set databus to passed in instruction value
|
||||
*GPIOA_ODR |= (inst<<4);
|
||||
// Reset E
|
||||
*GPIOC_ODR &= ~(E);
|
||||
delay_us(37);
|
||||
}
|
||||
|
||||
void writeData(uint8_t inst) {
|
||||
// Reset RW, E
|
||||
*GPIOC_ODR &= ~(RW);
|
||||
*GPIOC_ODR &= ~(E);
|
||||
// Set RS
|
||||
*GPIOC_ODR |= (RS);
|
||||
// Set E
|
||||
*GPIOC_ODR |= (E);
|
||||
// Clear databus
|
||||
*GPIOA_ODR &= ~(0xFF<<4);
|
||||
// Set databus to passed in instruction value
|
||||
*GPIOA_ODR |= (inst<<4);
|
||||
// Reset E
|
||||
*GPIOC_ODR &= ~(E);
|
||||
delay_us(37);
|
||||
}
|
||||
|
||||
void lcd_init(){
|
||||
|
||||
// Port Setup
|
||||
// Enable GPIO A and C in RCC
|
||||
*RCC_AHB1ENR |= (GPIOAEN||GPIOCEN);
|
||||
// Set DB pins to outputs
|
||||
*GPIOA_MODER &= ~(0xFFFF<<8);
|
||||
*GPIOA_MODER |= (0x5555<<8);
|
||||
// Set RS, RW, and E pins to outputs
|
||||
*GPIOC_MODER &= ~(0x3F<<16);
|
||||
*GPIOC_MODER |= (0x15<<16);
|
||||
// Delay for 40 ms
|
||||
delay_ms(40);
|
||||
|
||||
// Display Setup
|
||||
// Write Function Set
|
||||
writeInstruction(FUNCTION_SET);
|
||||
delay_us(37);
|
||||
// Write Function Set
|
||||
writeInstruction(FUNCTION_SET);
|
||||
delay_us(37);
|
||||
// Write Display On
|
||||
writeInstruction(DISPLAY_TOGGLE);
|
||||
delay_us(37);
|
||||
// Write Display Clear
|
||||
writeInstruction(DISPLAY_CLEAR);
|
||||
delay_ms(2);
|
||||
// Write Entry Mode Set
|
||||
writeInstruction(ENTRY_MODE_SET);
|
||||
delay_us(37);
|
||||
|
||||
}
|
||||
|
||||
void lcd_clear(){
|
||||
writeInstruction(DISPLAY_CLEAR);
|
||||
delay_ms(2);
|
||||
}
|
||||
|
||||
void lcd_home() {
|
||||
writeInstruction(0x80);
|
||||
delay_ms(2);
|
||||
}
|
||||
|
||||
void lcd_set_position(uint8_t posIndex) {
|
||||
posIndex--;
|
||||
int inst = 0x80;
|
||||
if (posIndex > 15) {
|
||||
inst |= (1<<6);
|
||||
posIndex -= 16;
|
||||
}
|
||||
inst |= posIndex;
|
||||
writeInstruction(inst);
|
||||
}
|
||||
|
||||
int lcd_print_string(char* str) {
|
||||
int index = 0;
|
||||
while (str[index] != 0x00) {
|
||||
writeData(str[index]);
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void lcd_print_char(char c) {
|
||||
writeData(c);
|
||||
}
|
||||
|
||||
|
||||
int lcd_print_num(int i){
|
||||
char numString[17];
|
||||
sprintf(numString, "%d", i);
|
||||
return lcd_print_string(numString);
|
||||
}
|
||||
119
labW3barnestr/Src/main.c
Normal file
119
labW3barnestr/Src/main.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* main.c
|
||||
*
|
||||
* Created on: Dec 17, 2021
|
||||
* Author: Trevor Barnes
|
||||
* A driver file to demonstrate the implemented functionality of the LCD and keypad. This file
|
||||
* contains functionality for a simple 4-operation calculator with two operands.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "lcd.h"
|
||||
#include "keypad.h"
|
||||
|
||||
char mathKeys[] = {'1','2','3','+','4','5','6','-','7','8','9','x','*','0','=','/'};
|
||||
char mathNums[] = {'1','2','3','_','4','5','6','_','7','8','9','_','_','0','_','_'};
|
||||
char mathOper[] = {'_','_','_','+','_','_','_','-','_','_','_','x','*','_','_','/'};
|
||||
char calculation[5];
|
||||
|
||||
void calculate(int operand1, int operand2, char operation) {
|
||||
int result;
|
||||
switch (operation) {
|
||||
case '+':
|
||||
result = operand1 + operand2;
|
||||
break;
|
||||
case '-':
|
||||
result = operand1 - operand2;
|
||||
break;
|
||||
case 'x':
|
||||
result = operand1 * operand2;
|
||||
break;
|
||||
default:
|
||||
if (operand2 == 0) {
|
||||
lcd_clear();
|
||||
char divError[] = " Err: Undefined ";
|
||||
lcd_print_string(divError);
|
||||
return;
|
||||
} else {
|
||||
result = operand1 / operand2;
|
||||
}
|
||||
}
|
||||
lcd_print_num(result);
|
||||
}
|
||||
|
||||
void inputSequence() {
|
||||
int currentKeyIndex;
|
||||
lcd_clear();
|
||||
int seqIndex = 0;
|
||||
|
||||
// While key != number, getKey
|
||||
do {
|
||||
currentKeyIndex = keypad_getKey()-1;
|
||||
if (mathKeys[currentKeyIndex] == '*') {
|
||||
return;
|
||||
}
|
||||
} while (mathKeys[currentKeyIndex] != mathNums[currentKeyIndex]);
|
||||
calculation[seqIndex] = mathKeys[currentKeyIndex];
|
||||
lcd_print_char(mathKeys[currentKeyIndex]);
|
||||
seqIndex++;
|
||||
|
||||
// While key != operation, getKey
|
||||
do {
|
||||
currentKeyIndex = keypad_getKey()-1;
|
||||
if(mathKeys[currentKeyIndex] == '*') {
|
||||
return;
|
||||
}
|
||||
} while (mathKeys[currentKeyIndex] != mathOper[currentKeyIndex]);
|
||||
calculation[seqIndex] = mathKeys[currentKeyIndex];
|
||||
lcd_print_char(mathKeys[currentKeyIndex]);
|
||||
seqIndex++;
|
||||
|
||||
// While key != number, getKey
|
||||
do {
|
||||
currentKeyIndex = keypad_getKey()-1;
|
||||
if(mathKeys[currentKeyIndex] == '*') {
|
||||
return;
|
||||
}
|
||||
} while (mathKeys[currentKeyIndex] != mathNums[currentKeyIndex]);
|
||||
calculation[seqIndex] = mathKeys[currentKeyIndex];
|
||||
lcd_print_char(mathKeys[currentKeyIndex]);
|
||||
seqIndex++;
|
||||
|
||||
// While key != '='
|
||||
do {
|
||||
currentKeyIndex = keypad_getKey()-1;
|
||||
if(mathKeys[currentKeyIndex] == '*') {
|
||||
return;
|
||||
}
|
||||
} while (mathKeys[currentKeyIndex] != '=');
|
||||
lcd_print_char(mathKeys[currentKeyIndex]);
|
||||
// Calculate
|
||||
calculate(calculation[0] -= '0', calculation[2] -= '0', calculation[1]);
|
||||
do {
|
||||
currentKeyIndex = keypad_getKey()-1;
|
||||
} while (mathKeys[currentKeyIndex] != '*');
|
||||
}
|
||||
|
||||
// main
|
||||
int main(){
|
||||
|
||||
// Initialize Components
|
||||
keypad_init();
|
||||
lcd_init();
|
||||
|
||||
// Prompt Message
|
||||
char prompt1[]= "+- Calculator x/";
|
||||
char prompt2[]= " Push any key ";
|
||||
lcd_print_string(prompt1);
|
||||
lcd_set_position(17);
|
||||
lcd_print_string(prompt2);
|
||||
keypad_getKey();
|
||||
|
||||
while(1) {
|
||||
inputSequence();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user