单片机入门实验——点灯

目录

[4.点亮 LED 灯](#4.点亮 LED 灯)

[4.1 认识 LED 灯](#4.1 认识 LED 灯)

[4.2 寄存器](#4.2 寄存器)

[4.2.1 寄存器原理](#4.2.1 寄存器原理)

[4.2.2 存储数据](#4.2.2 存储数据)

[4.3 数据类型](#4.3 数据类型)

[4.4 LED 灯实验](#4.4 LED 灯实验)

[4.4.1 点亮一个 LED 灯](#4.4.1 点亮一个 LED 灯)

[4.4.2 LED 灯闪烁](#4.4.2 LED 灯闪烁)

[4.4.3 LED 流水灯](#4.4.3 LED 流水灯)


4.点亮 LED 灯
4.1 认识 LED 灯

发光二极管:单向导电性。电流大小一般控制在3-20 mA;

电流较大时,会在发光二极管引脚串接电阻,限制电流,该电阻又被称为限流电阻 ;

一般有直插式、贴片式两种方式;

观察下实物图,对比上左图:

上图 PR9,PR10 指并联后的四个 LED 灯电阻,即 下图的 PR9,PR10

102即电阻:1000 欧;

该电阻表示方式:如 321:320 欧;573:57 000 欧;

4.2 寄存器
4.2.1 寄存器原理

任何单片机,内部都有寄存器,用来存储数据和控制器件。

51单片机是一种广泛使用的微控制器,它包含了一系列的寄存器,用于存储和控制数据

cpu 通过配置寄存器来控制硬件电路进而完成执行的功能

【采用寄存器,可以减少 CPU 访问内存的次数,从而提高CPU的工作速度】

【CPU访问寄存器所用的时间要比访问内存的时间短】

4.2.2 存储数据

学习单片机,本质上就是在学习它的寄存器

单片机中所有数据都是 二进制 形式存储和传送的。 写程序时可以是十进制 十六进制 二进制。

可是,如果我们直接使用二进制表示,程序会直接认为其为十进制,进而传送数据错误

如下:会将二进制 1111 1110 误认为是 十进制: 111,111,110

所以我们在编程时,使用十六进制

TTL 信号规定,+5V 等价于逻辑 "1",0V 等价于逻辑 "0"(采用二进制来表示数据时)。

单片机通电,默认其为高电平,即 "1";

单片机的寄存器被放到内部特定的地址空间,并被命名,这个命名文件就叫做单片机的头文件

4.3 数据类型

C51数据类型:

4.4 LED 灯实验
4.4.1 点亮一个 LED 灯

单片机只要上电,就会一直工作,不会停下来

当主函数执行完之后,又会从头开始执行

类似于"一直开灯"的状态

我们一般将核心代码写入一个 while 死循环中

4.4.2 LED 灯闪烁

在 STC-ISP 中生成一个延时函数:

复制到 Keil 中:

根据需求输入不同的实参进而控制灯亮与灭的时间;

cpp 复制代码
#include <at89c51RC2.h>
#include <intrins.h>

//点亮一个 LED 灯
//void main()
//{
//	while(1)
//	{
//		P2 = 0xFE //1111 1110
//	}
//}


//LED 灯闪烁
void Delayms(int xms)	//@11.0592MHz
{
	unsigned char data i, j;
	
	while(xms--)
	{
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}



void main()
{
	while(1)
	{
		P2 = 0xFE;
		Delayms(8000);
		P2 = 0xFF;
		Delayms(1000);
	}
}
4.4.3 LED 流水灯

实现 8 个 LED 灯轮流点亮的效果;

方案一:

简单易懂,但稍嫌麻烦,不够精简;

cpp 复制代码
#include <at89c51RC2.h>
#include <intrins.h>
//LED 流水灯实验

sbit led1 = P2^0;
sbit led2 = P2^1;
sbit led3 = P2^2;
sbit led4 = P2^3;
sbit led5 = P2^4;
sbit led6 = P2^5;
sbit led7 = P2^6;
sbit led8 = P2^7;

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

void main()
{
	while(1)
	{
		//LED灯的阳极引脚连接电源VCC,阴极引脚为P2^0-P2^7,故赋值 0 即可使其发光
		led1 = 0;
		Delay1ms(1000);
		led1 = 1;
		led2 = 0;
		Delay1ms(1000);
		led2 = 1;
		led3 = 0;
		Delay1ms(1000);
		led3 = 1;
		led4 = 0;
		Delay1ms(1000);
		led4 = 1;
		led5 = 0;
		Delay1ms(1000);
		led5 = 1;
		led6 = 0;
		Delay1ms(1000);
		led6 = 1;
		led7 = 0;
		Delay1ms(1000);
		led7 = 1;
		led8 = 0;
		Delay1ms(1000);
		led8 = 1;
	}
}

方案二:

利用 左移运算符;

cpp 复制代码
#include <at89c51RC2.h>
#include <intrins.h>

// 延时函数(原代码不变)
void Delay1ms(unsigned int ms)	//@11.0592MHz
{
	unsigned char data i, j;
	while(ms--)
	{
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

void main()
{	
	//所有51单片机的局部变量,都建议在函数开头集中定义
	unsigned char i;
	while(1)
	{
		P2 = 0x01;	//0xfe = 0000 0001
		for(i=0;i<8;i++)
		{
			Delay1ms(500);   // 延时500ms
			//P2 = 0xfe<<i;	 //这样不符合流水灯的要求:该灯亮起并熄灭后,下一个灯又亮起并熄灭,如此循环;

			P2 = ~(0x01<<i);
		}
	}
}

方案三:

使用 crol( )------循环左移函数,_cror_是循环右移,后面写上变量的名称、移动的位数

常见于流水灯等编程中;

cpp 复制代码
#include <at89c51RC2.h>
#include <intrins.h>

// 延时函数(原代码不变)
void Delay1ms(unsigned int ms)	//@11.0592MHz
{
	unsigned char data i, j;
	while(ms--)
	{
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

void main()
{	
	//所有51单片机的局部变量,都建议在函数开头集中定义
	unsigned char i;
	while(1)
	{
		P2 = 0xfe;	//0xfe = 1111 1110
		for(i=0;i<=8;i++)
		{
			Delay1ms(500);   // 延时500ms
			P2 = _crol_(0xfe,i);
		}
	}
}
复制代码
相关推荐
代码游侠3 小时前
ARM开发——阶段问题综述(二)
运维·arm开发·笔记·单片机·嵌入式硬件·学习
DLGXY3 小时前
STM32——旋转编码器计次(七)
stm32·单片机·嵌入式硬件
羽获飞3 小时前
从零开始学嵌入式之STM32——3.使用寄存器点亮一盏LED灯
单片机·嵌入式硬件
浩子智控4 小时前
商业航天计算机抗辐射设计
单片机·嵌入式硬件
独处东汉8 小时前
freertos开发空气检测仪之输入子系统结构体设计
数据结构·人工智能·stm32·单片机·嵌入式硬件·算法
czy87874758 小时前
机智云 MCU OTA可以对MCU程序进行无线远程升级。
单片机·嵌入式硬件
A9better10 小时前
嵌入式开发学习日志52——二值与计数信号量
单片机·嵌入式硬件·学习
日更嵌入式的打工仔12 小时前
(实用向)中断服务程序(ISR)的优化方向
笔记·单片机
想放学的刺客13 小时前
单片机嵌入式试题(第25)嵌入式系统可靠性设计与外设驱动异常处理
stm32·单片机·嵌入式硬件·mcu·物联网
wotaifuzao13 小时前
STM32+FreeRTOS 长期可维护架构设计(事件驱动篇)-- 告别“屎山”代码
c语言·stm32·嵌入式硬件·freertos·状态机·事件驱动·嵌入式架构