请教c51单片机,c语言编程,关于指示灯定时闪烁的

P1.0 P1.1 P1.2 P1.3上面各接有一个指示灯,P2.0接一个外接按键
现在要求
按一下按键P1.0以1Hz的频率闪烁
第二次按下按键P1.1以2Hz的频率闪烁
第三次按下按键P1.2以3Hz的频率闪烁
第四次按下按键P1.3以4Hz的频率闪烁
第五次按下按键P1.0以1Hz的频率闪烁
…………如此循环
假设单片机外接6MHz晶振,则单片机的机器周期为12/6M秒
请教各位,如何写这个程序?
对于定时和中断不是很熟悉,大家帮帮忙吧
请注意,是按第一次第一个灯闪,按第二次第二个灯闪,按第三次第三个灯闪……,不是一次按好几下。

用定时中断控制闪烁。

时间间隔则由主程序,根据按键次数来变更。 

程序可见:

http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/blog/item/d92cc98651bfef3bc75cc387.html

仿真实验截图如下:

温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-12-18
这个是串行通信用的时钟,就是SPI通信。这个引脚是接单片机的I/O的。
你既然知道CLK=0,哪你应该是有样例程序的。仔细看看程序。它在一个时间段内是CLK = 0;还有的时候是CLK = 1的。这是因为51单片机并没有SPI通信模块,所以要用普通的IO口接这个CLK段做模拟SPI通信。
好好看看程序。当CLK置零的时候程序下面有一定的操作,而当CLK为1的时候,又有其他的操作。
这样说你是不太明白的,好好看看SPI串行通信的协议把。
另外,就算接外部时钟,CLK = 0也不会关闭,因为外部时钟单片机是无法控制的。

补充,就是CLK在程序中不断给0再给1得到的。你仔细看一下程序,就可以看出他的时序来了。做单片机通信,时序最重要。本回答被网友采纳
第2个回答  2010-12-19
用定时器最好了;
在while(1){P2.0按下的次数}
定期那{switch(P2.0按下的次数)
定时输出高低电平就可以了;
}
定时器赋初值是放在中断最前面...
这样输出的误差最小......
那闪烁则跟高低电平一样就可以了...
第3个回答  2010-12-19
#include<reg51.h>
#define uint unsigned int
sbit d1=P0^0; //位声明
sbit d2=P0^1;
sbit d3=P0^2;
sbit d4=P0^3;
uint temp,num=0;
uint a;
//void chushihua();
void delay(uint z); //延时子函数
void main()
{
//chushihua();
while(1)
{
P1=0xef; //向P1口赋值
temp=P1; //读P1口的数
temp=temp&0x0f;
if(temp!=0x0f)
delay(100);
if(temp!=0x0f) //判断是否有键按下
{
num++;
if(num==5)
num=1;
if(temp==0xef)
delay(100);
if(temp==0xef) //判断按键是否松开
break;
}
if(num==1)
{
d4=1;
d2=1;
d3=1;
d1=~d1;
delay(50);
}
if(num==2)
{
d1=1;
d3=1;
d4=1;
d2=~d2;
delay(100);
}
if(num==3)
{
d1=1;
d2=1;
d4=1;
d3=~d3;
delay(150);
}
if(num==4)
{
d1=1;
d2=1;
d3=1;
d4=~d4;
delay(300);
}
}
}

/*void chushihua()
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
}*/

/*void init0() interrupt 1
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
a++;
}*/

void delay(uint z)
{
uint x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}
第4个回答  2010-12-17
用一寄存器来计算按健次数,用四个独立子程序分别对四个位进行设置,程序相当简单。