hc32l13x 4x5矩阵键盘,使用9个gpio口,3个数码管,每个按键带灯,每个灯使用数码管一个led,并给出示例代码
时间: 2023-11-04 14:05:41 浏览: 127
以下是一个基于HC32L13X的4x5矩阵键盘的示例代码:
```
#include "hc32l13x.h"
#define KEY_PORT GpioPortB
#define KEY_PIN GpioPin12
#define LED_PORT GpioPortB
#define LED_PIN GpioPin14
#define DIGIT_PORT GpioPortC
#define DIGIT_PIN_1 GpioPin0
#define DIGIT_PIN_2 GpioPin1
#define DIGIT_PIN_3 GpioPin2
#define KEY_SCAN_INTERVAL 50
#define KEY_LONG_PRESS_TIME 2000
uint8_t key_status[4][5] = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}
};
const uint8_t key_map[4][5] = {
{'1', '2', '3', 'A', 'L'},
{'4', '5', '6', 'B', 'R'},
{'7', '8', '9', 'C', 'U'},
{'*', '0', '#', 'D', 'D'}
};
const uint8_t digit_map[10] = {
0x3F, 0x06, 0x5B, 0x4F, 0x66,
0x6D, 0x7D, 0x07, 0x7F, 0x67
};
volatile uint32_t sys_tick = 0;
void SysTick_Handler(void)
{
sys_tick++;
}
void delay(uint32_t ms)
{
uint32_t start_tick = sys_tick;
while (sys_tick - start_tick < ms);
}
void set_led(uint8_t value)
{
if (value)
Gpio_SetIO(LED_PORT, LED_PIN);
else
Gpio_ClrIO(LED_PORT, LED_PIN);
}
void set_digit(uint8_t digit, uint8_t value)
{
switch (digit) {
case 1:
Gpio_WriteOutBits(DIGIT_PORT, DIGIT_PIN_1, digit_map[value]);
break;
case 2:
Gpio_WriteOutBits(DIGIT_PORT, DIGIT_PIN_2, digit_map[value]);
break;
case 3:
Gpio_WriteOutBits(DIGIT_PORT, DIGIT_PIN_3, digit_map[value]);
break;
}
}
void scan_key(void)
{
static uint8_t key_state[4][5] = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}
};
static uint32_t key_press_time[4][5] = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}
};
uint8_t i, j;
for (i = 0; i < 4; i++) {
Gpio_SetIO(KEY_PORT, KEY_PIN + i);
for (j = 0; j < 5; j++) {
if (Gpio_GetIO(KEY_PORT, KEY_PIN + 4 + j)) {
if (!key_state[i][j]) {
key_state[i][j] = 1;
key_press_time[i][j] = sys_tick;
} else {
if (sys_tick - key_press_time[i][j] >= KEY_LONG_PRESS_TIME) {
key_status[i][j] = 2;
}
}
} else {
if (key_state[i][j]) {
key_state[i][j] = 0;
if (sys_tick - key_press_time[i][j] < KEY_LONG_PRESS_TIME) {
key_status[i][j] = 1;
}
}
}
}
Gpio_ClrIO(KEY_PORT, KEY_PIN + i);
}
}
int main(void)
{
SystemInit();
SysTick_Config(SystemCoreClock / 1000);
Gpio_SetAnalogMode(GpioPortC, GpioPinAll);
Gpio_SetAnalogMode(GpioPortD, GpioPinAll);
Gpio_SetAnalogMode(GpioPortF, GpioPinAll);
Gpio_SetOutputMode(LED_PORT, LED_PIN, GpioOutPushPull, GpioOutHigh);
Gpio_SetOutputMode(DIGIT_PORT, DIGIT_PIN_1 | DIGIT_PIN_2 | DIGIT_PIN_3, GpioOutPushPull, GpioOutLow);
Gpio_SetInputMode(KEY_PORT, KEY_PIN + 4, GpioPullUp);
Gpio_SetInputMode(KEY_PORT, KEY_PIN + 3, GpioPullUp);
Gpio_SetInputMode(KEY_PORT, KEY_PIN + 2, GpioPullUp);
Gpio_SetInputMode(KEY_PORT, KEY_PIN + 1, GpioPullUp);
Gpio_SetInputMode(KEY_PORT, KEY_PIN, GpioPullUp);
while (1) {
scan_key();
uint8_t i, j, k = 0;
for (i = 0; i < 4; i++) {
for (j = 0; j < 5; j++) {
if (key_status[i][j]) {
if (key_status[i][j] == 1) {
// short press
set_led(1);
delay(100);
set_led(0);
} else {
// long press
set_led(1);
delay(500);
set_led(0);
}
key_status[i][j] = 0;
}
if (key_map[i][j] == 'L') {
set_digit(1, k % 10);
set_digit(2, (k / 10) % 10);
set_digit(3, (k / 100) % 10);
k++;
}
}
}
}
}
```
该示例代码使用了9个GPIO口,其中4个用于行扫描,5个用于列扫描,另外还使用了3个GPIO口控制数码管显示和LED灯。在主循环中,通过`scan_key()`函数扫描键盘状态,并根据按键的短按和长按状态控制LED灯的闪烁。同时,在按下'L'键时,会在数码管上循环显示0-999的数字。注意,该示例代码中使用了HC32L13X的库函数,具体使用方法请参考HC32L13X的官方文档。
阅读全文