草庐IT

基于C51实现led流水灯

妙乌 2023-09-06 原文

🐋 前言:本实验基于STC89C52RC芯片集成的51单片机,根据电路原理图点亮led灯,同时实现led灯的走马灯效果。由于51系列单片机结构大同小异,读者可根据此博客举一反三,实现所需完成的功能。


🐬 目录:


🐇 实验所选单片机及结构展示(以普中C51为例,其他大同小异),本实验所操作led模块位于图中⑤位置

🐇 实验效果

一、背景知识

🐪 单片机:是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM等功能集成到一块硅片上构成的一个小而完善的微型计算机系统

🐪 若要使系统正常运行,必须确保单片机的最小系统稳定工作。51 单片机的最 小系统由以下几部分组成: (1)晶振电路(晶振电路提供时钟给单片机工作,犹如人的心脏)(2)复位电路 (3)电源电路

🐪 芯片引脚分类:
(1)电源引脚:上图中的VCC、GND都属于电源引脚
(2)晶振引脚:上图中的XTAL1、XTAL@都属于晶振引脚
(3)复位引脚:上图中的RST/VPD属于复位引脚
(4)通信引脚:51单片机串口功能引脚(TXD、RXD)
(5)GPIO引脚:上图中带有Px.x等字样的属于GPIO引脚,共32个,分为4组,每组8个IO
🐺P0 口是漏极开路,要使其输出高电平,必须外接上拉电阻,通常选择 4.7K~10K 阻值。
🐺P0、P1、P2 几乎都用作普通 I/O 口使用,既可作为输入,又可作为输出。
🐺 P3 口既可用作普通 I/O 口,又可作为第二功能使用,比如串口、外部中 断、计数器等。


二、环境搭建(keil4)

新建工程->选择CPU型号(Atmel(AT89C52))->给工程添加文件->配置输出文件hex

三、点亮一个led灯

💌 3.1 查看电路原理图


通过观察开发板的线路连接图可以观察到:
☁️ 1.D1阴极连接到单片机的P2.0引脚(线编号相同表示连接在一起P20)、D2连接到单片机P2.1引脚………
☁️ 2.当单片机P2.0输出低电平0,则与电源连接的D1形成通路,D1灯亮。P2.X输出0,其他灯亦然。
因此,要想使得D1等亮,需要编程并将程序烧录到单片机中,使得P2.0端口输出低电平,

💌 3.2 编写代码并烧录

☁️ 3.2.1 导入reg52.h头文件,预编译时会将头文件中的内容加载到文件中,reg52.h头文件中内容如下:

#ifndef __REG52_H__
#define __REG52_H__

/*  BYTE Registers  */
sfr P0    = 0x80;
sfr P1    = 0x90;
sfr P2    = 0xA0;
sfr P3    = 0xB0;
sfr PSW   = 0xD0;
sfr ACC   = 0xE0;
sfr B     = 0xF0;
sfr SP    = 0x81;
sfr DPL   = 0x82;
sfr DPH   = 0x83;
sfr PCON  = 0x87;
sfr TCON  = 0x88;
sfr TMOD  = 0x89;
sfr TL0   = 0x8A;
sfr TL1   = 0x8B;
sfr TH0   = 0x8C;
sfr TH1   = 0x8D;
sfr IE    = 0xA8;
sfr IP    = 0xB8;
sfr SCON  = 0x98;
sfr SBUF  = 0x99;

/*  8052 Extensions  */
sfr T2CON  = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2    = 0xCC;
sfr TH2    = 0xCD;


/*  BIT Registers  */
/*  PSW  */
sbit CY    = PSW^7;
sbit AC    = PSW^6;
sbit F0    = PSW^5;
sbit RS1   = PSW^4;
sbit RS0   = PSW^3;
sbit OV    = PSW^2;
sbit P     = PSW^0; //8052 only

/*  TCON  */
sbit TF1   = TCON^7;
sbit TR1   = TCON^6;
sbit TF0   = TCON^5;
sbit TR0   = TCON^4;
sbit IE1   = TCON^3;
sbit IT1   = TCON^2;
sbit IE0   = TCON^1;
sbit IT0   = TCON^0;

/*  IE  */
sbit EA    = IE^7;
sbit ET2   = IE^5; //8052 only
sbit ES    = IE^4;
sbit ET1   = IE^3;
sbit EX1   = IE^2;
sbit ET0   = IE^1;
sbit EX0   = IE^0;

/*  IP  */
sbit PT2   = IP^5;
sbit PS    = IP^4;
sbit PT1   = IP^3;
sbit PX1   = IP^2;
sbit PT0   = IP^1;
sbit PX0   = IP^0;

/*  P3  */
sbit RD    = P3^7;
sbit WR    = P3^6;
sbit T1    = P3^5;
sbit T0    = P3^4;
sbit INT1  = P3^3;
sbit INT0  = P3^2;
sbit TXD   = P3^1;
sbit RXD   = P3^0;

/*  SCON  */
sbit SM0   = SCON^7;
sbit SM1   = SCON^6;
sbit SM2   = SCON^5;
sbit REN   = SCON^4;
sbit TB8   = SCON^3;
sbit RB8   = SCON^2;
sbit TI    = SCON^1;
sbit RI    = SCON^0;

/*  P1  */
sbit T2EX  = P1^1; // 8052 only
sbit T2    = P1^0; // 8052 only
             
/*  T2CON  */
sbit TF2    = T2CON^7;
sbit EXF2   = T2CON^6;
sbit RCLK   = T2CON^5;
sbit TCLK   = T2CON^4;
sbit EXEN2  = T2CON^3;
sbit TR2    = T2CON^2;
sbit C_T2   = T2CON^1;
sbit CP_RL2 = T2CON^0;

#endif

从上面代码中可以看到,该头文件中定义了 52 系列单片机内部所有的功能 寄存器。其中sbitsfr为C51扩充数据类型。C51扩充数据类型主要如下:

ssfr P2 = 0xA0;

声明一个8位的特殊功能寄存器,它的起始地址为0xA0

sbit LED1 = P2^0

P2是一个8位寄存器,P2^0表示这个8位寄存器的最低位。该语句的功能就是将P2寄存器的最低位声明为LED1,以后若是要对P2寄存器最低位操作,则可直接操作LED1

☁️ 3.2.2 编写程序
使用while(1)死循环,使得程序一直运行,这样能保证led灯一直亮着。
main.c

#include "reg52.h"

sbit LED1=P2^0;	//将P2.0管脚定义为LED1

void main()
{
	LED1=0;	//将寄存器P2的最低位赋低电平
	while(1)
	{
		
	}		
}

四、实现led灯闪烁

📟 当单片机P2.0引脚输出高电平时,led等两侧无电位差,因此没有电流通过,led灯熄灭。实现程序如下:

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

sbit LED1=P2^0;	//将P2.0管脚定义为LED1

/*******************************************************************************
*函数名      : delay_10us
* 函数功能		 : 延时函数,ten_us=1时,大约延时10us
*******************************************************************************/
void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}

void main()
{	
	while(1)
	{
		LED1=0;	//点亮
		delay_10us(50000); //点亮500ms
		LED1=1;	//熄灭
		delay_10us(50000); 	
	}		
}

五、实现led流水灯

🐙 本实验通过两种方式实现led走马灯效果,一种是通过循环+移位完成对P2寄存器各位轮流赋低电平。第二种是使用intrins,h头文件中定义的外部方法 _crol__cror_分别实现按位的移动

#include "reg52.h"
#include "intrins.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

#define LED_PORT	P2	//使用宏定义P2端口寄存器

/*******************************************************************************
* 函数名:       : delay_10us
* 函数功能		 : 延时函数,ten_us=1时,大约延时10us
*******************************************************************************/
void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}

void main()
{	
   	u8 i=0;

	LED_PORT=~0x01;	//给P2寄存器各位赋值,即给寄存器最低位赋低电平
	delay_10us(50000);
	while(1)
	{
		//方式一:通过移位+循环实现流水灯
				for(i=0;i<8;i++)
		{
			LED_PORT=~(0x01<<i);	//给P2寄存器最低位到最高位依次赋低电平,循环8次后继续循环
			delay_10us(50000);
		}
		
		//方式2:使用循环+_crol_或_cror_函数实现流水灯
//		for(i=0;i<7;i++)	 //将led左移一位
//		{									  
//			LED_PORT=_crol_(LED_PORT,1);
//			delay_10us(50000); 	
//		}
//		for(i=0;i<7;i++)	//将led右移一位
//		{
//			LED_PORT=_cror_(LED_PORT,1);
//			delay_10us(50000);	
//		}	
	}		
}

感谢观看,如对内容有疑惑或补充,欢迎留言讨论,共同进步!!!

有关基于C51实现led流水灯的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  3. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  6. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  7. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  8. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  9. ruby - Arrays Sets 和 SortedSets 在 Ruby 中是如何实现的 - 2

    通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复

  10. ruby - "public/protected/private"方法是如何实现的,我该如何模拟它? - 2

    在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定

随机推荐