单片机IO口原理(P1口最简单,所以这里只介绍

凡属于读-修改-写方式的指令,从锁存器读入信号,其它指令则从端口引脚线上读入信号。这个可以说是最简单的按键输入实验了!,我想说的是代码再多一点,你这个就是傻瓜程序,按键一按,其他子程序基本完蛋4*4矩阵按键输入代码一:按下按键显示键值,松开不显示代码二:按下按键,松开按键后显示键值

(P1口最简单,所以这里只介绍P1,其他IO口原理类似)

P1口原理

可见P1口的工作原理比较简单。 先用P1口做输入输出比较容易理解。

1. 内部总线:是内部P1.X位寄存器的值。 例如内部总线P1.0电压为0V,则对应P1.0=0; =1;

2. P1.X引脚:对应单片机引脚接口

3. 读锁存器:读锁存器为1,允许读锁存器。 为0时,不允许读取锁存器。

4. 读引脚:如果为0,则不允许读引脚,如果为1,则允许读引脚。

5、写锁存:提供上升沿锁存数据(向单片机IO口写入数据时自动提供脉冲)

单片机IO口原理(P1口最简单,所以这里只介绍

几个核心问题:

1. 读锁存器和读引脚有什么区别?

读锁存器:读取锁存器Q的电平

读引脚:读取P1.X引脚电平

2. 读锁存器和读引脚可以同时读取吗?

不可以,同时只能打开两个输入缓冲区之一,因此只能同时读取一层。

3. 何时读取锁存器以及何时读取引脚?

所有属于读-修改-写模式的指令从锁存器读取信号,其他指令从端口引脚线读取信号。也就是说,只有遇到读指令时才会打开相应的输入缓冲区,通常处于关闭状态。

4、如果P1.0口初始设置为1,然后用按键拉低,松开按键后P1.0口会处于低电平吗?

不会,锁存器锁定1,写0之前总是输出1。按下按钮时,P1.0引脚变低,松开后仍然为高。

(有了以上知识,我们就可以轻松解决很多问题了)

按键输入

1.按键抖动

由于按钮的机械结构,按下时不可避免地会产生振动。 一般情况下,按下和松开时会出现振动。 振动时间约为10ms。

单片机IO口原理(P1口最简单,所以这里只介绍

2.打开proteus仿真并画出电路

功能:一键控制一个发光二极管。

这可以说是最简单的按键输入实验了!

由于它是51单片机,它有一个内部上拉电阻,因此我们不想浪费材料将上拉电阻连接到按钮。

单片机IO口原理(P1口最简单,所以这里只介绍

3.打开keil,编写以下代码

#include 
sbit key=P1^0;  //定义key为P1.0
sbit led=P2^0; //定义LED为P2.0
void delay10(void)	 //延时10ms
{
	int n=1000;
	while(n--);
}
void main(void)
{
	while(1)
	{
		if(key==0)	  //读P1.0引脚,如果引脚为低电平,则进入if
		{
			delay10(); //延时10ms消抖
			if(key==0)	 //再次判断按键是否按下,防止干扰,增强稳定
			{
				 led = !led;//led状态改变
				 while(key==0);//等待按键松开,防止往下执行
			}
		}
	}
}

博主有一个疑问,很困惑。 当“key”改为“P2^0”时,程序将无法正常运行。 有了解的人可以帮我解释一下吗?

烧录单片机后,我们会发现按下按钮时LED会熄灭,再次按下时LED会再次点亮。

单片机IO口原理(P1口最简单,所以这里只介绍

单片机IO口原理(P1口最简单,所以这里只介绍

4、程序升级

! ! !

不知道小伙伴们有没有发现这段代码的缺点。 好的代码不能有延迟。 对于51单片机来说,10ms的延时影响并不大,但是你可以做一句“while(key==0);//等待按钮松开”,我想说的是,如果你代码多一点,你就会成为一个傻瓜程序。 一旦按钮按下,其他子程序就基本结束了。

接下来我们看看博主是如何摆脱掉“while(key==0);//等待key被释放”这个该死的程序的

#include 
sbit key=P1^0;  //定义key为P1.0
sbit led1=P2^0; //定义LED为P2.0
sbit led2=P2^7; //定义LED为P2.0
void delay_ms(unsigned int t)	 //ms延时
{
	unsigned int i,j;
	for(i=0; i<t; i++)
		for(j=0; j<120; j++);
}
void keyscan()
{
		static int key_up=1;  //按键松开标志位,
		if(key==0 && key_up==1)//判断按键是否按下
		{
			delay_ms(10);//延时消抖
			key_up=0;//按下状态,(防止循环执行按键控制程序)
			if(key==0)    //再次判断,排除是松开状态或外界杂波干扰
			{	
				led1=!led1;
			}
		}
		else if(key==1)	key_up=1;
}
void main(void)
{
	int count=0;	//计数
	while(1)
	{	
		keyscan();
		count++;
		if(count==10000)
		{
			count=0;
			led2=!led2;	 //程序运行led2闪烁
		}
	}
}

为了验证按下按钮时其他程序仍然可以运行,我添加了一个绿色LED。 闪烁表示程序运行正常。 按下按钮不会影响绿色LED,黄色LED也可以用同样的方式控制。

单片机IO口原理(P1口最简单,所以这里只介绍

单片机IO口原理(P1口最简单,所以这里只介绍

4*4矩阵按键输入

代码稳定!

代码1:按下按钮显示键值,松开不显示

#include 
 
//分别显示0 1 2 3 4 5 6 7 8 9	A b c d E F -
char sg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
void delayms(unsigned int t)
{
	unsigned int i,j;
	for(i=0; i<t; i++)
		for(j=0; j<120; j++);
}
int keyscan(void)//返回键值
{
	int val=16;//无按键按下默认键值16吧
	P1 = 0xf0;
	if(P1!=0xf0)
	{
		delayms(10); 	//按键消抖
		switch(P1)     //行扫描
		{
			case 0xe0:
				val = 0; break;	
			case 0xd0:
				val = 1; break;	
			case 0xb0:
				val = 2; break;
			case 0x70:
				val = 3; break;
		}	
		P1 = 0x0f;
		switch(P1)       //列扫描
		{
			case 0x0e:
				val += 0; break;	
			case 0x0d:
				val += 4; break;	
			case 0x0b:
				val += 8; break;
			case 0x07:
				val += 12; break;
		}
	}
	return val;
}
void main(void)
{
	/*在这里定义初始化防止循环执行时循环初始化*/
	char keyval=0;
	while(1)
	{
		keyval = keyscan();//按键扫描
		P0 = sg[keyval];           //数码管输出
	}
}

代码效果:

单片机IO口原理(P1口最简单,所以这里只介绍

单片机IO口原理(P1口最简单,所以这里只介绍

代码2:按下按钮,松开按钮后显示键值

#include 
 
//分别显示0 1 2 3 4 5 6 7 8 9	A b c d E F -
char sg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
void delayms(unsigned int t)
{
	unsigned int i,j;
	for(i=0; i<t; i++)
		for(j=0; j<120; j++);
}
int val=0;//使用全局变量定义键值
void keyscan(void)
{
	P1 = 0xf0;
	if(P1!=0xf0)
	{
		delayms(10); 	//按键消抖
		switch(P1)     //行扫描
		{
			case 0xe0:
				val = 0; break;	
			case 0xd0:
				val = 1; break;	
			case 0xb0:
				val = 2; break;
			case 0x70:
				val = 3; break;
		}	
		P1 = 0x0f;
		switch(P1)       //列扫描
		{
			case 0x0e:
				val += 0; break;	
			case 0x0d:
				val += 4; break;	
			case 0x0b:
				val += 8; break;
			case 0x07:
				val += 12; break;
		}while(P1!=0x0f);   //等待按键松开
	}
}
void main(void)
{
	//在这里定义初始化防止循环执行时循环初始化
	while(1)
	{
		keyscan();//按键扫描
		P0 = sg[val];           //数码管输出
	}
}

单片机IO口原理(P1口最简单,所以这里只介绍

单片机IO口原理(P1口最简单,所以这里只介绍

嵌入式物联网的学习之路很漫长,很多人因为学习路径错误或者学习内容不够专业而错失高薪offer。 不过不用担心,我给大家整理了一份150多G的学习资源,基本涵盖了嵌入式物联网学习的所有内容。 点击下方链接0元领取学习资源,让您的学习之旅更加顺利! 记得点赞、关注、收藏、转发!

点此找助手0元获取:扫码进群获取资料

单片机IO口原理(P1口最简单,所以这里只介绍

单片机

华为手机办公中常用的扫描功能,可以帮到你

2024-5-7 6:01:29

单片机

(电气工作计划4篇)--诚聘设计师、设计部

2024-5-7 7:01:55

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索