基于C51实现led流水灯
时间:2023-09-08 13:07:02
?? 本实验以前言为基础STC89C52RC51单片机芯片集成,根据电路原理图点亮led同时实现灯led灯的马灯效果。由于51系列单片机的结构相似,读者可以根据博客从一个例子中得出推论,以实现所需的功能。
?? 目录:
- 一、背景知识
- 二、环境建设
- 三、点亮一个led灯
- 四、led灯闪烁
- 五、led流水灯
?? 实验中选择的单片机和结构展示(以普中为基础)C以51为例,其他类似),本实验所操作led模块位于图中⑤位置
?? 实验效果
一、背景知识
?? 单片机:是一种集成电路芯片,是一种具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM等功能集成到一个小而完美的微型计算机系统,由硅片组成
?? 要使系统正常运行,必须保证单片机最小系统的稳定运行。 单片机的最 小系统由以下部分组成: (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)、D连接到单片机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 系列单片机内的所有功能 其中sbit
、sfr
为C51扩展数据类型。C51扩展数据类型如下:
ssfr P2 = 0xA0;
声明8位特殊功能寄存器的起始地址为0xA0
sbit LED1 = P2^0
P一个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" typedf 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<