STM32F103C8使用4x4矩阵键盘实现在oled显示屏上显示加减乘除代码
时间: 2024-04-15 18:31:19 浏览: 176
以下是一个示例代码,展示了如何使用STM32F103C8微控制器、4x4矩阵键盘和OLED显示屏实现在OLED显示屏上显示加减乘除的功能:
```c
#include "stm32f10x.h"
#include "ssd1306.h"
// 定义4x4矩阵键盘的行和列引脚
#define ROW_GPIO GPIOA
#define ROW_PIN1 GPIO_Pin_0
#define ROW_PIN2 GPIO_Pin_1
#define ROW_PIN3 GPIO_Pin_2
#define ROW_PIN4 GPIO_Pin_3
#define COL_GPIO GPIOA
#define COL_PIN1 GPIO_Pin_4
#define COL_PIN2 GPIO_Pin_5
#define COL_PIN3 GPIO_Pin_6
#define COL_PIN4 GPIO_Pin_7
// 定义按键值
#define KEY_1 '1'
#define KEY_2 '2'
#define KEY_3 '3'
#define KEY_ADD '+'
#define KEY_4 '4'
#define KEY_5 '5'
#define KEY_6 '6'
#define KEY_SUB '-'
#define KEY_7 '7'
#define KEY_8 '8'
#define KEY_9 '9'
#define KEY_MUL '*'
#define KEY_CLEAR 'C'
#define KEY_0 '0'
#define KEY_EQUAL '='
#define KEY_DIV '/'
// 等待按键释放
void waitForRelease(void)
{
while ((GPIO_ReadInputData(ROW_GPIO) & (ROW_PIN1 | ROW_PIN2 | ROW_PIN3 | ROW_PIN4)) != (ROW_PIN1 | ROW_PIN2 | ROW_PIN3 | ROW_PIN4));
}
// 扫描按键
char scanKey(void)
{
char key = '\0';
GPIO_SetBits(ROW_GPIO, ROW_PIN1 | ROW_PIN2 | ROW_PIN3 | ROW_PIN4);
GPIO_ResetBits(ROW_GPIO, ROW_PIN1);
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN1) key = KEY_1;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN2) key = KEY_2;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN3) key = KEY_3;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN4) key = KEY_ADD;
GPIO_ResetBits(ROW_GPIO, ROW_PIN2);
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN1) key = KEY_4;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN2) key = KEY_5;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN3) key = KEY_6;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN4) key = KEY_SUB;
GPIO_ResetBits(ROW_GPIO, ROW_PIN3);
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN1) key = KEY_7;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN2) key = KEY_8;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN3) key = KEY_9;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN4) key = KEY_MUL;
GPIO_ResetBits(ROW_GPIO, ROW_PIN4);
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN1) key = KEY_CLEAR;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN2) key = KEY_0;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN3) key = KEY_EQUAL;
if (GPIO_ReadInputData(ROW_GPIO) & COL_PIN4) key = KEY_DIV;
waitForRelease();
return key;
}
void displayResult(int result)
{
char buffer[16];
sprintf(buffer, "Result: %d", result);
SSD1306_Clear();
SSD1306_GotoXY(0, 0);
SSD1306_Puts(buffer, &Font_11x18, SSD1306_COLOR_WHITE);
SSD1306_UpdateScreen();
}
int main(void)
{
// 初始化GPIO引脚
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = ROW_PIN1 | ROW_PIN2 | ROW_PIN3 | ROW_PIN4;
GPIO_Init(ROW_GPIO, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin = COL_PIN1 | COL_PIN2 | COL_PIN3 | COL_PIN4;
GPIO_Init(COL_GPIO, &GPIO_InitStruct);
SSD1306_Init();
char key;
int num1 = 0, num2 = 0, result = 0;
char operator;
while (1)
{
key = scanKey();
if (key >= '0' && key <= '9') // 数字键
{
if (operator == '\0')
{
num1 = num1 * 10 + (key - '0');
}
else
{
num2 = num2 * 10 + (key - '0');
}
}
else if (key == '+' || key == '-' || key == '*' || key == '/') // 运算符键
{
operator = key;
}
else if (key == '=') // 等号键
{
switch (operator)
{
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
default:
break;
}
displayResult(result);
num1 = result;
num2 = 0;
operator = '\0';
}
else if (key == 'C') // 清除键
{
num1 = 0;
num2 = 0;
operator = '\0';
SSD1306_Clear();
}
}
}
```
请注意,以上代码只是一个示例,可能需要根据具体的硬件连接和OLED显示屏的驱动库进行适当的修改和优化。
阅读全文