登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[学习笔记] 电开开发板矩阵按键的扫描

[复制链接]
发表于 2021-1-24 22:56:55 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 单片机
学习安排: 单片机
开始时间: 2021-01-23
结束时间: 2021-01-24
本帖最后由 物电王铖浩 于 2021-1-24 23:03 编辑

关于电开开发板矩阵按键的扫描


好多天没有学过单片机了,今天想起来就学一下。

点阵是用的金沙滩开发板操作的,按键只看了视频,还没有上手操作,今天就来操作一下。

我主要用咱们电开的开发板上手操作,晶振是32.768mhz,单片机型号是stc12c5a60s2,

板子的布线等等和金沙滩的教程是不一样的,这样可以更好的锻炼自己看着原理图写程序。



但是打开原理图发现,矩阵需要的IO口和数码管有冲突,只能先硬着头皮把代码敲下来。

敲代码的时候想到P2这8个IO口同时用于扫描按键,和控制74H138来点亮数码管。

我可以让IO口主要用于显示数码管,进入中断扫描按键的时候把KeyIN这四个IO口电平拉高,

扫描完之后再回到原来的状态。



那么体现在代码上只需要增加一点内容即可。



代码如下;
#include <STC12C5A60S2.H>

sbit ENLED = P1^1;

sbit KOUT4 = P2^4;
sbit KOUT3 = P2^5;
sbit KOUT2 = P2^6;
sbit KOUT1 = P2^7;//这里我私自把KOUT1234改成改成4321了,至于为什么你们可以自己试试
//这里按照原理图本来应该把P2^0定义为P20的,但是头文件里面已经定义过了,所以就不再定义了,也不找其他标识符来定义了


unsigned char code DsChar[] =
        {0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
        0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};
//这里真值表多了一个0xFF

unsigned char KeySta[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char m = 16;


void main()
{
        unsigned char i,j;
        unsigned char backup[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};

        EA = 1;
        ENLED = 0;
        P22 = 0;
        P21 = 0;
        P20 = 0;
        AUXR = 0x80;   
        TMOD = 0x01;
        TH0 = 0x80;
        TL0 = 0x00;  //AUXR关闭单片机的12分频,定时1ms
        ET0 = 1;
        TR0 = 1;
        P0 = 0xFF;

        while(1)
        {
                for(i = 0;i<4;i++)
                {
                        for(j = 0;j<4;j++)
                        {
                                if(backup[j] != KeySta[j])
                                {
                                        if(backup[j] == 1)
                                        {
                                                m = i*4+j;
                                                P0 = DsChar[m];

                                        }
                                        backup[j] = KeySta[j];
                                }
                        }
                }
        }//while循环代码的核心思想就是挨个检测按键当前的状态是否和之前的状态一样,如果不一样就说明按键发生变化了,再检测按键之前的状态是按下还是弹起,
         //这里判断语句中backup[j] == 1,说明检测到之前按键状态是弹起就改变数码管的值。这里我们可以让backup[j] == 1,那就是按下按键,松手的时候数码管再改变
}


void InterruptTimer0() interrupt 1
{
        unsigned char i;
        static unsigned char keyout = 0;
        static unsigned char keybuf[4][4] =
        {
                {0xFF,0xFF,0xFF,0xFF},
                {0xFF,0xFF,0xFF,0xFF},
                {0xFF,0xFF,0xFF,0xFF},
                {0xFF,0xFF,0xFF,0xFF}
        };
        TH0 = 0x80;
        TL0 = 0x00;

        P0 = 0xFF;
        P20 = 1;
        P21 = 1;
        P22 = 1;
        //前面这4行就是增加的内容,先让P0=0xFF,防止改变138输入端后点亮对应的部分(其实也可以不加,因为咱们的板子138的输出端Y7什么也没接)
        //拉高P20,21,22的电平,准备读取按键


        keybuf[keyout][0] = (keybuf[keyout][0]<<1|P20);
        keybuf[keyout][1] = (keybuf[keyout][1]<<1|P21);
        keybuf[keyout][2] = (keybuf[keyout][2]<<1|P22);
        keybuf[keyout][3] = (keybuf[keyout][3]<<1|P23);//这四行是读取按键的瞬间状态

        P22 = 0;
        P21 = 0;
        P20 = 0;
        P0 = DsChar[m];
        //前面这4行也是增加的内容,把IO口的电平还原回来,并且再次点亮数码管

        for(i=0;i<4;i++)
        {
                if((keybuf[keyout]&0x0F) == 0x00)
                {
                        KeySta[keyout] = 0;
                }
                else if((keybuf[keyout]&0x0F) == 0x0F)
                {
                        KeySta[keyout] = 1;
                }
        }
        keyout++;
        keyout = keyout & 0x03;
        switch(keyout)
        {
                case 0:KOUT4 = 1;KOUT1 = 0;break;
                case 1:KOUT1 = 1;KOUT2 = 0;break;
                case 2:KOUT2 = 1;KOUT3 = 0;break;
          case 3:KOUT3 = 1;KOUT4 = 0;break;
        }
}

在我有了这个想法并且把代码敲出来的时候,编译的时候也是出现了一大堆错误。

改正之后下载到板子里面也是没有成功,找了很久才发现是因为中断函数之中的for循环的花括号括错了。



大家如果有什么更好的解决办法,也可以分享一下。

好懒~~不想说~~~
 楼主| 发表于 2021-1-24 23:01:04 | 显示全部楼层
本帖最后由 物电王铖浩 于 2021-1-24 23:05 编辑

代码模块会乱码
好懒~~不想说~~~
 楼主| 发表于 2021-1-24 23:01:37 | 显示全部楼层
本帖最后由 物电王铖浩 于 2021-1-24 23:05 编辑

改了一下没有使用代码模块  现在好了
好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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