建议先看:
《8051单片机实战分析(以STC89C52RC为例) | 01 - 点亮一个LED》
《8051单片机实战分析(以STC89C52RC为例) | 02 - LED延时约5s闪烁》
我们从这些基础上修改代码。
1 原理图
从图中不难看出,整个P2端口都接有LED,写代码时需要驱动整个P2端口。


2 代码
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include <intrins.h> //因为要用到左右移函数,所以加入这个头文件
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
#define led P2 //将P2口定义为led 后面就可以使用led代替P2口
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
u8 i;
led=0xfe;
delay(50000); //大约延时450ms
while(1)
{
for(i=0;i<7;i++) //将led左移一位
{
led=_crol_(led,1);
delay(50000); //大约延时450ms
}
for(i=0;i<7;i++) //将led右移一位
{
led=_cror_(led,1);
delay(50000); //大约延时450ms
}
}
}
简要分析:
- 使用宏定义
#define 定义 led 为 P2,这样我们可以使用led替换P2进行使用。 - 开始执行
main 函数的时候,led=0xfe; 首先点亮一个灯,0xfe用二进制表示就是0x11111110,二进制数中的每一位表示P2中某个端口的电平,此处就是表示P2.0端口为0,即低电平,从而点亮P2.0端口的LED。 - 进入大循环
while(1)后有两个 for 循环,从 i=0 跑到 i=7 ,使用 _crol_ 函数进行左移操作,例如第一次左移是从0x11111110变成0x11111101,这样P2.0端口的LED就会熄灭,P2.1端口的LED就会点亮;同理使用 _cror_ 函数进行右移操作,在左移7次后,P2.7端口的LED是点亮的,即0x01111111,在进行第一次右移的时候,从0x01111111变成0x10111111,这样P2.7端口的LED就会熄灭,P2.6端口的LED就会点亮,如此往返就行实现流水灯。










