hc32l13x矩阵键盘4x5带数码管示例,每个按键控制一个led,ch455控制三个数码管
时间: 2023-11-19 20:09:54 浏览: 168
以下是一个简单的示例代码,使用hc32l13x控制4x5矩阵键盘和数码管:
```c
#include "hc32l13x.h"
#include "hc32l13x_clk.h"
#include "hc32l13x_gpio.h"
#include "hc32l13x_keyscan.h"
#include "hc32l13x_ch455.h"
#define LED_PORT GpioPortA
#define LED_PIN GpioPin0
#define DIGIT_PORT GpioPortB
#define DIGIT_PIN_1 GpioPin0
#define DIGIT_PIN_2 GpioPin1
#define DIGIT_PIN_3 GpioPin2
#define ROW_PORT GpioPortC
#define ROW_PIN_1 GpioPin0
#define ROW_PIN_2 GpioPin1
#define ROW_PIN_3 GpioPin2
#define ROW_PIN_4 GpioPin3
#define ROW_PIN_5 GpioPin4
#define COL_PORT GpioPortD
#define COL_PIN_1 GpioPin0
#define COL_PIN_2 GpioPin1
#define COL_PIN_3 GpioPin2
#define COL_PIN_4 GpioPin3
#define KEY_SCAN_INTERVAL (100U) // 按键扫描间隔时间,单位:毫秒
/* 数码管显示的数字 */
static uint8_t u8DigitNum[3] = {0};
/* 矩阵键盘对应的按键状态 */
static uint8_t u8KeyStatus[5][4] = {0};
/* 数码管扫描计数器,用于控制数码管的显示刷新率 */
static uint8_t u8DigitScanCnt = 0;
/* 数码管刷新函数 */
static void DIGIT_Display(void)
{
static uint8_t u8DigitIndex = 0;
/* 数码管切换 */
Gpio_WriteOutput(DIGIT_PORT, DIGIT_PIN_1 << u8DigitIndex, Enable);
Gpio_WriteOutput(DIGIT_PORT, DIGIT_PIN_1 << (u8DigitIndex + 1), Disable);
/* 数码管显示 */
CH455_WriteData(u8DigitNum[u8DigitIndex]);
/* 数码管索引递增 */
u8DigitIndex++;
if (u8DigitIndex >= 3U)
{
u8DigitIndex = 0;
}
}
/* 按键扫描函数 */
static void KEY_Scan(void)
{
static uint16_t u16KeyScanTimer = 0;
static uint8_t u8LastKeyStatus[5][4] = {0};
uint8_t i, j;
/* 判断是否到达按键扫描时间间隔 */
if (SysTick_GetReloadValue() - SysTick_GetCurValue() > KEY_SCAN_INTERVAL)
{
u16KeyScanTimer += KEY_SCAN_INTERVAL;
/* 扫描按键状态 */
for (i = 0; i < 5; i++)
{
/* 拉低对应行 */
Gpio_WriteOutput(ROW_PORT, ROW_PIN_1 << i, Disable);
for (j = 0; j < 4; j++)
{
/* 读取列状态 */
if (Gpio_ReadInput(COL_PORT, COL_PIN_1 << j) == Disable)
{
u8KeyStatus[i][j] = 1;
}
else
{
u8KeyStatus[i][j] = 0;
}
}
/* 恢复行状态 */
Gpio_WriteOutput(ROW_PORT, ROW_PIN_1 << i, Enable);
}
/* 判断按键是否有变化 */
for (i = 0; i < 5; i++)
{
for (j = 0; j < 4; j++)
{
if (u8KeyStatus[i][j] != u8LastKeyStatus[i][j])
{
if (u8KeyStatus[i][j] == 1)
{
/* 按键按下 */
Gpio_WriteOutput(LED_PORT, LED_PIN << ((i * 4) + j), Enable);
}
else
{
/* 按键松开 */
Gpio_WriteOutput(LED_PORT, LED_PIN << ((i * 4) + j), Disable);
}
}
}
}
/* 保存上一次的按键状态 */
for (i = 0; i < 5; i++)
{
for (j = 0; j < 4; j++)
{
u8LastKeyStatus[i][j] = u8KeyStatus[i][j];
}
}
/* 重置计时器 */
u16KeyScanTimer = 0;
}
}
int main(void)
{
/* 系统初始化 */
Clk_SetPeripheralGate(ClkPeripheralGpio, Enable);
Clk_SetPeripheralGate(ClkPeripheralKeyScan, Enable);
Clk_SetPeripheralGate(ClkPeripheralCH455, Enable);
Gpio_SetFunc(LED_PORT, LED_PIN, GpioDirOut);
Gpio_WriteOutput(LED_PORT, LED_PIN, Disable);
Gpio_SetFunc(DIGIT_PORT, DIGIT_PIN_1 | DIGIT_PIN_2 | DIGIT_PIN_3, GpioDirOut);
Gpio_WriteOutput(DIGIT_PORT, DIGIT_PIN_1 | DIGIT_PIN_2 | DIGIT_PIN_3, Enable);
Gpio_SetFunc(ROW_PORT, ROW_PIN_1 | ROW_PIN_2 | ROW_PIN_3 | ROW_PIN_4 | ROW_PIN_5, GpioDirOut);
Gpio_WriteOutput(ROW_PORT, ROW_PIN_1 | ROW_PIN_2 | ROW_PIN_3 | ROW_PIN_4 | ROW_PIN_5, Enable);
Gpio_SetFunc(COL_PORT, COL_PIN_1 | COL_PIN_2 | COL_PIN_3 | COL_PIN_4, GpioDirIn);
CH455_Init();
KeyScan_Init(KeyScanClkDiv1);
KeyScan_Enable();
SysTick_Init(1);
while (1)
{
/* 数码管刷新 */
u8DigitScanCnt++;
if (u8DigitScanCnt >= 50U)
{
u8DigitScanCnt = 0;
DIGIT_Display();
}
/* 按键扫描 */
KEY_Scan();
}
}
```
在这个例子中,我们使用hc32l13x的GPIO模块控制LED和矩阵键盘的输入输出,使用KeyScan模块扫描矩阵键盘状态,使用CH455模块控制数码管的显示。在主循环中,我们分别调用DIGIT_Display函数和KEY_Scan函数进行数码管刷新和按键扫描。需要注意的是,数码管的刷新率需要适当控制,以免占用过多的CPU资源。
阅读全文