51单片机__LED相关

51单片机__LED相关

单片机介绍

单片机,英文Micro Controller Unit,简称MCU

内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能

单片机的任务是信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(例如电机,LED等)的控制

单片机跟计算机相比,单片机算是一个袖珍版计算机,一个芯片就能构成完整的计算机系统。但在性能上,与计算机相差甚远,但单片机成本低、体积小、结构简单,在生活和工业控制领域大有所用

同时,学习使用单片机是了解计算机原理与结构的最佳选择

单片机应用

单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词------"智能型",如智能型洗衣机等。

STC89C52单片机

开发板原理图和复位单路

创建工程并实现LED控制

1)点亮LED灯

观察原理图,LED灯低电平点亮,下面开始编写代码:

c 复制代码
#include <REGX52.H>

void main()
{
	P2 = 0;
}

// 现象:所有LED灯均被点亮

2)实现LED_1灯闪烁

延时方法与实现:

通过单片机驱动外围显示电路,为了能够让人眼识别到所显示内容的变化,需要保证所显示的内容有所停留。在单片机中,实现这一效果有两种方式,一种是通过C语言编写一段延时效果的程序或者子程序,实现该目的。另一种是调用单片机自带的定式/计数器,这里暂时使用第一种方式。

使用单片机烧录软件AiCube-ISP-v6.96A,生成一段500ms的延时函数。

c 复制代码
// 延时500ms
void Delay500ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
c 复制代码
#include <REGX52.H>
#include <INTRINS.H>  // 解决 _nop_ 报错

// 延时500ms
void Delay500ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	while(1)
	{	
		P2 = 0xFE;     // 1111 1110
		Delay500ms();  // 延时0.5s
		P2 = 0xFF;     // 1111 1111
		Delay500ms();  // 延时0.5s
	}
}

// 现象: LED_1 闪烁,其他LED灯不亮

3)实现LED流水灯

第一种方式:使用数组实现流水灯效果

c 复制代码
#include <REGX52.H>
#include <INTRINS.H>  // 解决 _nop_ 报错


// 延时500ms
void Delay500ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

// 定义流水灯数组
unsigned char LedCode[] = {0xFE,0xFD,0xFB,0xF7,0Xef,0xDF,0xBF,0x7F};

void main()
{
	unsigned char i;
	while(1)
	{	
		for(i = 0;i < 8;i ++)
		{
			P2 = LedCode[i];
			Delay500ms();
		}
	}
}

// 现象:LED灯从低到高依次点亮

//附加内容:
//0xFE  1111 1110
//0xFD  1111 1101
//0xFB  1111 1011
//0xF7  1111 0111
//0Xef  1110 1111
//0xDF  1101 1111
//0xBF  1011 1111
//0x7F  0111 1111

第二种方式:左右移运算符实现

c 复制代码
#include <REGX52.H>
#include <INTRINS.H>  // 解决 _nop_ 报错


// 延时500ms
void Delay500ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main() {
    unsigned char Led = 0x01; // 0000 0001
    
    while(1) {
        P2 = ~Led;      // 取反,输出到P2端口
        Delay500ms();   // 延时500ms
        
        // 使用左移运算符
        Led = Led << 1;
        
        // 如果移到最右边,重新从最左边开始
        if(Led == 0x00) {
            Led = 0x01;
        }
    }
}

// 现象:LED灯从低到高依次点亮

第三种方式:循环左右移函数的调用

1. cror() - 循环右移函数

头文件: #include <intrins.h>
原型: unsigned char _cror_(unsigned char val, unsigned char n);

功能: 将 8 位数据循环右移 n 位,移出的位从左边补入

示例:

c 复制代码
unsigned char data = 0x81;  // 二进制:10000001
data = _cror_(data, 1);     // 结果:0xC0 (11000000)
// 原:10000001 → 右移1位 → 11000000

2. crol() - 循环左移函数

头文件: #include <intrins.h>
原型: unsigned char _crol_(unsigned char val, unsigned char n);

功能: 将 8 位数据循环左移 n 位,移出的位从右边补入

示例:

c 复制代码
unsigned char data = 0x81;  // 二进制:10000001
data = _crol_(data, 1);     // 结果:0x03 (00000011)
// 原:10000001 → 左移1位 → 00000011

流水灯应用示例:

c 复制代码
#include <REGX52.H>
#include <INTRINS.H>  // 解决 _nop_ 报错


// 延时500ms
void Delay500ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main() 
	{
		unsigned char aa;
		aa = 0xFE;  // 1111 1110
		
		while(1)
		{
			P2 = aa;
			Delay500ms();
			aa = _crol_(aa,1);  // 循环左移函数
		}

	}

// 现象:LED灯从低到高依次点亮

注意: 这两个函数是 C51 编译器特有,仅适用于 51 单片机开发。

综合练习:双向流水灯

c 复制代码
#include <REGX52.H>
#include <INTRINS.H>  // 包含移位函数头文件

// 延时500ms
void Delay500ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main() 
{
    unsigned char aa;
    unsigned char direction = 0;  // 0:左移, 1:右移
    unsigned char counter = 0;    // 计数左移/右移的次数
    
    aa = 0xFE;  // 1111 1110,第一个灯亮
    
    while(1)
    {
        P2 = aa;
        Delay500ms();
        
        // 左移8次后改为右移
        if(direction == 0)
        {
            aa = _crol_(aa, 1);  // 循环左移
            counter++;
            
            if(counter >= 7)  // 左移7次后(共8个状态)
            {
                direction = 1;  // 改为右移方向
                counter = 0;    // 计数器清零
            }
        }
        // 右移8次后改为左移
        else
        {
            aa = _cror_(aa, 1);  // 循环右移
            counter++;
            
            if(counter >= 7)  // 右移7次后(共8个状态)
            {
                direction = 0;  // 改为左移方向
                counter = 0;    // 计数器清零
            }
        }
    }
}

// 现象:LED左右依次点亮
相关推荐
代码游侠5 小时前
ARM开发——阶段问题综述(二)
运维·arm开发·笔记·单片机·嵌入式硬件·学习
DLGXY6 小时前
STM32——旋转编码器计次(七)
stm32·单片机·嵌入式硬件
羽获飞6 小时前
从零开始学嵌入式之STM32——3.使用寄存器点亮一盏LED灯
单片机·嵌入式硬件
浩子智控7 小时前
商业航天计算机抗辐射设计
单片机·嵌入式硬件
独处东汉11 小时前
freertos开发空气检测仪之输入子系统结构体设计
数据结构·人工智能·stm32·单片机·嵌入式硬件·算法
czy878747511 小时前
机智云 MCU OTA可以对MCU程序进行无线远程升级。
单片机·嵌入式硬件
麦托团子12 小时前
51单片机学习笔记17-红外遥控(外部中断)
51单片机
A9better13 小时前
嵌入式开发学习日志52——二值与计数信号量
单片机·嵌入式硬件·学习
日更嵌入式的打工仔14 小时前
(实用向)中断服务程序(ISR)的优化方向
笔记·单片机
想放学的刺客15 小时前
单片机嵌入式试题(第25)嵌入式系统可靠性设计与外设驱动异常处理
stm32·单片机·嵌入式硬件·mcu·物联网