Autoleaders控制组-51单片机学习笔记(1)

一.单片机简介

单片机(MCU),内部集成CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能;
51单片机系列
CPU:单片机核心,处理信息;
位数:8位;
RAM:随机存储器(掉电丢失)==内存条,512字节
ROM:只读存储器(掉电不丢失)==硬盘,8K
工作频率:取决于单片机给的时钟(晶振)
电平:高电平5V,低电平0V;

二.LED

在这里插入图片描述

1. 点亮一个LED

该LED模块中LED左端连接VCC,为高电平,若要点亮LED则要使LED另一端(右侧)为低电平;即可通过控制P2管脚的电平控制LED的亮灭;
控制管脚:值为0为低电平,值为1为高电平;

代码:让P2以16进制形式展示8个管脚的电平;
P2=0xFE; <==>1 1 1 1 1 1 1 0
由于数据的高位对应端口的高位,如P2_7对应第一个1;所以P2=0xFE意味着P2_0=0,剩余端口为1,即仅D1会亮

#include <REGX52.H>

void main()
{
	P2=0x7f;
}

而上述代码将点亮D8。

2.LED闪烁

利用stc-isp中的软件延时计算器实现LED闪烁;
生成延时代码时确保选择的系统频率与单片机时钟频率一致;
若软件延时计算器生成的代码带有_nop_函数,需加上头文件#include <INTRINS.H>

#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 22;
	j = 3;
	k = 227;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	while(1)
	{
		
		P2=0xFE;
		Delay500ms();//达到闪烁效果
		P2=0xFE;
	}

}

可对延时函数进行修改使延时的长短可更改;先生成1ms的延时函数,传参进入函数后对函数内部设置参数次数的循环。

void Delayxms(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;
	while(xms--){
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}	
}

3.流水灯

将LED闪烁的代码进行修改,即LED熄灭后替换下一个亮起的LED可逐个点亮LED;
亦可设置为双向流水灯:

void main()
{
	unsigned int xms;//利用变量传参便于修改
	xms=100;
		while(1)
	{
		
		P2=0x7E;
		Delayxms(xms);
		P2=0xBD;
		Delayxms(xms);
		P2=0xDB;
		Delayxms(xms);
		P2=0xE7;
		Delayxms(xms);
		P2=0xDB;
		Delayxms(xms);
		P2=0xBD;
		Delayxms(xms);
		
	}
}

三. 独立按键

在这里插入图片描述

1.控制LED亮灭

单片机端口默认电平为高电平,按下按键接通时由于另一端连接GND,相应的端口转变为低电平。
在循环中使用判断语句,以按键的电平状态控制LED;仅按住按键时灯亮

#include <REGX52.H>

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


}

2.控制LED状态

按键按下或松开瞬间会发生颤抖,影响按键的稳定,此时需要延时来消除颤抖带来的影响;

~表示按位取反,如 ~10010001==01101110

void main()
{
	while(1){ 
		if(P3_1==0){
		Delay(20);
		while(P3_1==0);//按住按键时一直再此循环中,避免按键时长的影响;
		Delay(20);
		P2_0=~P2_0;//电平取反,控制亮灭
		
		}
	}

}

3.控制LED显示二进制

①使P2按照从零开始的二进制形式进行逐次递加1可以显示二进制形式,但是此时移动的是1,而点亮LED所需电平为0,此时可运用取反符;

unsigned char num;//取反的对象
void main()
{
	while(1){
		if(P3_1==0){
			Delay(20);
			while(P3_1==0);
			Delay(20);
			num++;
			P2=~num;
		}
	}
}

②P2口默认每个接口为高电平,即初始形式为1111 1111;此时令P2–即可实现二进制的显示;

while(1){
		if(P3_1==0){
			Delay(20);
			while(P3_1==0);
			Delay(20);
			P2--;
		}
	

4.控制LED移位

<<:按位左移; 0001 0100<<2即往左位移两位,新位补零,为0101 0000;>>按位右移类似

由按位移动可通过按键控制LED位移显示;

void main()
{
	while(1){
	if(P3_1==0||P3_0==0||P3_2==0||P3_3==0){
			Delay(20);
			while(P3_1==0||P3_0==0||P3_2==0||P3_3==0);
			Delay(20);
			P2_0=0;
			break;
	}//设置启动(任意一个按键点亮)
}	
	while(1){
		if(P3_0==0){
			Delay(20);
			while(P3_0==0);
			Delay(20);
			numofLED++;
			if(numofLED==8){
			numofLED=0;}//当超出LED个数时刷新
			P2=~(0x01<<numofLED);//取反让0移位
		}else if(P3_1==0){
			Delay(20);
			while(P3_1==0);
			Delay(20);
			numofLED--;//减少向左移的个数,相对右移;
			if(numofLED==-1){
			numofLED=7;}
			P2=~(0x01<<numofLED);
		}
	}
}

四.数码管

数码管管脚分为共阴极和共阳极;
共阴极位选时选中即电平为0;
共阳极位选时选中及电平为1;
在这里插入图片描述
位选:通过P2_2,P2_3,P2_4三个端口控制要点亮的LED,此三个端口数值拼接显示的二进制数对应十进制数的LED接通,此时也遵循数据高位对端口的高位;如

P2_4=1;P2_3=1;P2_2=0;对应的十进制值为6,即Y6对应的LED7被选中;电平为0,其他LED电平为默认值1
每次只能选择一个LED

在这里插入图片描述
段选:P0输入控制信号通过74HC245放大,驱动LED;
此处可看作8个LED共用一套管脚,即信号传输到每个LED,但只有位选中的LED显示;
由于位选时是共阴极,要让LED对应区域亮则需令其为1;
以16进制输入P0数值,同样遵循高位端口对应高位数字;

1.静态显示

#include <REGX52.H>
unsigned char key[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//输入数组下标对应的“显示码”
void Nixie(unsigned char LED,num)//通过输入对应的LED号和显示的数字达到显示静态显示的效果
{
	switch(LED){
		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=key[num];//段选

	}

void main()
{
		Nixie(2,0);
	while(1){
	}
}

2.动态显示

通过余辉和视觉残留显示多个数字;
连续重复位选和段选的操作可实现动态显示,
即 位选 段选 位选 段选… …
但是由于程序按顺序自上而下逐步进行,在前一个段选仍执行,下一个位选开始执行而下一个段选未执行时,会在下一个位选的位置显示上一个段选的数字,所以需要在段选和位选中间将段选归零;

#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;
	while(xms--){
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}	
}
unsigned char key[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char LED,num)
{
	switch(LED){
		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=key[num];Delay(1);P0=0x00;//延时一毫秒为了显示得更清楚
	}
void main()
{
		
	while(1){
		Nixie(1,5);
		Nixie(2,2);
		Nixie(3,0);
		Nixie(4,1);
		Nixie(5,3);
		Nixie(6,1);
		Nixie(7,4);
		Nixie(8,0);
	}


}

以上图片采自普中单片机原理图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BOKUSAIQ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值