N°004 2024-05-20 10:07 采纳率: 0%
浏览 7
已结题

51单片机 矩阵键盘 问题求解(语言-c语言)

跟着江科大的51教程走,学到矩阵键盘这一章,按自己的理解写下了这段代码,想问问大家这段代码逻辑上有什么问题啊,一直没有办法输出键码值,调了好久, 大哭

img

#include <REGX52.H>
#include "delay.h"
unsigned char keydata[4][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12},
    {13, 14, 15, 16}
};

unsigned char i, keypads_value;
unsigned char keypads()
{
    P1 = 0x7F;
    for(i = 0; i < 4; i++)
    {     
        P1 = ~((~P1) >> i);
        
        if (P1_3 == 0)
        {
            Delay1ms(20);
            keypads_value = keydata[i][0];
            while(P1_3 == 0);
            Delay1ms(20);
        }
        if (P1_2 == 0)
        {
            Delay1ms(20);
            keypads_value = keydata[i][1];
            while(P1_2 == 0);
            Delay1ms(20);
        }
        if (P1_1 == 0)
        {
            Delay1ms(20);
            keypads_value = keydata[i][2];
            while(P1_1 == 0);
            Delay1ms(20);
        }
        if (P1_0 == 0)
        {
            Delay1ms(20);
            keypads_value = keydata[i][3];
            while(P1_0 == 0);
            Delay1ms(20);
        }
        
        
    }
    return keypads_value;
}

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-05-20 10:07
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    【您想要解决的问题】:您想要解决的问题是如何在51单片机上实现矩阵键盘的键码值检测,因为您编写的代码一直无法正确输出键码值。

    【问题出现原因】:

    1. 您的代码中对P1端口的操作逻辑存在问题。您尝试通过右移P1端口的值来逐行扫描键盘,但P1端口的位操作可能不正确。
    2. 判断按键是否被按下的条件可能不正确,您使用了P1_3 == 0P1_2 == 0等表达式,这可能不是正确的方式去检测单个引脚的状态。
    3. 您的代码中没有对键盘的列线进行操作,矩阵键盘通常需要对行线和列线进行操作以检测按键。
    4. Delay1ms(20);可能不足以稳定检测按键状态,需要根据实际情况调整延时。

    【问题解决方案】:

    1. 需要使用正确的方法来操作P1端口,通常需要设置行线为低电平,读取列线的状态。
    2. 需要添加对列线的控制逻辑,以便能够检测到哪一列被激活。
    3. 需要确保延时足够长,以稳定读取按键状态。
    4. 需要添加消抖逻辑,以避免误触发。

    【提供代码】: 以下是修改后的代码示例,它展示了如何使用行和列扫描来检测矩阵键盘的按键:

    #include <REGX52.H>
    #include "delay.h"
    
    #define ROW P1  // 定义行端口
    #define COL P3  // 定义列端口,假设列线连接到P3
    
    unsigned char keydata[4][4] = {
    	{1, 2, 3, 4},
    	{5, 6, 7, 8},
    	{9, 10, 11, 12},
    	{13, 14, 15, 16}
    };
    
    unsigned char keypads()
    {
    	unsigned char i, j, keypads_value = 0;
    
    	// 扫描行
    	for(i = 0; i < 4; i++)
    	{
    		ROW = ~(1 << i);  // 设置当前行为低电平,其他行为高电平
    		for(j = 0; j < 4; j++)
    		{
    			if(COL & (0x10 << j))  // 检查列线是否被拉低
    			{
    				Delay1ms(20);  // 消抖延时
    				if(COL & (0x10 << j))  // 再次检查确认
    				{
    					keypads_value = keydata[i][j];
    					break;
    				}
    			}
    		}
    		if(keypads_value) break;  // 如果找到按键,跳出循环
    	}
    
    	// 恢复端口状态
    	ROW = 0xFF;
    	COL = 0xFF;
    	return keypads_value;
    }
    

    【代码运行方式】:

    • 需要在支持51单片机的编译环境中编译此代码。
    • 将编译后的机器码烧录到51单片机中。
    • 连接矩阵键盘到单片机的相应端口。
    • 运行程序,按下键盘时应该能够看到对应的键码值。

    【代码预期运行结果】:

    如果按下键盘上的某个键,比如“1”,那么程序应该输出键码值1。
    

    【推荐相关链接】:

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月21日
  • 修改了问题 5月20日
  • 创建了问题 5月20日

悬赏问题

  • ¥15 odoo17处理受托加工产品
  • ¥15 如何用MATLAB编码图三的积分
  • ¥15 为什么我安装了Homebrew之后,无法像官网的那样通过执行命令安装Watchman
  • ¥15 圆孔衍射光强随孔径变化
  • ¥15 MacBook pro m3max上用vscode运行c语言没有反应
  • ¥15 ESP-PROG配置错误,ALL ONES
  • ¥15 结构功能耦合指标计算
  • ¥50 AI大模型精调(百度千帆、飞浆)
  • ¥15 非科班怎么跑代码?如何导数据和调参
  • ¥15 福州市的全人群死因监测点死亡原因报表