找回密码
 立即注册
搜索
热搜: 中医 针灸 咳嗽
查看: 214|回复: 0

矩阵键盘的扫描

[复制链接]

3711

主题

1

回帖

1万

积分

管理员

积分
11937
发表于 2023-3-14 15:18:04 | 显示全部楼层 |阅读模式
sys.h


[C] 纯文本查看 复制代码
//--------------------------------------------------------------
/*本代码严格遵循微软代码风格约定
//---------------------------------------------------------------
代码风格约定:
局部变量:   小写可(加下划线)
    float sum = 0.0f;
    float sum_count = 0;


全局变量:  g_开头加小驼峰(可加下划线)
    int g_maxStudents = 100;
    float g_averageScore = 0.0f;


函数:    大驼峰(可加下划线)
int CalculateSum(int x, int y);
int Calculate_Sum(int x, int y);


宏定义:  全大写
#define PI 3.14159265358979323846

*/
//----------------------------------------------------------------
/*程序说明:

降龙棍~矩阵键盘按键响应数码管,显示每个键值
*引脚说明:
P46(30) 行S6,7,8,9
P47(31) 行S10,11,12,13
P32 行S14,15,16,17
P33 行S18,19,20,21

P34 列S6,10,14,18
P35 列S7,S11,15,19
P36 列S8,12,16,20
P37 列S9,13,17,21

数码管位:P27
数码管段:P26


~74HC573,4位数码管接线在P0口,数码管采用共阴极

同步89开发板的时钟,这里为了与89开发板同步做实验统一用11.0592晶振
*/

#ifndef __SYS_H_
#define __SYS_H_
#include <STC32G.H>

/*定义无符号整数类型*/ #define ULONG unsigned long
/*定义数码管端口*/ #define B8LED P0
/*定义矩阵键盘端口*/ #define KEYPORT P3

unsigned char code g_duan_Data[] = {
    0x3F, //"0"
    0x06, //"1"
    0x5B, //"2"
    0x4F, //"3"
    0x66, //"4"
    0x6D, //"5"
    0x7D, //"6"
    0x07, //"7"
    0x7F, //"8"
    0x6F, //"9"
    0x77, //"A"
    0x7C, //"B"
    0x39, //"C"
    0x5E, //"D"
    0x79, //"E"
    0x71, //"F"
    0x76, //"H"
    0x38, //"L"
    0x37, //"n"
    0x3E, //"u"
    0x73, //"P"
    0x5C, //"o"
    0x40, //"-"
    0x00, // 熄灭
    0x00  // 自定义

};
/*数码管位表*/
unsigned char code g_wei_Data[] = {
    0xfe, // 1111 1110  b
    0xfd, // 1111 1101  b
    0xfb, // 1111 1011  b
    0xf7, // 1111 0111  b
    0xef, // 1110 1111  b
    0xdf, // 1101 1111  b
    0xbf, // 1011 1111  b
    0x7f  // 0111 1111  b
};
/*数据存储*/ ULONG g_num = 0;

/*段引脚*/ sbit g_duan = P2 ^ 6;
/*位引脚*/ sbit g_wei = P2 ^ 7;

/*矩阵键盘引脚定义*/
// 编程框架函数声明

void Sys_Init();
void Sys_Draw();
void User_Updata();
void Sys_Updata();

// 用户函数声明

void Dis_Show(char wei_flag, char val);
void Dis_Scan(ULONG val);
void Keys_Scan();
void Delay5ms();
char Get_Row();
char Get_Col();




#endif



main.c
[C] 纯文本查看 复制代码
#include "sys.h"

void main()

{

    // 采用框架式编程
    //  1.定义数据
    //  2.系统初始化数据
    Sys_Init(); // 初始化
    while (1)
    {
        // 3.系统数据绘制
        Sys_Draw();
        // ----------------------------------------4.数据更新
        // 4.1用户干预更新数据
        User_Updata();
        // 4.2 系统自动更新数据
        Sys_Updata();
    }
}
// 系统式编程框架-----------------------------------------------
/*初始化函数*/
void Sys_Init()
{
    // 准双向IO口定义
    P2M0 = 0x00;
    P2M1 = 0x00; // P2口设置为准双向IO口,74H芯片
    P0M0 = 0x00;
    P0M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    // 初始化
    P2 = 0xff; // 设置为高电平
    P3 = 0Xff;
    P4 = 0Xff;
    P0 = 0x00;
    WTST = 0X00; // 延时等待控制器
}
/*绘制处理数据*/
void Sys_Draw()

{
    Dis_Scan(g_num);
}

/*用户干预更新数据*/
void User_Updata()
{

    Keys_Scan();
}
/*系统更新数据*/
void Sys_Updata()
{
}
// 下面数用户函数实现区域-----------------------------------

/*键盘扫描*/
void Keys_Scan()
{
    int x, y;                   // 矩阵键盘的X和Y 轴
    unsigned char temp_row = 0; // 行数据
    unsigned char temp_col = 0; // 列数据
    int key_tables[4][4]={//这是一个矩阵键盘对应的键值表
        0,1,2,3,
        4,5,6,7,
        8,9,10,11,
        12,13,14,15
    };

    temp_row = (unsigned char)Get_Row(); // 扫描行
    temp_col = (unsigned char)Get_Col(); // 扫描列
    if (temp_row != 99)//如果返回99说明按键并未被按下
    {
        switch (temp_row)//对获得的值取x坐标
        {
        case 0X07:
            x = 0;
            break;
        case 0X0B:
            x = 1;
            break;
        case 0X0D:
            x = 2;
            break;
        case 0X0E:
            x = 3;
            break;
        default:
            break;
        }
    }
    if (temp_col != 99)//对获得的值取y坐标
    {
        switch (temp_col)
        {
        case 0XE0:
            y = 0;
            break;
        case 0XD0:
            y = 1;
            break;
        case 0XB0:
            y = 2;
            break;
        case 0X70:
            y = 3;
            break;

        default:
            break;
        }
    }

    if(temp_row!=99 &&temp_row!=99)//如果确定按键已经被按下,
    g_num =key_tables[x][y] ;//给全局变量赋值
}

/*数码管单位显示
 *参数1:wei_flag: 显示在哪一位上
 *参数2:val: 需要显示的值
 */
void Dis_Show(char wei_flag, char val)
{
    B8LED = 0;                    // 清除段码
    g_wei = 1;                    // 打开位锁存器
    B8LED = g_wei_Data[wei_flag]; // 选择数码管位
    g_wei = 0;                    // 关闭位锁存器
    B8LED = 0;                    // 清除段码
    g_duan = 1;                   // 打开段锁存器
    B8LED = g_duan_Data[val];     // 显示段数据
    g_duan = 0;                   // 关闭段锁存器
}
/*数码管动态扫描
 *参数1:val需要显示的数据
 */
void Dis_Scan(ULONG val)
{
    char val_arr[8]; // 储存每个位置的数组
    char count = 0;  // 初始化遍历记录变量为0

    if (val == 0)
    {                   // 如果传入的值为0
        Delay5ms();     // 消除鬼影
        Dis_Show(7, 0); // 直接输出数码管显示结果为0
    }
    else
    {
        while (val != 0)
        {
            val_arr[count] = val % 10;
            val /= 10;
            count++;
            Delay5ms(); // 消除鬼影
            Dis_Show((char)(8 - count), val_arr[count - 1]);
        }
    }
}
/*返回矩阵键盘按下行码*/
char Get_Row()
{
    P46 = 1;
    P47 = 1;
    P3 = 0X0f;
    P30 = P46; // P30 位置在降龙棍上被阉割,被替换为P46
    P31 = P47; // P31 位置在降龙棍上被阉割,被替换为P47

    if (P3 != 0x0f) // 行扫描
    {
        return P3;
    }
    return 99;//说明按键未被按下
}
/*返回矩阵键盘按下列码*/
char Get_Col()
{
    P3 = 0Xf0;
    P46 = 0;
    P47 = 0;
    P30 = P46; // P30 位置在降龙棍上被阉割,被替换为P46
    P31 = P47; // P31 位置在降龙棍上被阉割,被替换为P47

    if (P3 != 0xf0) // 行扫描
    {
        return P3;
    }
    return 99;//说明按键未被按下
}
void Delay5ms() //@11.0592MHz
{
    volatile unsigned long i;

    _nop_();
    _nop_();
    _nop_();
    i = 13822UL;
    while (i)
        i--;
}




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|私人站点 ( 冀ICP备2023028127号-2 )

GMT+8, 2025-7-4 10:10 , Processed in 0.086702 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表