`

51单片机学习笔记,4*4矩阵键盘

阅读更多

今天学习了下矩阵键盘,

4*4,  分别代表0~F这16个数字

我们按了哪个键就显示到数码管上

 

看完郭老师讲解原理后就自己动手写了,郁闷的是

在keil软件中,我在switch-case语句中 少了个冒号,竟然编译通过!

结果当然不正确了,然后我再keil中调试代码,那更郁闷了,P3口在扫描到第2行键盘时就

会复位成0xff,怎么赋值都没用,其实是没写冒号啊!

 

调了半天都不行,最后不得不将STC89C52RC换上仿真芯片SST89E516,在线调试后才发现的错误,

然后参考书上的代码才调试成功的,表示无语~~~

 

mark下

 

#include <reg52.h>
#include "MY51.H"

void showKey(uint8 num); //静态显示
void keyScan();
void main() 	
{	
    showKey(18); 	//初始显示的是6个负号
	while(1)
	{	//循环检测
        keyScan();
	}
}

void showKey(uint8 num)
{
	P0=0xc0;        //11000000 打开6个数码管
	wela=open;
	wela=lock;
	
	P0=table[num];
	dula=1;
	dula=0;
}
void keyScan()
{
    uint8 num=0;  	             //定义显示的数字
	uint8 temp=0; 	             //P3口回读信息
	uint8 i=0;                      //定义矩阵键盘行号索引	
    for(i=0; i<4;i++)           //共4行
    {
        P3=_crol_(0xfe,i);      //扫描的行索引号,从第0行到第3行
        temp=P3;                  //读取P3口
        temp=temp&0xf0;   		//提取高4位
        if(temp!=0xf0)          //按键了
        {
            delayms(5);          //消抖
            temp=P3;
            temp=temp&0xf0;
            if(temp!=0xf0)     //真的按键了
            {
                switch(temp)
                {
                    case  0xe0:         //1110 0000
                    {
                        num=0+4*i;
                        break;
                    }
                    case  0xd0:         //1101 0000
                    {
                        num=1+4*i;
                        break;
                    }
                    case  0xb0:         //1011 0000
                    {
                        num=2+4*i;
                        break;
                    }
                    case  0x70:         //0111 0000
                    {
                        num=3+4*i;
                        break;
                    }         
                    default:
                    {
                        num=18;         //18号索引是负号
                        led7=0;           // 按了不该按的指示灯
                        break;
                    }

                }
                while(1)    //松开按键检测
                {
                    temp=P3;               //读取P3口
                    temp=temp&0xf0;   //提取高4位
                    if(temp==0xf0)      //松开按键了
                    {
                        delayms(5);
                        temp=P3;
                        temp=temp&0xf0;
                        if(temp==0xf0)  //真的松开键盘了
                        {
                            break;
                        }
                    }
                }
                showKey(num); 	//静态显示按键
            }
        }
    }  	
}
void T0_Work()  //T0定时器调用的工作函数
{  

}


 

 

#ifndef _MY51_H_
#define _MY51_H_
#include <math.h>
#include <intrins.h>

typedef int   				int16  ;
typedef int   				INT16  ;
typedef unsigned int    uint16 ;
typedef unsigned int    UINT16 ;
typedef unsigned short  uint ;
typedef unsigned short  UINT ;
typedef unsigned short  word ;
typedef unsigned short  WORD ;
typedef unsigned long   uint32 ;
typedef unsigned long   UINT32 ;
typedef unsigned long   DWORD ;
typedef unsigned long   dword ;
typedef signed long	   int32	 ;
typedef signed long	   INT32  ;
typedef float		    	    float32	 ;
typedef double		    	double64  ;
typedef signed char		int8 ;
typedef signed char 		INT8 ;
typedef unsigned char	byte ;
typedef unsigned char    BYTE 	 ;		//WINDOWS的windef.h里面是这么定义的
typedef unsigned char	uchar ;
typedef unsigned char	UCHAR ;
typedef unsigned char	UINT8 ;
typedef unsigned char	uint8 ;
typedef unsigned char	BOOL	 ;		//windows中定义BOOL为int
typedef unsigned char	bool	 ;		    //bool是c++的内置类型

#define TRUE     1
#define true     1
#define FALSE    0
#define false    0

#define open     1    //open和close用于 标志打开和关闭状态
#define OPEN     1
#define close    0
#define CLOSE    0
#define lock     0
#define start    1
#define START    1
#define stop     0
#define STOP     0
#define keyDown  0
#define keyUp    1

sbit dula =P2^6;  //段选锁存器控制  控制笔段
sbit wela =P2^7;  //位选锁存器控制  控制位置

#define led P1    //灯总线控制
sbit led0=P1^0;   //8个led灯,阴极送低电平点亮
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;

sbit keyS2=P3^4; 	//4个独立按键
sbit keyS3=P3^5;
sbit keyS4=P3^6;
sbit keyS5=P3^7;

void displaySMG(uint8 one,uint8 two,uint8 three,uint8 four,uint8 five,uint8 six,uint8 dot); 
void delayms(uint16 ms);
void T0_Work();

void delayms(uint16 ms)  //软延时函数
{
	uint16 i,j;
	for(i=ms;i>0;i--)
	{
        for(j=113;j>0;j--)
        {}
	}
}
///////////////////////////////////////////////////////////////////////////
#define dark	0x11  //在段中,0x11是第17号元素,为0是低电平,数码管不亮
#define dotDark 0xff //小数点全暗时
uint8 code table[]= { 			//0~F外加小数点和空输出的数码管编码
 0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3
 0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7
 0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B
 0x39 , 0x5e , 0x79 , 0x71 , // C D E F
 0x80 , 0x00 ,0x40              // . 空  负号      空时是第0x11号也就是第17号元素
 };

/////////////////////////////////////////////////////////////////////////////
uint8   TH0Cout=0 ;	    //初值	
uint8   TL0Cout=0 ;	   
uint16  T0IntCout=0;     //中断计数
uint16  T0IntCountAll=0; //(N-1)/65536+1;  //总中断次数
bool    bT0Delay=false;  //使用延时函数标志,初始未用
bool    bT0Over=false; 	 //中断处理函数执行结果之一

void startT0(uint32 ms)  //开启定时器
{	
	float32   	t=ms/1000.0;		   		 //定时时间
	double64    fox =11.0592*(pow(10,6));   //晶振频率
	uint32    	N=(t*fox)/12 ; 				 //定时器总计数值

	TH0Cout =(65536-N%65536)/256;      	 //装入计时值零头计数初值
	TL0Cout =(65536-N%65536)%256;
	T0IntCountAll=(N-1)/65536+1;			 //总中断次数
	TMOD=TMOD | 0x01; 						 //设置定时器0的工作方式为1
	
	EA =open;   //打开总中断
	ET0=open;   //打开定时器中断

	TH0=TH0Cout;  //定时器装入初值
	TL0=TL0Cout;
	TR0=start;	 //启动定时器
}

void delayT0(uint32 ms)		//硬延时函数,自己乱写的不好用,求指点
{
	startT0(ms);				//启动定时器
	bT0Delay=true;    		//告诉T0定时器,起用延时模式
	while(bT0Over==false);	//时间没到的话继续检测
	bT0Over=false;				//时间到了,让标志复位
}

void T0_times() interrupt 1 //T0定时器中断函数
{
	T0IntCout++;
	if(T0IntCout==T0IntCountAll)  //达到总中断次数值
	{	
		T0IntCout=0; 		 //中断次数清零,重新计时
		bT0Over=true;     //时间真的到了
		if(bT0Delay)		//本次中断是用来延时的吗
		{
			TR0=stop; 		 //如果是由延时函数开启T0的话,关闭T0
			return;
		}

		TH0=TH0Cout;   		//循环定时的话要重装初值,每次定时1秒,重装一次
		TL0=TL0Cout;
		T0_Work();     		//工作函数
	}
}

////////////////////////////////////////////////////////////////////////////////
void displaySMG(uint8 oneWela,uint8 twoWela,uint8 threeWela,uint8 fourWela,uint8 fiveWela,uint8 sixWela,uint8 dot)
{		//控制6位数码管显示函数,不显示的位用参数 dark
		P0=0;
		dula=1;
		dula=0;	 //段选数据清空并锁定
//////////////////////////
		P0=0xff; //送位数据前关闭所有显示
		wela=1;
		P0=0xfe;
		wela=0;

		P0=0;  	//低电平输到数码管阳极,避免数码管吴亮
      dula=1;
		P0=table[oneWela]|((0x01&dot)?0x00:0x80);   //送段数据,使用小数点显示标志
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xfd;
		wela=0;

		P0=0;
		dula=1;
		P0=table[twoWela]|((0x02&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xfb;
		wela=0;
		P0=0;
		dula=1;
		P0=table[threeWela]|((0x04&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xf7;
		wela=0;

		P0=0;
		dula=1;
		P0=table[fourWela]|((0x08&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xef;
		wela=0;

		P0=0;
		dula=1;
		P0=table[fiveWela]|((0x10&dot)?0x00:0x80);
		dula=0;
		delayms(2);
/////////////////////////
		P0=0xff;
		wela=1;
		P0=0xdf;
		wela=0;

		P0=0;
		dula=1;
		P0=table[sixWela]|((0x20&dot)?0x00:0x80);
		dula=0;
		delayms(2);
}

#endif

 

 

14
18
分享到:
评论

相关推荐

    部门绩效考核评价表excel.xls

    部门绩效考核评价表excel

    全面的公司行政费用统计表.xls

    全面的公司行政费用统计表

    视觉跟踪算法综述.pdf

    视觉跟踪算法综述.pdf

    CMD 命令行高级教程精选合编

    CMD 命令行高级教程精选合编

    apr-devel-1.4.8-7.el7.x64-86.rpm.tar.gz

    1、文件内容:apr-devel-1.4.8-7.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/apr-devel-1.4.8-7.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装

    10-4-生产主管绩效考核表(自动计算、等级评价).xlsx

    10-4-生产主管绩效考核表(自动计算、等级评价)

    深度学习python基础(第三节) 函数、列表

    深度学习python基础(第三节) 函数、列表

    岗位绩效考核评定表excel表格模板.xlsx

    岗位绩效考核评定表excel表格模板

    成品库仓管员绩效考核表.xls

    成品库仓管员绩效考核表

    环卫业务 基础知识培训(小步创想)PPT(133页).pptx

    一、智慧环卫管理平台的建设背景与目标 智慧环卫管理平台的建设源于对环卫管理全面升级的需求。当前,城管局已拥有139辆配备车载GPS系统、摄像头和油耗传感器的环卫车辆,但环卫人员尚未配备智能移动终端,公厕也缺乏信息化系统和智能终端设备。为了提升环卫作业效率、实现精细化管理并节省开支,智慧环卫管理平台应运而生。该平台旨在通过信息化技术和软硬件设备,如车载智能终端和环卫手机App,实时了解环卫人员、车辆的工作状态、信息和历史记录,使环卫作业管理透明化、精细化。同时,平台还期望通过数据模型搭建和数据研读,实现更合理的环卫动态资源配置,为环卫工作的科学、健康、持续发展提供决策支持。 二、智慧环卫管理平台的建设内容与功能 智慧环卫管理平台的建设内容包括运行机制体制建设、业务流程设计、智慧公厕系统建设、网络建设、主机和储存平台需求、平台运维管理体系、硬件标准规范体系以及考核评价体系等多个方面。其中,智慧公厕系统建设尤为关键,它能实时监控公厕运行状态,保障公厕的清洁和正常运行。平台建设还充分利用了现有的电子政务网络资源,并考虑了有线和无线网络的需求。在功能上,平台通过普查、整合等手段全面收集环卫车辆、企业、人员、设施、设备等数据,建立智慧环卫基础数据库。利用智能传感、卫星定位等技术实现环卫作业的在线监管和远程监控,实现对道路、公共场所等的作业状况和卫生状况的全面监管。此外,平台还建立了环卫作业网格化管理责任机制,实现从作业过程到结果的全面监管,科学评价区域、部门、单位和人员的作业效果。 三、智慧环卫管理平台的效益与风险规避 智慧环卫管理平台的建设将带来显著的环境、经济和管理效益。环境方面,它将有力推进环境卫生监管服务工作,改善环境卫生状况,为人民群众创造更加清洁、卫生的工作和生活环境。经济方面,通过智慧化监管,大大降低了传统管理手段的成本,提高了监管的准确性和效率。管理方面,平台能够追踪溯源市民反映的问题,如公厕异味、渣土车辆抛洒等,并找到相应的责任单位进行处置,防止类似事件再次发生。同时,平台还拥有强大的预警机制功能,能够在很多环卫问题尚未出现前进行处置。然而,平台建设也面临一定的风险,如部门协调、配合问题,建设单位选择风险以及不可预测的自然灾害等。为了规避这些风险,需要加强领导、统一思想,选择优秀的系统集成商承接项目建设,并做好计算机和应用系统的培训工作。同时,也要注意标准制定工作和相关法律法规的制定工作,以保证系统建设完成后能够真正为环卫管理工作带来便利。

    基于平衡计分卡绩效考核表(管理高层)模板.xls

    基于平衡计分卡绩效考核表(管理高层)模板

    网站运营各部门绩效考核表.xls

    网站运营各部门绩效考核表

    XX公司行政部绩效考核指标.xls

    XX公司行政部绩效考核指标

    基于齿向修形的抛物线锥齿轮仿真分析.pdf

    基于齿向修形的抛物线锥齿轮仿真分析.pdf

    三相半桥逆变器低电压穿越控制策略设计:两级式光伏并网系统电路原理与容量优化报告,两级式光伏并网系统及其低电压穿越控制策略设计,容量30kW 三相半桥逆变器,boost电路作前级 带低电压穿越,有一

    三相半桥逆变器低电压穿越控制策略设计:两级式光伏并网系统电路原理与容量优化报告,两级式光伏并网系统及其低电压穿越控制策略设计,容量30kW。 三相半桥逆变器,boost电路作前级。 带低电压穿越,有一万七千字的报告,没有水文字。 报告内容,电路原理,pi参数设计,bode和根轨迹分析,波形良好 ,关键词:两级式光伏并网系统;低电压穿越控制策略;30kW容量;三相半桥逆变器;boost电路;前级设计;低电压穿越功能;报告内容;电路原理;PI参数设计;Bode和根轨迹分析;波形良好。,基于30kW容量两级式光伏并网系统的控制策略设计:低电压穿越及高效逆变技术研究

    毕业设计文本预测项目python源码+托尔斯泰《战争与和平》文本分析数据集-最新出炉.zip

    毕业设计文本预测项目python源码+托尔斯泰《战争与和平》文本分析数据集-最新出炉 关于数据集 背景: 该数据集包含列夫·托尔斯泰的《战争与和平》的全文,这是一部于 1869 年出版的开创性文学作品。作为公共领域文本,它为对文学分析、自然语言处理和历史研究感兴趣的研究人员和爱好者提供了丰富的资源。这部小说以俄国拿破仑战争为背景,探讨了战争、和平和人类状况的主题。 内容: 数据集由一个纯文本文件组成,其中包含《战争与和平》的完整叙述。文本已进行预处理,以方便分析和建模,使其适用于各种应用,包括文本挖掘、情感分析和机器学习项目。该文件可通过以下链接访问:战争与和平文本数据集。

    18 -广告部经理绩效考核表1.xlsx

    18 -广告部经理绩效考核表1

    永磁同步电机电流内环PR控制Simulink仿真模型:转速电流双闭环矢量控制,波形完美带原理说明与文献参考,永磁同步电机电流内环PR控制Matlab simulink仿真模型,参数已设置好,可直接运行

    永磁同步电机电流内环PR控制Simulink仿真模型:转速电流双闭环矢量控制,波形完美带原理说明与文献参考,永磁同步电机电流内环PR控制Matlab simulink仿真模型,参数已设置好,可直接运行。 属于PMSM转速电流双闭环矢量控制系统模型。 电流内环采用PR控制器,不需要旋转坐标变,在静止坐标下进行矢量控制,转速外环采用PI控制器。 波形完美,包含原理说明文档和参考文献。 ,关键词:永磁同步电机;电流内环PR控制;Matlab simulink仿真模型;PMSM转速电流双闭环矢量控制系统;PR控制器;PI控制器;波形完美;原理说明文档;参考文献。,"基于PR控制的永磁同步电机电流内环仿真模型:静止坐标矢量控制与波形解析"

    基于主从博弈理论的共享储能与综合能源微网优化运行策略研究:Stackelberg均衡下的优化调度与运行框架,基于主从博弈理论的共享储能与综合能源微网优化运行研究 关键词:主从博弈 共享储能 综合能源微

    基于主从博弈理论的共享储能与综合能源微网优化运行策略研究:Stackelberg均衡下的优化调度与运行框架,基于主从博弈理论的共享储能与综合能源微网优化运行研究 关键词:主从博弈 共享储能 综合能源微网 优化调度 参考文档:《基于主从博弈理论的共享储能与综合能源微网优化运行研究》完全复现 仿真平台:MATLAB yalmip+cplex 主要内容:代码主要做的是基于主从博弈理论的共享储能与综合能源微网优化运行研究,首先介绍了系统运行框架,分析了系统内各利益体的功能。 其次,分别针对微网运营商、共享储能服务商以及用户聚合商建立优化运行模型。 进一步,分析了微网运营商与用户聚合商间的博弈关系,提出共享储能背景下微网运营商与用户聚合商间的 Stackelberg 博弈模型,并证明Stackelberg 均衡解的存在性与唯一性。 最后,在 MATLAB平台上进行算例仿真,通过 Yalmip 工具与 CPLEX 求解器进行建模与求解,利用启发式算法与求解器相结合的方法优化微网运营商与用户聚合商的策略。 结果表明,本文所提模型所提模型不仅能有效权衡微网运营商与用户聚合商的利益,也实现了用户聚合商

Global site tag (gtag.js) - Google Analytics