`

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
分享到:
评论

相关推荐

    单片机学习笔记ourdev_530143.pdf

    ### 单片机学习笔记ourdev_530143.pdf知识点总结 #### 一、开发板配件 - **HJ-1G开发板主机**:作为学习平台的核心部分,该开发板集成了多种功能模块,适用于初学者进行单片机的学习与实践。 - **STC单片机**:已...

    HJ2GAVR单片机学习笔记1概述.pdf

    HJ-2G AVR单片机学习笔记主要介绍了开发板的介绍、核心处理器ATMEGA16、锁存器、数码管、矩阵键盘、液晶1602接口、串口接口MAX232、DS1302时钟电路等内容,为学习单片机的开发者提供了丰富的资源和知识。

    USB下载 51单片机开发板与应用

    5. **矩阵键盘**: 4×4矩阵键盘,便于学习矩阵键盘编码和解码扫描原理。 6. **蜂鸣器**: 可用于声音报警、播放音乐等实验。 7. **DS18B20温度传感器**: 一线式总线元件,用于温度检测实验。 8. **AT24C08 EEPROM存储...

    优质收藏资料郭天祥51单片机笔记.docx

    9. **4x4矩阵键盘**:行线由P1.0-P1.3控制,列线由P1.4-P1.7控制。优点是节省端口资源,硬件简单,但编程相对复杂。检测方法包括扫描法和线反转法。扫描法的程序示例中,定义了扫描码和编码数组,通过循环扫描行和列...

    51单片机程序C语言-20矩阵键盘.zip

    学习这个压缩包的内容,可以帮助你掌握51单片机使用C语言处理矩阵键盘的方法,这对于电子爱好者和初学者来说是一份宝贵的资源。通过实践,你可以理解I/O端口的控制、中断处理、循环扫描键盘等技术,并且了解如何将...

    51单片机开发实验板使用说明

    根据给定文件的信息,我们可以详细地探讨51单片机学习开发实验板的相关知识点,包括其功能、使用方法以及各种接口和技术的应用。 ### 一、51单片机学习开发实验板简介 #### 1.1 SYB-2A单片机学习开发实验板概述 ...

    51单片机入门实训代码

    7. **显示与键盘接口**:7段数码管、LCD显示和矩阵键盘是常见的外设,代码会教你如何驱动它们,实现数据显示和用户交互。 8. **RTOS(实时操作系统)基础**:虽然51单片机资源有限,但也可以尝试使用简单的RTOS,如...

    单片机学习资料

    3. **矩阵键盘**:实现用户输入功能。 4. **AD键盘**:利用单片机内置AD转换功能,降低成本。 5. **8x8点阵**:展示图形显示能力。 6. **DS18B20温度传感器**:实现温度检测功能。 7. **蜂鸣器**:编写简单的音乐...

    51单片机控制步进电机的程序(含仿真和相关芯片文档)

    在电子工程领域,51单片机是一种广泛应用的微控制器,尤其在教学和小型控制系统中。这个项目聚焦于51单片机如何控制步进电机,一个精密的执行器,常用于精确的位置和速度控制。下面我们将深入探讨相关知识点。 首先...

    以应用能力培养为目标的单片机课堂教学改革.pdf

    这样的实验板主要包括51单片机小系统、LED指示灯、4位LED数码管、独立按键、矩阵键盘、串并转换、IIC存储器、音频喇叭、LCD1602液晶显示、A/D与D/A等单元电路,能在上面完成I/O端口、中断、定时器/计数器、串口等...

    红外线遥控器解码程序.doc-教程与笔记习题

    发射器主要包括键盘矩阵、编码调制和红外发送器,使用特定的编解码集成电路芯片,如LC7461,来编码按键信息。编码通常采用脉冲宽度调制(PWM),例如,用不同宽度的脉冲来代表二进制的“0”和“1”。具体来说,"0"由...

Global site tag (gtag.js) - Google Analytics