首先是proteus的仿真图
1、第一种流水灯实现方法,按字操作
延时函数是用烧录软件生成的,用到了_nop_()函数,所以头文件要加上#include <intrins.h> .用别的方法延时也是OK的。
#include <reg51.h>
#include <intrins.h>
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
P1 = 0xFF; //1111 1111 全灭
Delay500ms();
P1 = 0xFE; //1111 1110
Delay500ms();
P1 = 0xFD; //1111 1101
Delay500ms();
P1 = 0xFB; //1111 1011
Delay500ms();
P1 = 0xF7; //1111 0111
Delay500ms();
P1 = 0xEF; //1110 1111
Delay500ms();
P1 = 0xDF; //1101 1111
Delay500ms();
P1 = 0xBF; //1011 1111
Delay500ms();
P1 = 0x7F; //0111 1111
Delay500ms();
}
端口置0为亮,置1为灭
2、按位操作
#include <REGX52.H>
sbit D1 = P1^0;
sbit D2 = P1^1;
sbit D3 = P1^2;
sbit D4 = P1^3;
sbit D5 = P1^4;
sbit D6 = P1^5;
sbit D7 = P1^6;
sbit D8 = P1^7;
void delayms(unsigned int x)
{
unsigned char i;
while(x--)
{
for(i = 0;i <113;i++);
}
}
void main()
{
while(1){
D1 = 0; //P1^0
delayms(500);
D1 = 1;
D2 = 0;
delayms(500);
D2 = 1;
D3 = 0;
delayms(500);
D3 = 1;
D4 = 0;
delayms(500);
D4 = 1;
D5 = 0;
delayms(500);
D5 = 1;
D6 = 0;
delayms(500);
D6 = 1;
D7 = 0;
delayms(500);
D7 = 1;
D8 = 0;
delayms(500);
D8 = 1;
}
}
3、数组
void delayms(unsigned int x)
{
unsigned char i;
while(x--)
{
for(i = 0;i <113;i++);
}
}
void main()
{
unsigned char i;
while(1){
for(i = 0;i < 9;i++)
{
P1 = table[i];
delayms(500);
}
}
}
4、位移
#include <REGX52.H>
#include <intrins.h>
void Delayms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char k;
k = 0xFE; // 1111 1110
while(1)
{
P1 = k;
k = _crol_(k,1); //字符循环左移
Delayms(500);
}
}
要解决的一个问题是确定延时时间的精度
时钟周期 = 1/晶振频率
状态周期 = 2时钟周期
机器周期 = 6状态周期 = 12*时钟周期
要生成准确的延时函数可以直接用烧录软件根据晶振生成
C51的晶振频率是11.0592MHz
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
也可以生成1ms的延时函数,然后进行修改
void Delayms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
要记得加入头文件#include <intrins.h>
crol 字符循环左移
cror 字符循环右移
irol 整数循环左移
iror 整数循环右移
lrol 长整数循环左移
lror 长整数循环右移
nop 空操作 (相当于8051 NOP 指令)
testbit 测试并清零位 (相当于8051 JBC 指令)