51单片机学习笔记

1 LED笔记

1.1控制原理

左
右边的vcc表示的是正极。
初始状态LED两端都会接高电平,所以只需要通过编辑程序,使得左边电平变为低电平即能点亮LED。
其各个LED连接于单片机的位置为:
在这里插入图片描述
单片机的寄存机为8位,每一位可以控制其电平的正负

LED连接的寄存器名为P2

CPU可以访问寄存器去写值,然后使寄存器发送信息给驱动器,然后就可以控制完成我们想要的功能

若在寄存器的一位上写1则为高电平,写0则为低电频

1.2 点亮一个LED

点亮一个LED

#include <REGX52.H>
void main()
{
	P2=0xFE;//大写P
}

这里的0xFE是二进制数1111 1110对应的16进制数

当单片机执行完这个任务后,会点亮第一个LED
如图:
在这里插入图片描述
如果想要点亮其他LED,改变P2的值即可

好!你现在已经完成伟大的一步了!
点亮是什么,点亮就是初生的婴儿!

现在你尽可以发挥想象,使用你的c语言知识去点亮!

1.3闪烁

很简单,你只需要延时点亮就行。
但需要注意的是这个延时的时间取决于你的单片机的金振频率。
所以我们需要在STC软件中找到自己的单片机型号,生成延时函数。

在这里插入图片描述
但这个代码会有一个函数 __ nop__(),这个函数需要一个头文件:#include<INTRINS.H>

__ nop__()是一个空语句

然后使用这个函数,再在主函数里调用

以上都可不看,这个函数暂时没有用处。直接删掉即可。

在stc中选择一个延时1毫秒的函数然后更改成

void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms){
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

1.4通过按键控制LED

独立键盘处
有4个按键,分别为
K1,K2,K3,K4
由于设计时k1与k2接反,所以需要主要的是第一个按键为P3_1,第二个按键为P3_0,第三个按键为P3_2,第三个按键为P3_3
在这里插入图片描述
按键在不按下时默认值为1,若按下第一个键,则P3_1=0,若按下第二个键,则P3_0=0,按下第三个按键则P3_2=0…

独立按键按下与松开时存在按键抖动
在这里插入图片描述
所以需要消抖方式如下。

if(P3_1==0){
			Delay(20);
			while(P3_1==0);
			Delay(20);

消抖后可以避免函数重复执行。
控制LED点亮与熄灭

#include <REGX52.H>

void main()
{
	while(1)
	{
		if(P3_0==0){
			P2_0=0;
		}else{
			P2_0=1;
		}
	}
}

1.5 led的亮点位移

简单的来说就是按一下按键K1,点亮第一个led,再按一下K1点亮第二个led…
这时候我们就要用上位移符号:<<和>>,他们分别是左移与右移
例如:P2从1111 1110到1111 1101,
P2=0x01<<1
再取反:即P2=~(0x01<<1)
为什么不用P2<<1呢?
这是因为左移的话,会变成这样1111 1100,右侧补零,左侧移出。
所以使0111 1111与1111 1110能够按一次左或右就能转换
则无法直接使用P2=P2<<1来实现,而需要一个中间变量LEDNum
请看以下范例,可以使用变量:

#include <REGX52.H>

void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;

while(xms){
	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
	xms--;
}

}
unsigned char LEDNum=0;

void main()
{
	P2=~0x01;
	while(1)
	{
		if(P3_0==0)
		{
			Delay(20);
			while(P3_0==0);
			Delay(20);
			LEDNum++;
			if(LEDNum==8)
			{
				LEDNum=0;
			}
			P2=~(0x01<<LEDNum);
		}
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			if(LEDNum==0)
			{
				LEDNum=7;
			}else
			{
				LEDNum--;
			}
			P2=~(0x01<<LEDNum);
		}

}

}

2 数码管学习笔记

2.1原理介绍

在这里插入图片描述
其每一个衡或竖都是一个LED加上右下角的一个点,每一个数字都刚好为8个二极管正好可以使用16进制数来控制其亮灭,其段码1111 1111分别对应为DP,G,F,E,D,C,B,A,其顺序是反过来的
在这里插入图片描述

看上图右侧可知,这是共阴极连接,控制单个数字的引脚是公用的。

所以这是控制单个数码管显示的原理图。
在这里插入图片描述
其工作原理为用3个口P2_2、P2_3、P2_4控制8个口LED1/2/3/4/5/6/7/8

其原理为用3个二进制的数可以表达2^3个数,即为8个数,如:000则表示LED1,111表示LED8等,但需要主要的是LED1在最右边,LED8在最左边

其作用为只让一个LED闪烁。

接下来请看实例来了解
如果想在第3位输入数字6

#include <REGX52.H>

void main()
{

		P2_4=1;
		P2_3=0;
		P2_2=1;
		P0=0x7D;
	while(1)
	{
	
	}
}

这里要注意高位表示,即从P2_4开始往下写,得101。101对应的是16进制中的5(为什么这里是5而不是3)因为他是从右开始数的,且最右边的为000,右二则为001
P2_4=1;
P2_3=0;
P2_2=1;
这三行指的是第3个数码管亮
0x7D对应的则是数字6

2.1动态显示

通过函数的反复多次的扫描,执行我们就可以实现动态显示。
(为什么不能123位置同时显示呢,上面说了,他们的结构决定了他们不能同时静态地在123位置显示123,需要以多次反复地以人眼无法察觉的速度显示1或2或3,这样就可以看起来同时在123位置显示123了)
但在此之前我们还要先建立一个显示的函数。
每次都一个一个打,太麻烦,所以我们可以使用函数来实现这个功能。

unsigned char nixietable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7D,0x07,0x7F,0x6F};

void nixie(unsigned char location,number)
{
	switch(location)
	{
		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=nixietable[number];
	Delay(1);
	P0=0x00;
	
}


注意函数的的最后两行,他们的作用是消影。
如果没有他们,在动态显示时。
在这里插入图片描述
就会变成这样,由于先选位选再选段选,但在下一个位选选择时上一次的段选会篡到下一位的位选上。

当我们调用函数,nixie(1,2),这样,数码管的第一位就会显示2。

然后再多次调用显示。

#include <REGX52.H>

void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}


unsigned char nixietable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7D,0x07,0x7F,0x6F};

void nixie(unsigned char location,number)
{
	switch(location)
	{
		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=nixietable[number];
	Delay(1);
	P0=0x00;
}

void main()
{
	while(1)
	{
		nixie(1,1);
		nixie(2,2);
		nixie(3,3);

	}
}

单片机执行此函数后,就会在123位置显示123.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lisabier

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

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

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

打赏作者

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

抵扣说明:

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

余额充值