登录  | 立即注册

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

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[学习笔记] 按键扫描

[复制链接]
发表于 2018-2-20 19:31:56 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 单片机
学习安排: 按键扫描
开始时间: 2018-02-21
结束时间:
单片机最小系统(补)
1. 电源
    常用的单片机电源系统有5V和3.3V
    常用的数字电路系统电源类别分别有
    24V 12V 5V 3.3V 2.5V 1.8V
2. 晶振
    有源晶振  需要电压
    无源晶振
3. 复位电路
单片机在给 RST 引脚高电平信号时,单片机发生复位
    上电复位
        上电的时候电容会进行充电,由于下拉电阻,给rst引脚一个高电平信号,从而进行复位
    复位时间计算 t=1.2RC
        单片机有要求上电复位的最低时间,也就是高电平信号的最低时间
    手动复位
        手动复位时,时间一般比较长,满足复位的最低时间

bit型变量,大小就是1位,只有在51单片机中可以使用

按键
按键按下时I/O口处于低电平没按下时处于高电平,
单片机可以通过判断高低电平间接判断按键是否按下
(单片机如果要读取按键信息,那么内部输出就需要时高电平)

我把按键扫描的程序分成了三个子程序
#include<stc12c5a60s2.h>
#include"timer.h"
#include"cType.h"

uint8 ledchar[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uint8 keysta[4][4]={//按键状态值
                                  {1,1,1,1,},
                                  {1,1,1,1,},
                                  {1,1,1,1,},
                                  {1,1,1,1,}};

void main()
{
    uint8 i,j;
        uint8 backup[4][4]={
        {1,1,1,1,},{1,1,1,1,},{1,1,1,1,},{1,1,1,1,},//档寸值,用来判断按键是否按下
                };
        uint8 ledchar[]=
        {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
        P11=0;
        P0=ledchar[0];
        timer();

        while(1){
                for(i=0;i<4;i++)
                {
                        for(j=0;j<4;j++)//遍历矩阵按键
                        {
                                if(keysta[i][j]!=backup[i][j])
                                {
                                        if(backup[i][j]==0){
                                                P0=ledchar[i*4+j];
                                        }
                                        backup[i][j]=keysta[i][j];
                                }
                        }
                }
        }
}

#include"key.h"

extern uint8 keysta[4][4];
void keyscan(void){
        static uint8 keyout=0;
        uint8 i=0;
        static uint8 keybuf[4][4]={
                {0xff,0xff,0xff,0xff,},
                {0xff,0xff,0xff,0xff,},
                {0xff,0xff,0xff,0xff,},
                {0xff,0xff,0xff,0xff,},
        } ;
        P21 = 1;
        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;
       
        for(i=0;i<4;i++){
                if((keybuf[keyout][i]&0x0f)==0x0f){
                        keysta[keyout][i]=1;
                }else if((keybuf[keyout][i]&0x0f)==0x00){
                        keysta[keyout][i]=0;
                }
        }
        keyout++;
        keyout&=0x03;
        switch(keyout){
                case 02=0x7d;break;
                case 12=0xbd;break;
                case 22=0xdd;break;
                case 32=0xed;break;

                default: break;
        }
}

#include "timer.h"
#include "key.h"

void timer(void){
        AUXR |= 0x80;                //定时器时钟1T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0x00;                //设置定时初值
        TH0 = 0x83;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        EA=1;
        ET0=1;
}
void interruptT0() interrupt 1
{
        TL0 = 0x00;                //设置定时初值
        TH0 = 0x83;                //设置定时初值
        keyscan();
}

#ifndef __cType_h_
#define __cType_h_

typedef unsigned char uint8;
typedef unsigned int  uint32;
typedef unsigned long uint64;

typedef signed char int8;
typedef signed int  int32;
typedef signed long int64;

#endif


#ifndef __key_h_
#define __key_h_

#include<stc12c5a60s2.h>
#include"cType.h"

void keyscan(void);

#endif


#ifndef __timer_h_
#define        __timer_h_

#include <stc12c5a60s2.h>
void timer(void);

#endif
上面分别是子程序以及头文件,由于还手生,于是就不直接用社团写好的了,多写几遍以后慢慢就熟了

好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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