STM32矩阵键盘与串口通信
实现目标:外接4x4矩阵键盘,按下键盘后串口返回按键值
键盘模块
键盘扫描函数
u16 KEY44_Scan()
{
H_1 = 0;
H_2 = 1;
H_3 = 1;
H_4 = 1;
if(L_1 == 0)
{
delay_ms(10);
if(L_1 == 0)
{
while(!L_1);
return 1;
}
}
if(L_2 == 0)
{
delay_ms(10);
if(L_2 == 0)
{
while(!L_2);
return 2;
}
}
if(L_3 == 0)
{
delay_ms(10);
if(L_3 == 0)
{
while(!L_3);
return 3;
}
}
if(L_4 == 0)
{
delay_ms(10);
if(L_4 == 0)
{
while(!L_4);
return 4;
}
}
H_1 = 1;
H_2 = 0;
H_3 = 1;
H_4 = 1;
if(L_1 == 0)
{
delay_ms(10);
if(L_1 == 0)
{
while(!L_1);
return 5;
}
}
if(L_2 == 0)
{
delay_ms(10);
if(L_2 == 0)
{
while(!L_2);
return 6;
}
}
if(L_3 == 0)
{
delay_ms(10);
if(L_3 == 0)
{
while(!L_3);
return 7;
}
}
if(L_4 == 0)
{
delay_ms(10);
if(L_4 == 0)
{
while(!L_4);
return 8;
}
}
H_1 = 1;
H_2 = 1;
H_3 = 0;
H_4 = 1;
if(L_1 == 0)
{
delay_ms(10);
if(L_1 == 0)
{
while(!L_1);
return 9;
}
}
if(L_2 == 0)
{
delay_ms(10);
if(L_2 == 0)
{
while(!L_2);
return 10;
}
}
if(L_3 == 0)
{
delay_ms(10);
if(L_3 == 0)
{
while(!L_3);
return 11;
}
}
if(L_4 == 0)
{
delay_ms(10);
if(L_4 == 0)
{
while(!L_4);
return 12;
}
}
H_1 = 1;
H_2 = 1;
H_3 = 1;
H_4 = 0;
if(L_1 == 0)
{
delay_ms(10);
if(L_1 == 0)
{
while(!L_1);
return 13;
}
}
if(L_2 == 0)
{
delay_ms(10);
if(L_2 == 0)
{
while(!L_2);
return 14;
}
}
if(L_3 == 0)
{
delay_ms(10);
if(L_3 == 0)
{
while(!L_3);
return 15;
}
}
if(L_4 == 0)
{
delay_ms(10);
if(L_4 == 0)
{
while(!L_4);
return 16;
}
}
return 0;
}
键盘引脚配置
void KEY44_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
键盘模块.h文件
#include "sys.h"
#ifndef __KEYSCAN_H
#define __KEYSCAN_H
#define H_1 PAout(0)
#define H_2 PAout(1)
#define H_3 PAout(2)
#define H_4 PAout(3)
#define L_1 PAin(4)
#define L_2 PAin(5)
#define L_3 PAin(6)
#define L_4 PAin(7)
void KEY44_Init(void);
u16 KEY44_Scan(void);
#endif
串口模块
STM32串口简介
串口设置的一般步骤可以总结为如下几个步骤:
- 串口时钟使能,GPIO 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);//串口使能
- 串口复位
void USART_DeInit(USART_TypeDef* USARTx);//串口复位
- GPIO 端口模式设置
- 串口参数初始化
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
- 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
- 使能串口
- 编写中断处理函数
以串口1为例
串口1的初始化函数
void uart_init(u32 bound){
//GPIO¶Ë¿ÚÉèÖÃ
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ʹÄÜUSART1£¬GPIOAʱÖÓ
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍìÊä³ö
GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.9
//USART1_RX GPIOA.10³õʼ»¯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë
GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.10
//Usart1 NVIC ÅäÖÃ
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //×ÓÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ
NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷
//USART ³õʼ»¯ÉèÖÃ
USART_InitStructure.USART_BaudRate = bound;//´®¿Ú²¨ÌØÂÊ
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ
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); //³õʼ»¯´®¿Ú1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆô´®¿Ú½ÓÊÜÖжÏ
USART_Cmd(USART1, ENABLE); //ʹÄÜ´®¿Ú1
}
串口1中断服务程序
void USART1_IRQHandler(void) //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
u8 Res;
#if SYSTEM_SUPPORT_OS //Èç¹ûSYSTEM_SUPPORT_OSÎªÕæ£¬ÔòÐèÒªÖ§³ÖOS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ)
{
Res =USART_ReceiveData(USART1); //¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý
if((USART_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É
{
if(USART_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//½ÓÊÕ´íÎó,ÖØÐ¿ªÊ¼
else USART_RX_STA|=0x8000; //½ÓÊÕÍê³ÉÁË
}
else //»¹Ã»ÊÕµ½0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØÐ¿ªÊ¼½ÓÊÕ
}
}
}
}
#if SYSTEM_SUPPORT_OS //Èç¹ûSYSTEM_SUPPORT_OSÎªÕæ£¬ÔòÐèÒªÖ§³ÖOS.
OSIntExit();
#endif
}
#endif
主函数
u16 keyvalue;
int main(void)
{
KEY44_Init(); //键盘初始化
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //
uart_init(115200); //´设置比特率为115200
while(1)
{
// printf("begin");
delay_ms(100);
keyvalue = KEY44_Scan();
if(keyvalue != 0)
{
printf("KEY NUM IS %d\r\n",keyvalue);
}
}
}