51单片机16路流水灯怎么用C语言写,并求每个步骤的讲解

本人单片机初学者

我给你个简单的例子:

#include <AT89X51.H> //预处理文件里面定义了特殊寄存器的名称如P1 口定义为P1

void main(void)

{

//定义花样数据

const unsigned char design[32]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,

0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,

0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x0,

0xE7,0xDB,0xBD,0x7E,0xFF};

unsigned int a; //定义循环用的变量

unsigned char b; //在C51 编程中因内存有限尽可能注意变量类型的使用

//尽可能使用少字节的类型,在大型的程序中很

受用

do{

for (b=0; b<32; b++)

{

for(a=0; a<30000; a++); //延时一段时间

P1 = design[b]; //读已定义的花样数据并写花样数据到P1 口

}

}while(1);

}

程序中的花样数据可以自以去定义,因这里我们的LED 要AT89C51 的P1 引脚为低电平才

会点亮,所以我们要向P1 口的各引脚写数据O 对应连接的LED 才会被点亮,P1 口的八个引

脚刚好对应P1 口特殊寄存器的八个二进位,如向P1 口定数据0xFE,转成二进制就是

11111110,最低位D0 为0 这里P1.0 引脚输出低电平,LED1 被点亮。如此类推,大家不难算

出自己想要做的效果了。 

留个邮箱给你发个入门文档

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-10-13
看看这个也许能行
//*******************************************************
#define Byte unsigned char
#define Word unsigned int
#define DWord unsigned long
//*******************************************************
#define Speed 12 //12 MHz(注意更高就不能一次得到50ms定时了)
#define TTTT 50000 //50ms
#define TH1_Init_Val (65536-Speed * TTTT / 12)/256
#define TL1_Init_Val (65536-Speed * TTTT / 12)%256

sbit L1 = P1^0 ;
sbit L2 = P1^1 ;
sbit L3 = P1^2 ;
sbit L4 = P1^3 ;
sbit L5 = P1^4 ;
sbit L6 = P1^5 ;
sbit L7 = P1^6 ;
sbit L8 = P1^7 ;
//*******************************************************模块变量
bit flag1s ;

//*******************************************************T1初始化
void T1_Init()
{
TMOD= 0x11;
TH1=TH1_Init_Val ;
TL1=TL1_Init_Val ;
ET1 =1;
EA =1;
TR1 =1;
}

/*******************************************************LED主进程

第一秒钟L1,L3亮,
第二秒钟L2,L4亮,
第三秒钟L5,L7亮,
第四秒钟L6,L8亮,
第六秒钟L2,L4,L6,L8亮,
第七秒钟八个二极管全亮,
第八秒钟全灭
[可以将P0口各时刻的状态做个表格,这里就不做了]
********************************************************/
void Led_Run()
{
static Byte step;
if (!flag1s)return; //接收定时器“flag1s”消息,没到1s返回
flag1s = 0; //1s到则开始工作

step++;
switch(step) //以1s为间隔进行顺序控制
{
case 1:
P1 =0xff; //先熄灭
L1 = 0;
L3 = 0;
break;
case 2:
P1 =0xff; //先熄灭
L2 = 0;
L4 = 0;
break;
case 3:
P1 =0xff; //先熄灭
L5 = 0;
L7 = 0;
break;
case 4:
P1 =0xff; //先熄灭
L6 = 0;
L8 = 0;
break;
case 5:
//do nothing 维持第4秒内容
break;
case 6:
P1 =0xff; //先熄灭
L2 = 0;
L4 = 0;
L6 = 0;
L8 = 0;
break;
case 7:
P1 = 0x00; //全亮
break;
case 8:
P1 =0xff; //全灭
step = 0; //步骤复位
break;
default:
step = 0; //具有一定的抗干扰意义
break;
}
}
//*******************************************************主程序
void main()
{
T1_Init();
while(1)
{
Led_Run();
}
}

void ISR_T1() interrupt 3 using 2 //定时器1中断服务程序50ms
{
static Byte cnt1s;
TH1=TH1_Init_Val ;
TL1=TL1_Init_Val ; //reload val
if (++cnt1s >= 20)
{
cnt1s = 0;
flag1s = 1;
}
}
第2个回答  2011-10-12
这个没有0实验板原理图,没法写哈。
大概就是先定义一下管脚,再向管脚写ff或00初始化。再把第一个灯点亮,再关掉第一个灯,再点亮第二个灯。。。 。。。把它放在do循环里就OK了,
熟练了后,加个for循环简化一下程序,设几个变量就行了。
第3个回答  2011-10-12
#include "reg52.h"
#include "intrins.h"
void Delay(unsigned int t)
{
unsigned i;
while(t--!=0)
{
for(i=0;i<500;i++)
{;}
}
}
void main(void)
{
unsigned char temp,num1,num2;
P0=0xff;
p1=0xff;
while(1)
{
temp=0xfe;
for(num1=0;num1<8;num1++)
{
P0=temp;
p1=0xff;
Delay(100);
temp = _crol_(temp , 1);
}
temp=0x7f;
for(num2=0;num2<8;num2++)
{
P0=temp;
p1=0xff;
Delay(100);
temp =_cror_(temp,1);
}
temp=0xfe;
for(num1=0;num1<8;num1++)
{
P1=temp;
p0=0xff;
Delay(100);
temp = _crol_(temp , 1);
}
temp=0x7f;
for(num2=0;num2<8;num2++)
{
P1=temp;
p0=0xff;
Delay(100);
temp =_cror_(temp,1);
}
}
}
16个二极管分别接到p0口和p1口.....
参考资料:http://zhidao.baidu.com/question/324586572.html