2019-01-09 20:36:32 ermaoHa 阅读数 1890
  • 静态和动态控制数码管-第1季第7部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第7个课程,全面讲解了静态数码管、无38译码器式动态数码管、有38译码器式动态数码管等各种数码管驱动方式,学完本课程将会对数码管的驱动方式彻底熟悉和掌握。

    2846 人正在学习 去看看 朱有鹏

c51单片机实现矩阵键盘用数码管动态依次显示键值

//4*4矩阵按键0-F4位LED轮流显示,按键从左到右从上到下0-F 
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

uchar count=0,down=0;//全局变量用于表示按键个数

	
//函数声明
uchar keyscan();
void delay(uchar z);
void delay1();
uchar keyscan(void);


uchar a[]={0,0,0,0,0};//用于暂存按键

uchar code table[]=
{
	0x3f,0x06,0x5b,0x4f,
	0x66,0x6d,0x7d,0x07,
	0x7f,0x6f,0x77,0x7c,
	0x39,0x5e,0x79,0x71,
};

//延时函数
void delay(uchar z)//动态扫描延时
{
	while(z--);
}

void delay1()//按键延时消抖函数
{
	uchar i,j;
	for(i=50;i>0;i--)
	for(j=200;j>0;j--);
}

//扫描函数
uchar keyscan(void)
{
	uchar sccode,recode,key;
	P1=0xf0;
	if((P1&0xf0)!=0xf0)
	{
		delay1();
		if((P1&0xf0)!=0xf0)
		{
			sccode=0xfe;
			while((sccode&0x10)!=0)
			{
				P1=sccode;
				if((P1&0xf0)!=0xf0)
				{
					recode=P1&0xf0;
					sccode=sccode&0x0f;
					switch(sccode+recode)
					{
						case 0xee: key=0;break;
						case 0xde: key=1; break;
						case 0xbe:key=2;break;
						case 0x7e:key=3;break;
						case 0xed:key=4;break;
						case 0xdd:key=5;break;
						case 0xbd:key=6;break;
						case 0x7d:key=7;break;
						case 0xeb:key=8;break;
						case 0xdb:key=9;break;
						case 0xbb:key=10;break;
						case 0x7b:key=11;break;
						case 0xe7:key=12;break;
						case 0xd7:key=13;break;
						case 0xb7:key=14;break;
						case 0x77:key=15;break;
					}
					count++;
					down=1;
					//return key;
				}
				else
					sccode=(sccode<<1)|0x01;
			}
		}
	}
	return key;
}

//主函数
void main()
{
	uchar temp,j,b;
	temp=0xf7;
	P2=0x7f;
	P0=0x3f;
	while(1)
	{
		a[0]=keyscan();
		if(down==1){
		for(j=4;j>0;j--)//存放数据
			{
				a[j]=a[j-1];
			}
			down=0;	
		}
		for(b=0;b<100;b++)//动态扫描
		{
			for(j=4;j>0;j--)
			{
				P2=_cror_(temp,j-1);//数组角标表示移了多少位数
				P0=0x00;//消隐
				P0=table[a[j]];
				delay(100);
			}
		}
 }
}
2019-10-22 22:05:27 qq_41909909 阅读数 20
  • 静态和动态控制数码管-第1季第7部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第7个课程,全面讲解了静态数码管、无38译码器式动态数码管、有38译码器式动态数码管等各种数码管驱动方式,学完本课程将会对数码管的驱动方式彻底熟悉和掌握。

    2846 人正在学习 去看看 朱有鹏

单片机开发板如何实现接地?

电源的负极和单片机GND引脚连接,就是接地了,电源可以是电池,或者市电经过直流稳压器出来的电,注意电压要匹配,过大可能会烧坏单片机。
接电源负极就是接地

矩阵键盘

/*************************************************************************************

*
实验现象:下载程序后数码管显示0,按下矩阵按键上的按键显示对应的数字
		  S1-S4:0-3
		  S5-S8:4-7
		  S9-S12:8-B
		  S13-S16:C-F。
接线说明: (具体接线图可见开发攻略对应实验的“实验现象”章节)
		   1,单片机-->静态数码管模块
		   J22-->J8
		   2,单片机-->矩阵键盘模块
		   J20-->JP3	
注意事项:										

										  
**************************************************************************************

*/
#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

#define GPIO_DIG P0
#define GPIO_KEY P1


u8 KeyValue;	//用来存放读取到的键值


u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}

/*******************************************************************************
* 函 数 名         : KeyDown
* 函数功能		   : 检测有按键按下并读取键值
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void KeyDown(void)
{
	char a=0;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)//读取按键是否按下
	{
		delay(1000);//延时10ms进行消抖
		if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
		{	
			//测试列
			GPIO_KEY=0X0F;
			switch(GPIO_KEY)
			{
				case(0X07):	KeyValue=0;break;
				case(0X0b):	KeyValue=1;break;
				case(0X0d): KeyValue=2;break;
				case(0X0e):	KeyValue=3;break;
			}
			//测试行
			GPIO_KEY=0XF0;
			switch(GPIO_KEY)
			{
				case(0X70):	KeyValue=KeyValue;break;
				case(0Xb0):	KeyValue=KeyValue+4;break;
				case(0Xd0): KeyValue=KeyValue+8;break;
				case(0Xe0):	KeyValue=KeyValue+12;break;
			}
			
		}
	}
	while((a<50)&&(GPIO_KEY!=0xf0))	 //检测按键松手检测
	{
		delay(100);
		a++;
	}
}


/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	

	while(1)
	{	
		KeyDown();		   //按键判断函数
		GPIO_DIG=~smgduan[KeyValue];	  //
	}		
}

GPIO_KEY=0x0f;
是把它高4位设置为0,我理解的是,设置为0,你不动它它不会变成1.所以先把他设置为00001111,这时候再读取它,比如塔是11011101,此时就变为00001101,然后去测试列,然后去测试行。

他说可以做计算器。。不会/。。。

char code SST516[3] _at_ 0x003b;  
//保留仿真器

_at_定义的变量是绝对变量,是对指定存储空间绝对地址的操作。采用_at_定义的变量只能是全局变量。
这个句子的意思是:定义变量字符型数组SST516,地址为为 code空间的0x003b。

#include <reg52.h>
#include <intrins.h>
sbit BEEP = P3 ^ 7;
//蜂鸣器驱动线
unsigned char key;
unsigned char code disp_code[] = {    0x28,0xa9,0x20,0x30,0x34,0x60,0x21,0x62,0x28,0x20,0x61,0xa2,0x34,0x7a,0x74,0x7e };
//显示码数组0,C,8,A,H,9,6,3,0,8,5,2,H,7,4,1
unsigned char code key_code[] = {   0xee, 0xed, 0xeb, 0xe7, 0xde, 0xdd, 0xdb, 0xd7, 0xbe, 0xbd, 0xbb,   0xb7, 0x7e, 0x7d, 0x7b, 0x77   //键编码数组};
char code SST516[3] _at_ 0x003b;
//保留仿真器
                                    /********************延时子函数***************/
void delayms(unsigned int ms) {
	unsigned char t;
	while (ms--) {
		for (t = 0; t < 114; t++);
	}
} /*************x*0.14MS 延时子函数****************/
void delayus(unsigned char x) {
	unsigned char i;
	while (x--) {
		for (i = 0; i < 14; i++)     {
			;
		}
	}
}
/******************蜂鸣器驱动子函数*****************/
void beep() {
	unsigned char i;
	for (i = 0; i < 250; i++) {
		delayus(6);
		BEEP = !BEEP; //BEEP取反
	}
	BEEP = 1;
	//关闭蜂鸣器
	delayms(150);
	//延时
}
/******************键盘扫描子函数*********************/
unsigned char keyscan() {
	unsigned char scan1, scan2, keycode, j;
	P1 = 0xf0;
	scan1 = P1;
	if (scan1 != 0xf0) { //判键是否按下
		delayms(10);    //延时10ms
		scan1 = P1;
		if (scan1 != 0xf0) { //二次判键是否按下
			P1 = 0x0f;
			scan2 = P1;
			keycode = scan1 | scan2; //组合成键扫描编码
			for (j = 0; j < 16; j++) {
				if (keycode == key_code[j]) { //查表得键值
					key = j;
					return (key); //返回有效键值
				}
			}
		}
	} else
		P1 = 0xff;
	return (key = 16); //返回无效码
}
/*************************主函数***********************/
void main(void) {
	P0 = 0xf7; //数码管初始显示"-"
	P2 = 0xfd;//数码管显示在第二位
	P1 = 0xff;
	while (1) {
		keyscan();
		if (key < 16) { //有效键值
			P0 = disp_code[key]; //显示键值
			beep(); //蜂鸣器响一声
		}
	}
}
2018-01-27 18:33:35 xiongjianjunCSND 阅读数 8390
  • 静态和动态控制数码管-第1季第7部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第7个课程,全面讲解了静态数码管、无38译码器式动态数码管、有38译码器式动态数码管等各种数码管驱动方式,学完本课程将会对数码管的驱动方式彻底熟悉和掌握。

    2846 人正在学习 去看看 朱有鹏

51单片机矩阵键盘响应程序

#include <reg51.h>

// P0端口接LED
// P0端口接数码管
// P3端口接矩阵键盘


#define LED P0
#define KEY P3
#define DIG P0
unsigned char GetKey(void);
void delay10ms(void);
// 独立数码管的段码表
unsigned char val[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
void main(void)
{
unsigned char key = 0;
while (1)
{
key = GetKey();
if (key != 0)
{
DIG = val[key];
}
}
}
unsigned char GetKey(void)
{
unsigned char hang = 0, lie = 0;
unsigned char keyvalue = 0;
// 第1回合第1步
KEY = 0x0f; // 从IO口输出,写IO口
if (KEY != 0x0f)// 从IO口输入,读IO口
{
// 读出的不是0x0f说明有按键被按下
// 第1回合第2步:读出端口从读出值来判断是哪一行
 delay10ms();
// 第一回合中算出行号
switch (KEY)
{
case 0x0e:hang = 1; break;
case 0x0d: hang = 2; break;
case 0x0b: hang = 3; break;
case 0x07: hang = 4; break;
default: break;
}
// 第2回合第1步
KEY = 0xf0;
if (KEY != 0xf0)
{
 switch (KEY)
{
case 0xe0:lie = 1; break;
case 0xd0: lie = 2; break;
case 0xb0: lie = 3; break;
case 0x70: lie = 4; break;
default: break;
}
// 经过2个回合后hang和lie都知道了,然后根据hang和lie去计算键值即可
keyvalue = (hang - 1) * 4 + lie;
return keyvalue;
}
}
return 0;
}
void delay10ms(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=5;c>0;c--)
        for(b=4;b>0;b--)
            for(a=248;a>0;a--);
}


2015-01-22 16:08:33 u011046042 阅读数 2304
  • 静态和动态控制数码管-第1季第7部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第7个课程,全面讲解了静态数码管、无38译码器式动态数码管、有38译码器式动态数码管等各种数码管驱动方式,学完本课程将会对数码管的驱动方式彻底熟悉和掌握。

    2846 人正在学习 去看看 朱有鹏

使用4*4的矩阵键盘和一个数码管

在4*4的矩阵键盘上编码0-F的字符,和一个数码管显示每个键盘上输入的字符。

//4*4键盘检测程序,按下键后相应的代码显示在数码管上
#include<reg51.h>
typedef unsigned char UINT8;
UINT8 i=100;
UINT8 j,k,temp,key;
void delay(unsigned char i)
{
  for(j=i;j>0;j--)
    for(k=125;k>0;k--);
}
UINT8 code table[]=
{
	0x3f,0x06,0x5b,0x4f,
	0x66,0x6d,0x7d,0x07,
	0x7f,0x6f,0x77,0x7c,
	0x39,0x5e,0x79,0x71
};

void display(unsigned char num)
{
     P0=table[num];
}

void init_led()
{
	P0 = 0x00;
}
                                                                                                     
void main()
{
	while(1)
	{  
		P1 = 0xef;
		temp = P1;
		temp = temp&0xf0;
		if (temp != 0xf0)
		{
			temp = P1;
			switch(temp)
			{
				  case 0xee:
					   key=0;
					   break;
				  case 0xed:
					   key=1;
					   break;
				  case 0xeb:
					   key=2;
					   break;
				  case 0xe7:
					   key=3;
					   break;
				  default:					  
					  break;
			}
			display(key);
			P1=0xfe;
		}
		P1 = 0xdf;
		temp = P1;
		temp = temp&0x0f;
		if(temp != 0x0f)
		{
			temp = P1;
			switch(temp)
			{
				  case 0xde:
					   key = 4;
					   break;
				  case 0xdd:
					   key = 5;
					   break;
				  case 0xdb:
					   key = 6;
					   break;
				  case 0xd7:
					   key = 7;
					   break;
				  default:
					  break;
			 }
			 display(key);
		}
		P1=0xbf;
		temp=P1;
		temp=temp&0x0f;
		if(temp != 0x0f)
		{
			temp=P1;
			switch(temp)
			{
				  case 0xbe:
					   key=8;
					   break;

				  case 0xbd:
					   key=9;
					   break;

				  case 0xbb:
					   key=10;
					   break;

				  case 0xb7:
					   key=11;
					   break;
				  default:
					   break;
			}
			display(key);
		}
		P1=0x7f;
		temp=P1;
		temp=temp&0x0f;
		if(temp!=0x0f)
		{		  
			temp=P1;
			switch(temp)
			{
				  case 0x7e:
					   key=12;
					   break;

				  case 0x7d:
					   key=13;
					   break;

				  case 0x7b:
					   key=14;
					   break;

				  case 0x77:
					   key=15;
					   break;
				  
				  default:
					  break;
			}
			display(key);
		}
	}	
}
这个上面有一个bug就是每进入的时候数码管不是空的而是现实“0”这个没有解决。



2018-07-17 01:04:32 weixin_40814407 阅读数 2123
  • 静态和动态控制数码管-第1季第7部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第7个课程,全面讲解了静态数码管、无38译码器式动态数码管、有38译码器式动态数码管等各种数码管驱动方式,学完本课程将会对数码管的驱动方式彻底熟悉和掌握。

    2846 人正在学习 去看看 朱有鹏
/*******************************************************************************
*  标题:                  矩阵键盘显示数字到静态数码管                         *
*  时间                      2018年7月17日00:45:03					           *
*																			   *
*  实验说明:用矩阵键盘上的16个按键,分别为0、1、3、4、5、6、7、8、9、a、b、c  *
d、e、f显示到静态数码管上				   *                                   *
********************************************************************************
* 实验心得:															       *
1.测试行(row)的时候就是线是竖着的的那一列为1,测试列(col)的时候就是		   *
线是横着的那几行为1															   *
2.调用函数void KeyScan(void);时,调用的时候只需要写KeyScan就行,不然调试不成功 *
********************************************************************************/


#include <reg52.h>

#define GPIO_KEY P1
#define GPIO_SHOW P2

unsigned char code DIG_CODE[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
                                 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
void KeyScan(void);
void Delay10ms(unsigned int c);
unsigned int KeyValue=-1;
void main()
{

   while(1)
  {
     
    KeyScan();
	switch(KeyValue)
	{
		 case(0):
		 P2=~DIG_CODE[0];
		 break;	
		 case(1):
		 P2=~DIG_CODE[1];
		 break;
		 case(2):
		 P2=~DIG_CODE[2];
		 break;	
		 case(3):
		 P2=~DIG_CODE[3];
		 break;	
		 case(4):
		 P2=~DIG_CODE[4];
		 break;	
		 case(5):
		 P2=~DIG_CODE[5];
		 break;	
		 case(6):
		 P2=~DIG_CODE[6];
		 break;	
		 case(7):
		 P2=~DIG_CODE[7];
		 break;	
		 case(8):
		 P2=~DIG_CODE[8];
		 break;	
		 case(9):
		 P2=~DIG_CODE[9];
		 break;	
		 case(10):
		 P2=~DIG_CODE[10];
		 break;	
		 case(11):
		 P2=~DIG_CODE[11];
		 break;	
		 case(12):
		 P2=~DIG_CODE[12];
		 break;	
		 case(13):
		 P2=~DIG_CODE[13];
		 break;	
		 case(14):
		 P2=~DIG_CODE[14];
		 break;	
		 case(15):
		 P2=~DIG_CODE[15];
		 break;	
		 default:
		 P2=~DIG_CODE[1];
		 break;
	}

    


	/******************************************************
	*******************************************************
	if语句的算法
	 if(KeyValue==0)
	 P2=~DIG_CODE[0];
	 if(KeyValue==1)
	 P2=~DIG_CODE[1];
	 if(KeyValue==2)
	 P2=~DIG_CODE[2];
	 if(KeyValue==3)
	 P2=~DIG_CODE[3];
	 if(KeyValue==4)
	 P2=~DIG_CODE[4];
	 if(KeyValue==5)
	 P2=~DIG_CODE[5];
	 if(KeyValue==6)
	 P2=~DIG_CODE[6];
	 if(KeyValue==7)
	 P2=~DIG_CODE[7];
	 if(KeyValue==8)
	 P2=~DIG_CODE[8];
	 if(KeyValue==9)
	 P2=~DIG_CODE[9];
	 if(KeyValue==10)
	 P2=~DIG_CODE[10];
	 if(KeyValue==11)
	 P2=~DIG_CODE[11];
	 if(KeyValue==12)
	 P2=~DIG_CODE[12];
	 if(KeyValue==13)
	 P2=~DIG_CODE[13];
	 if(KeyValue==14)
	 P2=~DIG_CODE[14];
	 if(KeyValue==15)
	 P2=~DIG_CODE[15];
	*************************************************/
   }
}

 void KeyScan(void)	  //测试行(row)的时候就是线是竖着的的那一列为1,测试列(col)的时候就是线是横着的那几行为1 
{
	char a = 0;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)//读取按键是否按下
	{
		Delay10ms(1);//延时10ms进行消抖
		if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
		{
			
			//测试列
			GPIO_KEY=0X0F;
			switch(GPIO_KEY)
			{
				case(0X07):	KeyValue=0;break;
				case(0X0b):	KeyValue=4;break;
				case(0X0d): KeyValue=8;break;
				case(0X0e):	KeyValue=12;break;
			}
			//测试行
			GPIO_KEY=0XF0;
			switch(GPIO_KEY)
			{
				case(0X70):	KeyValue=KeyValue+3;break;
				case(0Xb0):	KeyValue=KeyValue+2;break;
				case(0Xd0): KeyValue=KeyValue+1;break;
				case(0Xe0):	KeyValue=KeyValue;break;
			}
			while((a<50) && (GPIO_KEY!=0xf0))	 //检测按键松手检测
			{
				Delay10ms(1);
				a++;
			}
		}
	}
}

/*******************************************************************************
* 函 数 名         : Delay10ms
* 函数功能		   : 延时函数,延时10ms
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void Delay10ms(unsigned int c)   //误差 0us
{
    unsigned char a, b;

	//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
    for (;c>0;c--)
	{
		for (b=38;b>0;b--)
		{
			for (a=130;a>0;a--);
		}          
	}       
}

 

 

 

单片机矩阵键盘

阅读数 453

没有更多推荐了,返回首页