C51实现LED流水灯:完美的DIY电子项目!

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


🐬 目录:

  • 一、背景知识
  • 二、环境搭建
  • 三、点亮一个led灯
  • 四、led灯闪烁
  • 五、led流水灯

  • 🐇 实验所选单片机及结构展示(以普中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);	
    //		}	
    	}		
    }
    

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

    物联沃分享整理
    物联沃-IOTWORD物联网 » C51实现LED流水灯:完美的DIY电子项目!

    发表评论