F103矩阵键盘并串口打印
时间: 2023-06-26 22:04:43 浏览: 71
以下是使用F103单片机控制矩阵键盘并通过串口打印键值的示例代码:
```c
#include "stm32f10x.h"
#include "stdio.h"
#define ROWS 4
#define COLS 4
char keymap[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
GPIO_InitTypeDef GPIO_InitStructure;
void init_keyboard(void);
char get_key(void);
void init_usart(void);
void usart_send_char(char ch);
int main()
{
SystemInit();
init_keyboard();
init_usart();
char key;
while(1)
{
key = get_key();
if(key != '\0')
{
printf("%c\n", key);
}
}
}
void init_keyboard(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
char get_key(void)
{
int row, col;
char key = '\0';
for(row = 0; row < ROWS; row++)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_RESET);
GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_RESET);
GPIO_WriteBit(GPIOB, GPIO_Pin_3, Bit_RESET);
GPIO_WriteBit(GPIOB, GPIO_Pin_0 + row, Bit_SET);
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET)
{
col = 0;
key = keymap[row][col];
break;
}
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == Bit_RESET)
{
col = 1;
key = keymap[row][col];
break;
}
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == Bit_RESET)
{
col = 2;
key = keymap[row][col];
break;
}
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) == Bit_RESET)
{
col = 3;
key = keymap[row][col];
break;
}
}
return key;
}
void init_usart(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// Configure USART1 Tx (PA.9) as alternate function push-pull
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure USART1 Rx (PA.10) as input floating
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USART1 configuration
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
// Enable USART1
USART_Cmd(USART1, ENABLE);
}
void usart_send_char(char ch)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, ch);
}
```
在该示例代码中,我们首先定义了一个4x4的键值矩阵,并通过变量`keymap`来表示键值。然后在`init_keyboard`函数中,我们初始化了4个行引脚(GPIOB0-B3)和4个列引脚(GPIOA0-A3),其中行引脚设置为输出模式,列引脚设置为输入模式。在`get_key`函数中,我们轮询每一个行引脚,将其置为高电平,然后依次读取每一个列引脚的状态,如果有列引脚被按下,则通过`keymap`数组来返回相应的键值。
在主函数中,我们不断轮询键盘,并使用串口输出键值。为了输出键值,我们还需要初始化串口,并定义一个`usart_send_char`函数来发送字符。在`usart_send_char`函数中,我们首先等待USART1的数据寄存器空位标志位被置位,然后将待发送字符通过USART1发送出去即可。
要编译和下载该程序,你需要使用Keil MDK或者其他类似的IDE,并将该代码保存为`main.c`文件。然后将F103单片机与电脑连接,并使用ST-Link或者其他支持SWD协议的调试器进行下载和调试。如果一切顺利,你应该能够在串口工具中看到按键对应的字符被打印出来。