蓝桥杯之单片机设计与开发(4)——矩阵按键

本文深入讲解了矩阵按键的扫描原理及程序实现,介绍了如何通过快速中断循环判断按键状态,实现按键的准确检测与消抖处理。同时,提供了具体的C语言代码示例,包括按键状态的读取、比较与更新过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

矩阵按键

在我的印象中,从我学单片机开始,就很少写矩阵按键的程序,但是原理差不多都清楚,不过在这里不仅要考虑程序的执行,而且需考虑程序的完整与完善。

一针见血,看原理图

将开发板上面的J5跳线帽接到KBD端,也就是J5的1和2相接。

这里注意:在开发板上,根据转接板原理图,WR端接到单片机的P42管脚,RD端接到单片机的P44管脚。

我们知道,按键按下通常会保持100ms以上,如果在按键扫描中断中,每次让矩阵按键的一个KeyOut输出低电平其他三个输出高电平,判断当前所有Keyln的状态,下次中断时再让下一个KeyOut输出低电平,其他三个输出高电平.再次判断所有KeyIn,通过快速的中断不停地循环进行判断,就可以最终确定哪个按键按下了。

这个原理是不是跟数码管动态扫描有点类似?数码管在动态赋值,而按键在动态读取状态。至于扫描间隔时间和消抖时间,因为现在有4个KeyOut输出,要中断4次才能完成一次全部按键的扫描,显然2ms中断时间较长,这里我们使用1ms。

//main.c

#define u16 unsigned int
#define u8 unsigned char

u8 Led_flag = 0;
u8 Led_dat;				//led显示状态
u8 KeySta[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};			//当前按键状态
u8 Key_backup[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};	//按键状态备份,保存前一次的按键值

void main(void)
{
	u8 i,j;
	All_Init();
	Time0_Init();
	Led_dat = 0xfe;
	while(1)
	{
		for(i = 0;i < 4;i ++)					//循环检测4×4的矩阵按键
		{	
			for(j = 0;j < 4;j ++)
			{
				if(Key_backup[i][j] != KeySta[i][j])	    //检测按键当前动作
				{
					if(Key_backup[i][j] != 0)    	    //按键按下时执行动作
					
					Key_backup[i][j] = KeySta[i][j];    //更新前一次的备份值
				}
			}
		}
	}
}
//key.c

//按键扫描
void Key_Scan(void)
{
	u8 i;
	static u8 keyout = 0;		//矩阵按键扫描输出索引
	static u8 keybuff[4][4] = {{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};	//矩阵按键扫描缓存区
	
	keybuff[keyout][0] = (keybuff[keyout][0] << 1) | KEY_IN_1;		//将每一行的4个按键值移入缓存区
	keybuff[keyout][1] = (keybuff[keyout][1] << 1) | KEY_IN_2;
	keybuff[keyout][2] = (keybuff[keyout][2] << 1) | KEY_IN_3;
	keybuff[keyout][3] = (keybuff[keyout][3] << 1) | KEY_IN_4;
		
	//消抖后更新按键状态
	for(i = 0;i < 4;i ++)
	{
		if((keybuff[keyout][i] & 0x0f) == 0x00)
			KeySta[keyout][i] = 0;		//连续4次扫描值都是0,即4×4s内都是按下状态,认为按键已平稳按下
		else if((keybuff[keyout][i] & 0x0f) == 0x0f)
			KeySta[keyout][i] = 1;		//连续4次扫描值都是1,即4×4s内都是松开状态,认为按键已稳定弹起
	}
	
	//执行下一次的扫描输出
	keyout ++;
	keyout = keyout & 0x03;		//索引加到4就归零
	switch(keyout)						//根据索引,释放当前输出引脚,拉低下次的输出引脚
	{
		case 0:KEY_OUT_4 = 1;KEY_OUT_1 = 0;break;
		case 1:KEY_OUT_1 = 1;KEY_OUT_2 = 0;break;
		case 2:KEY_OUT_2 = 1;KEY_OUT_3 = 0;break;
		case 3:KEY_OUT_3 = 1;KEY_OUT_4 = 0;break;
		default:break;
	}
}

 

 

 

 

 

 

<think>好的,用户的问题是询问MSPM0G3507的串口跳线帽硬件连接和配置方法。我需要先查看提供的引用资料,看看是否有相关信息。 首先,引用[1]提到MSP430 LaunchPad的外设资源有限,有跳线帽,但这是MSP430的,可能不适用于MSPM0G3507。不过用户可能混淆了这两个系列,但需要确认。 引用[3]提到USB转TTL模块的跳线帽连接,指出红色是共地,蓝色是共5V,并且需要连接PB10和PB11的左边引脚。这可能用户的问题相关,因为MSPM0G3507可能使用类似的GPIO引脚进行串口通信。 引用[4]中提到,如果通信不正常,需要检查跳线帽是否接到靠上的两个引脚,根据原理图。这可能指的是UART的跳线位置,确保正确连接RX和TX。 用户可能需要知道如何正确设置跳线帽的位置,以连接MSPM0G3507的串口到外部设备,比如USB转TTL模块。根据引用[3]和[4],跳线帽的正确位置可能是关键,需要连接到特定的引脚(如PB10/PB11),并确保电源和地线正确。 另外,引用[4]中的代码示例使用了UART的中断处理,这可能涉及到硬件配置中的跳线设置,以确保数据能正确收发。需要指导用户检查硬件连接,特别是跳线帽的位置是否在正确的引脚上,以及是否共地和电源正确。 总结来说,用户需要关于MSPM0G3507的UART跳线帽连接步骤,包括跳线位置、引脚对应关系以及配置验证方法。需要结合引用中的信息,特别是引用[3]和[4],给出具体的步骤,并提醒可能的常见错误,如跳线帽位置错误或电压不匹配。</think>根据引用资料[3][4]中关于MSPM0G系列串口跳线帽的硬件配置信息,整理配置方法如下: ### 一、硬件连接步骤 1. **跳线帽定位** - 找到开发板上的UART通信专用跳线排针组(通常标记为UART或USART) - 根据原理图要求,**跳线帽必须连接靠上的两个引脚**才能建立有效通信通道[^4] 2. **引脚对应关系** | 功能 | MSPM0G3507引脚 | 外部模块引脚 | |---|---|----| | TXD | PB11 (发送端) | 目标设备RXD | | RXD | PB10 (接收端) | 目标设备TXD | | GND | 板载GND排针 | 外部模块GND | *注意:必须使用杜邦线连接左侧引脚组(靠近MCU的一侧)[^3]* 3. **电压匹配检查** - 确认外部模块工作电压MSPM0G3507匹配(3.3V逻辑电平) - 若使用5V模块,必须断开红色跳线帽并外接电平转换电路[^1] ### 二、配置验证方法 1. **物理层检测** ```c // 通过GPIO状态检测连接 DL_GPIO_setInput(GPIO_PORT_B, GPIO_PIN_10); // 配置RXD为输入 DL_GPIO_setOutput(GPIO_PORT_B, GPIO_PIN_11); // 配置TXD为输出 ``` 用万用表测量PB11引脚,发送数据时应有电平跳变 2. **软件环回测试** 参考引用[2]的uart_external_loopback_interrupt例程,短接PB10和PB11后: ```c DL_UART_Main_transmitData(UART_0_INST, 0x55); // 发送测试数据 if(gEchoData == 0x55) { /* 环回成功 */ } // 验证接收数据 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值