单片机流水灯问题
题目:在P1口接8个发光二极管(高电平或低电平亮都可以),完成流水灯功能。设计一个按键(随便哪个口),开始中间朝二边开花,按一次键松开后由上到下亮,再按松开后由下到上亮,...
题目:在P1口接8个发光二极管(高电平或低电平亮都可以),完成流水灯功能。设计一个按键(随便哪个口),开始中间朝二边开花,按一次键松开后由上到下亮,再按松开后由下到上亮,再按松开后朝二边开花,又再按键松开后朝二边开花,如此循环。形成三种状态,如R1开始为0,按以下键松开后R1加一,加到3又回到零,形成0、1、2三种状态,判别零的值程序到不同的分支)。
我编写的程序:#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key=P3^0;
uint data count;
void delay(){
uint i;
for(i=0;i<32000;i++);
}
void led0(void){
uchar temp=0x18,a,b;
uint i;
P1=temp;
delay();
for(i=0;i<4;i++){
a=(temp&0xf0)<<i;
b=(temp&0x0f)>>i;
P1=a|b; delay();
}
}
void led1(void){
uchar cmd=0x01;
while(1){
P1=cmd;
delay();
if((cmd&0x80)==0x80) cmd=(cmd<<1)+1;
else cmd=cmd<<1;
}
}
void led2(void){
uchar cmd=0x80;
while(1){
P1=cmd;
delay();
if((cmd&0x01)==0x01) cmd=(cmd>>1)+0x80;
else cmd=cmd>>1;
}
}
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
count=count+1;
if(count==3) count=0;
}
while(key==0);
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}
问题:仿真按键转换状态时,第一次按,转为第二种状态,再次按键后,就没反应了,不能转为下一状态,请大侠们指点一下,谢谢!! 展开
我编写的程序:#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key=P3^0;
uint data count;
void delay(){
uint i;
for(i=0;i<32000;i++);
}
void led0(void){
uchar temp=0x18,a,b;
uint i;
P1=temp;
delay();
for(i=0;i<4;i++){
a=(temp&0xf0)<<i;
b=(temp&0x0f)>>i;
P1=a|b; delay();
}
}
void led1(void){
uchar cmd=0x01;
while(1){
P1=cmd;
delay();
if((cmd&0x80)==0x80) cmd=(cmd<<1)+1;
else cmd=cmd<<1;
}
}
void led2(void){
uchar cmd=0x80;
while(1){
P1=cmd;
delay();
if((cmd&0x01)==0x01) cmd=(cmd>>1)+0x80;
else cmd=cmd>>1;
}
}
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
count=count+1;
if(count==3) count=0;
}
while(key==0);
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}
问题:仿真按键转换状态时,第一次按,转为第二种状态,再次按键后,就没反应了,不能转为下一状态,请大侠们指点一下,谢谢!! 展开
4个回答
展开全部
你的问题在与led1()和led2()中有while(1)死循环,程序是不会出来了,可以根据实际要求设定循环次数,但是如果这样 按下的时间会长,因为要执行完for 才能检测到按键。
键盘最好不用P0口,如果要使用必须接上拉电阻
#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key=P3^0;
uint data count;
void delay(){
uint i;
for(i=0;i<32000;i++);
}
void led0(void){
uchar temp=0x18,a,b;
uint i;
P1=temp;
delay();
for(i=0;i<4;i++){
a=(temp&0xf0)<<i;
b=(temp&0x0f)>>i;
P1=a|b; delay();
}
}
void led1(void){
uchar cmd=0x01;
for( )//这里不能用死循环;就像led0()一样,用FOR控制次数,你自己填写吧,不过这样按按键的时间要长。
{
P1=cmd;
delay();
if((cmd&0x80)==0x80) cmd=(cmd<<1)+1;
else cmd=cmd<<1;
}
}
}
void led2(void){
uchar cmd=0x80;
for( )//这里不能用死循环;就像led0()一样,用FOR控制次数,你自己填写吧,不过这样按按键的时间要长。
{
P1=cmd;
delay();
if((cmd&0x01)==0x01) cmd=(cmd>>1)+0x80;
else cmd=cmd>>1;
}
}
}
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
count=count+1;
if(count==3) count=0;
}
while(key==0);
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}
键盘最好不用P0口,如果要使用必须接上拉电阻
#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key=P3^0;
uint data count;
void delay(){
uint i;
for(i=0;i<32000;i++);
}
void led0(void){
uchar temp=0x18,a,b;
uint i;
P1=temp;
delay();
for(i=0;i<4;i++){
a=(temp&0xf0)<<i;
b=(temp&0x0f)>>i;
P1=a|b; delay();
}
}
void led1(void){
uchar cmd=0x01;
for( )//这里不能用死循环;就像led0()一样,用FOR控制次数,你自己填写吧,不过这样按按键的时间要长。
{
P1=cmd;
delay();
if((cmd&0x80)==0x80) cmd=(cmd<<1)+1;
else cmd=cmd<<1;
}
}
}
void led2(void){
uchar cmd=0x80;
for( )//这里不能用死循环;就像led0()一样,用FOR控制次数,你自己填写吧,不过这样按按键的时间要长。
{
P1=cmd;
delay();
if((cmd&0x01)==0x01) cmd=(cmd>>1)+0x80;
else cmd=cmd>>1;
}
}
}
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
count=count+1;
if(count==3) count=0;
}
while(key==0);
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
宿兴电子
2024-11-28 广告
2024-11-28 广告
联系我们一、有无震荡源 无源这里的“源”不是指电源,而是指震荡源。也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。 二、价格不同 有源蜂鸣器往比无源蜂鸣器贵,就是因为里面多个震荡...
点击进入详情页
本回答由宿兴电子提供
展开全部
按键是否接有上啦电阻?松开后不能自动上拉吧。另外你的led1、2函数里面都有while(1){},按理说按键根本就不会有作用,但是你的led0()里面又没有while(1){}所以能从第一状态跳出来,第一次按键后进入led1()后,就无法扫描你的按键程序咯。
呵呵!
给分吧!
呵呵!
给分吧!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
把松手检测放到判断函数内部改成如下程序试一下:
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
while(key==0);
count=count+1;
if(count==3) count=0;
}
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}
void main(void){
count=0;
led0();
while(1){
if(key==0){
delay();
if(key==0){
while(key==0);
count=count+1;
if(count==3) count=0;
}
}
switch(count){
case 0: led0();break;
case 1: led1();break;
case 2: led2();break;
default:;
}
}
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
花样流水灯的玩法,一个51单片机8位端口轮流输出16颗灯珠,
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询