51单片机编程学习笔记——管脚输入

大纲

《51单片机编程学习笔记——管脚输出》一文中,我们了解了管脚和寄存器之间的关系。我们可以给寄存器的一些位设置值,然后控制管脚的电平,以达到给器件传输信号的目的。

实际上,这些管脚除了有输出功能,还有输入功能。即我们可以通过器件影响寄存器的值,从而给单片机获取输入信息的机会。

我们可以使用开发板上的“独立按键模块”来学习该知识点。

在学习之前,我们需要知道P0~P3管脚在复位情况下的电平状态。这将影响到后续编码时我们对默认状态的考虑和理解。

  • P0 :在复位后,P0 口的管脚处于高阻态,既不是高电平也不是低电平。这是因为 P0 口在作为通用 I/O 口使用时,内部没有上拉电阻,其电平状态取决于外部电路的连接情况。当 P0 口作为地址 / 数据总线复用口时,在不进行数据传输时,其状态不确定。
  • P1:复位后,P1 口的管脚默认输出高电平。这是因为 P1 口内部具有上拉电阻,在上电复位后,寄存器初始值为全 1,使得管脚呈现高电平状态。
  • P2:与 P1 口类似,P2 口复位后管脚默认输出高电平。因为 P2 口内部也有上拉电阻,上电复位后,其端口寄存器初始化为全 1,所以管脚为高电平。
  • P3:P3 口同样内部有上拉电阻,复位后管脚默认输出高电平。其端口寄存器在上电复位后为全 1,使得管脚处于高电平状态,并且 P3 口的各个管脚还具有第二功能,在没有使用第二功能时,默认呈现高电平。

由上可见,除了P0,其他端口默认状态时都是高电平。

让我们回到“独立按键模块”的电路原理图。

在这里插入图片描述
图中4个按键的电路连接的都是P3系列的管脚。它们的另一端连接着GND。

GND 是英文 “Ground” 的缩写,在电子电路等领域中表示接地。它代表着电路中的参考电位点,通常被定义为零电位。

然后按键被按下,管脚接地会导致其对应的寄存器位中值变成0。当按键被松开,管脚不接地,会自动上电,对应的寄存器位的值恢复成1

基于这样的认知,我们可以通过判断P30~P31的位变量值是否为0,来得知对应按键是否被按下。

我们可以设置如下规则:

  • K1被按下,LED的亮灯会左移1位
  • K2被按下,LED的亮灯会右移1位
  • K3被按下,LED的亮灯会熄灭,之前熄灭的灯会亮起
  • K4被按下,LED的灯会跑一轮马灯

对应代码如下

#include <REG52.H>
#include <intrins.h>

void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void Delay(unsigned int millisecond) {
	unsigned int i = 0;
 	for (i = 0; i < millisecond; i++) {
		Delay1ms();	
	}
}


void marquee(unsigned char from) {
	unsigned char i;
	for(i=0;i<8;i++) {
		// P2=~(0x01<<((from+i)%8));
		P2 = _cror_(P2, 1);
		Delay(200);
	}
}

sbit K1 = P3^0;
sbit K2 = P3^1;
sbit K3 = P3^2;
sbit K4 = P3^3;

// K1被按下,LED的亮灯会左移1位
// K2被按下,LED的亮灯会右移1位
// K3被按下,LED的亮灯会熄灭,之前熄灭的灯会亮起
// K4被按下,LED的灯会跑一轮马灯

void main() {
	P2 = 0xfe;

	while(1) {
		if(K1 == 0) {
			P2 = _crol_(P2, 1);
			Delay(200);
		}
		if(K2 == 0) {
			P2 = _cror_(P2, 1);
			Delay(200);
		}	
		if(K3 == 0) {
			P2 = ~P2;
			Delay(200);
		}
		if(K4 == 0) {
			// 从当前位置开始跑马灯
			marquee(j);
		}
	}		
}

需要说明的是,电路图中给的K1和K2对应的管脚是错的。实际上,我购买的开发板上,K1对应P30,K2对应P31。

这儿有两个函数需要解释下:

  • _cror_
    功能:对一个无符号字符型(unsigned char)变量进行循环右移操作,同样是将二进制位整体右移,移出的位补到最左边。
  • _iror_
    功能:对一个无符号整型(unsigned int)变量进行循环右移操作。循环右移意味着将变量的二进制位整体向右移动指定的位数,最右边移出的位会移到最左边。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

breaksoftware

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值