51单片机学习笔记(一)

51单片机学习笔记(一)

我所使用的51单片机概况

下图为我所使用的单片机:
在这里插入图片描述

其中的外设及相关部件为:

1:独立按键;

2:一个向下凹陷的小槽:标志单片机的正极接口所在方向;

3:NRF24L01:无线通信模块;

4:红外接收头;

5:DS18B20:温度传感器;

6:矩阵键盘;

7:74HC595:用于拓展I/O口;

8:LED;

9:LED点阵屏;

10:LCD12864的接口;

11:LCD1602的接口;

12:调节LCD的清晰度;

13:晶振11.0592MHz;

14:数码管;

15:74HC138:控制数码管位选;

16:74HC245:控制数码管段选;

17:步进电机的接口和控制模块;

18:DS1302:一个时钟芯片,用于计时;

19:蜂鸣器;

20:变阻器;

21:热敏电阻;

22:光敏电阻;

23:外接其他传感器的接口;

24:冷启动按键;

25:复位按键;
在这里插入图片描述

1:复位电路;

2:晶振电路;

3:中断允许控制寄存器引脚;
在这里插入图片描述

单片机工作电压:3.5V到5.5V

定时器:3个

中断源:8个

中断优先级:4个

最多I/O口数量:39个

控制LED

点亮LED

在这里插入图片描述

由此图可知,LED的一端接的都是高电平。于是,只要引脚端是低电平,就能使LED点亮P。

注意:在上图中P2_7是高位,而P2_0是低位。

P2口是可位寻址,因此在对P2口进行赋值时,既可以对每一位进行逐一赋值。当P2口没有被赋值0时,所有的LED都是灭的,也就是所有引脚的初始值都是1.

如果想要点亮第二个灯和第七个灯,有以下两种赋值方法:

逐一赋值:

#include <REGX52.H>
void main()
{
	while(1)
	{
		P2_1=0;
		P2_6=0;
	}
}

整体赋值:

#include <REGX52.H>
void main()
{
	while(1)
	{
		P2=0xbd;
	}
}

由于在单片机对程序的执行中,单片机会反复地执行代码,不断地从头开始循环。所以,为了使程序的执行限制在主函数内,通常我们需要在主函数中加入一个死循环。

使LED闪烁

为了实现LED的闪烁,需要让单片机每隔一段时间,改变LED的状态。由于目前单片机只需要执行改变LED状态的指令,不需要同时执行其他指令,所以,可以使用Delay函数让单片机在不需要改变LED状态期间处于停滞状态。于是,使LED闪烁的代码如下

#include <REGX52.H>
void Delay(int a)
{
	unsigned char i, j;
while(a--){
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}

void main()
{
	P2_0=0;
	while(1)
	{
		Delay(1000);
		P2_0=~P2_0;
	}
}

Delay函数可在STC-ISP中的软件延时计算器获得,将其中的配置设置为“1毫秒”,“STC-Y1"获得函数Delay1ms后再在进行更改。将其更改成上述代码中的Delay函数。

LED流水灯

代码如下:

#include <REGX52.H>
void Delay(int a)
{
	unsigned char i, j;
while(a--){
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}

void main()
{
	unsigned char a=1;//定义8个字节的变量a,来表示每一次”1“的位置。
	while(1)
	{
		if(a==0)//一旦超出定义范围,重置a=1。
			a=1;
			P2=~a;//P2等于a的取反。
			a=a*2;
		Delay(250);
		}
}

控制独立按键

在这里插入图片描述

由上图知:独立按键的公共端都接在低电平,而另一端都是单片机的引脚,单片机的引脚出来一般都是高电平。因此,当按键按下时,开关接通,相对应的,其引脚也将变成低电平。独立按键从左至右四个开关分别对应引脚为P3_1,P3_0,P3_2,P3_3。

消抖与检测松手

消抖:在按键按下的瞬间和松开的瞬间,由于机械触点的弹性作用,一个开关在闭合时不会马上接通,而是会抖动一会。于是开关处的电位会发生短时间的抖动变化,而为了使这一部分抖动不影响单片机的运行,所以一般会使用Delay函数使单片机不处理这部分抖动。

检测松手:由于在按下按键时,引脚处持续为低电平。因此,要检测按下按键的次数,只需要检测松手的次数。于是,可以循环让按下按键的瞬间的前一刻的按键状态,当前一刻为0后一刻为1时,说明按键发生了松手;当前一刻为1后一刻为0时,说明按键发生了按下。

检测独立按键的代码如下:

#include <REGX52.H>

void Delay(int a)
{
	unsigned char i, j;
while(a--){
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}
void main()
{
	P2_0=0;
	while(1)
	{
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			P2_0=~P2_0;
		}
	}
}

独立按键控制LED显示二进制

代码如下:

#include <REGX52.H>

void Delay(int a)
{
	unsigned char i, j;
while(a--){
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}
void main()
{
	unsigned char a=0;
	while(1)
	{
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			a++;
		}
		P2=~a;
	}
}

独立按键控制LED移位

代码如下:

#include <REGX52.H>

void Delay(int a)
{
	unsigned char i, j;
while(a--){
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}
void main()
{
	unsigned char a=1;
	while(1)
	{
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			a=a*2;
			if(a==0)
				a=1;
		}
		P2=~a;
	}
}

控制数码管

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

数码管的显示是以一种扫描的方式显示的,即程序会重复地询问控制数码管的引脚的值,并决定LED的亮灭。因此数码管的显示需要长时间占用单片机的运行。

静态数码管显示

​ 要使数码管显示,需要先确定显示内容所在的位置,然后还有显示的内容,这就关系到位选和段选。

位选:

74HC138译码器:

该译码器所能复制三个引脚用于控制右边8个LED的接口,对P2_2,P2_3,P2_4进行赋值能够选中右边的LED的位置:

第一个LED: P2_4=1;P2_3=1;P2_2=1;

第二个LED: P2_4=1;P2_3=1;P2_2=0;

第三个LED: P2_4=1;P2_3=0;P2_2=1;

第四个LED: P2_4=1;P2_3=0;P2_2=0;

第五个LED: P2_4=0;P2_3=1;P2_2=1;

第六个LED: P2_4=0;P2_3=1;P2_2=0;

第七个LED: P2_4=0;P2_3=0;P2_2=1;

第八个LED: P2_4=0;P2_3=0;P2_2=0;

使用该译码器进行位选时,需要注意以下几点:

1、位选中,每次只能选择一个LED;

2、P2_2口为低位,P2_4口为高位;

3、记忆方法:每一个代表LED的位置位选其实是LED的位置减一再取其二进制,把每一位分离,并按高低位赋值给P2_4,P2_3,P2_2这三个引脚。

4、当没有对位选进行赋值时,P2_4,P2_3,P2_2这三个引脚的初始值均为1,所以数码管默认初始位置为的一个LED

段选:

由上图可知:

在数码管中,其连接方式为共阴极的连接方式。因此,想要点亮数码管,就应该使对应的想点亮的LED连接的引脚为1。由上图可知,一个LED有10个灯,这是个灯的控制引脚从高位到低位依次分别为P0_7,P0_6,P0_5,P0_4,P0_3,P0_2,P0_1,P0_0。

进行段选时,需要注意以下几点:

1、当没有对段选进行赋值时,所有引脚的初始值均为1,所以数码管默认初始显示为点亮所有LED。

2、段选中,P0口可以位寻址。因此,在赋值时,既可以整体赋值,也可以对P0_0等进行单独赋值。

使数码管静态显示的代码如下:

#include <REGX52.H>
void main ()
{
	while(1)
	{
		P2_2=0;
		P2_3=1;
		P2_4=0;
		P0=0x7d;
	}
}

动态数码管显示

由于数码管的位选每次只能选中一个LED。因此,想要实现数码管上出现多个LED同时显示不同的内容,就需要利用数码管扫描显示的原理,让数码管显示一个LED后马上显示下一个LED,由于数码管的扫描速度很快加上人眼的暂留效应,就能使数码管看起来能够多个LED同时显示不同的内容。

消影:

由于在单片机中,是先选中位选,再执行段选。在没有延时和清零情况下,直接进入下一个位选,会导致上一个段选残留进入到下一个位选,直到下一个段选执行才结束。这样,就会导致LED中的内容出现串位,使显示效果变差。

所以,要在一个段选执行之后,将段选清零。这样,才不会是上一个段选影响到下一个位选。

同时,要在段选和清零之间延时一点点时间,这样能是数码管的亮度更好。(由于延时期间,单片机不执行程序。所以,延时时间不能太长,否则数码管的亮度会下降甚至出现闪烁)

使数码管动态显示各个LED位置的代码如下:

#include <REGX52.H>

void Delay(int a)		//@11.0592MHz
{
	
	unsigned char i, j;
	while(a--){
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}
void light(unsigned char postion,unsigned char value)
{
	unsigned char x[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
	switch(postion)
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=x[value];
	Delay(1);
	P0=0x00;
}
void main ()
{
	while(1)
	{
		light(1,1);
		light(2,2);
		light(3,3);
		light(4,4);
		light(5,5);
		light(6,6);
		light(7,7);
		light(8,8);
	}
}

我的学习笔记(1)到此为止,谢谢阅读!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值