51单片机独立按键扫描程序出现问题
sbit SW1 = P1^2;
sbit SW2 = P1^3;
sbit SW3 = P1^4;
sbit SW4 = P1^5;
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
unsigned char SWSTA[4] = {1,1,1,1};
unsigned char backup[4] = {1,1,1,1};
void main()
{ static unsigned char i=0,j=0;
unsigned char cnt = 0;
EA = 1;
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x67;
ET0 = 1;
TR0 = 1;
while (1)
{
for (i=0;i<4;i++)
{
if (backup[i] != SWSTA[i])
{
backup[i] = SWSTA[i];
}
}
}
if ( SWSTA[0] == 0 )
{
P0 = ~(0x01 <<j);
if ( TF0 == 1 )
{
TF0 = 0;
TH0 = 0xFC;
TL0 = 0x67;
cnt++;
}
if (cnt >= 100)
{
cnt = 0;
}
j++ ;
if(j>=3)
{
j = 0;
}
}
if (SWSTA[1] == 0 )
{
LED1 = 0;
}
if (SWSTA[2] == 0 )
{
LED2 = 0;
}
if (SWSTA[3] == 0 )
{
LED3 = 0;
}
}
void interrupTimer()interrupt 1
{static unsigned char i=0;
static unsigned char SWOUT = 0;
TH0 = 0xFC;
TL0 = 0x67;
for ( i=0;i<4;i++ )
{
if(SWSTA[i] & 0x0F == 0x00)
{
SWSTA[i] = 0;
}
else if(SWSTA[i] & 0x0F == 0x0F)
{
SWSTA[i] = 1;
}
}
SWOUT++;
SWOUT = SWOUT & 0x03;
}
还有,我尝试着直接把按键上的状态给LED灯,按键没按下之前是高位状态,按下后是低位状态,把地位状态的值给LED,按说是应该亮的,但就是不亮,我现在也搞不清楚了。
#include <reg52.h>
sbit SW1 = P1^2;
sbit SW2 = P1^3;
sbit SW3 = P1^4;
sbit SW4 = P1^5;
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
void main()
{
while(1)
{ LED1 = SW1; //按下时为0,对应的LED点亮
LED2 = SW2;
LED3 = SW3; }
}
这个直接控制按键来控制LED亮灭,假入我把while语句里面的改为
if(SW1==0)
{LED1=0;}
else
{LED1=1;}
这样改过后,按下按键1,LED1就亮,不按就不亮,但是改成第二段程序就不亮。
请教下大家,第一个程序的按键扫描与消抖该如何处理,第二个程序我是哪里出错了。
已经弄好了程序,但是现在出现个问题?怎么跳出while(1)循环语句。如果我按下SW1,它一直在执行while(1)循环语句,按其他按键也没反应,如果是按SW2,SW3,SW4,都会执行相应语句,唯有一按SW1,它就执行while(1)循环语句,怎么都挑不出来。
#include <reg52.h>
sbit SW1 = P1^2;
sbit SW2 = P1^3;
sbit SW3 = P1^4;
sbit SW4 = P1^5;
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
unsigned char keyscan(void);
void delayus2x(unsigned char t);
void delayma(unsigned char t);
void main()
{ unsigned char num;
unsigned int cnt=0;
unsigned int i=0;
unsigned char m;
while(1)
{
num = keyscan();//循环扫描按键
if (num==1)
{
while(1)
{
P0 = ~(0x01 <<cnt);
delayma(10);
cnt++;
if(cnt>=3)
{
cnt = 0;
}
}
}
else if (num==2)
{ m=1;
P0=0x06;
}
else if (num==3)
{
P0=0x05;
}
else if (num==4)
{
P0=0x03;
}
}
}
void delayus2x(unsigned char t)//软件延时,大致的,不够精确,可以用中断延时
{while(--t) ;
}
void delayma(unsigned char t)
{
while(t--)
{
//大致延时1ms
delayus2x(245);
delayus2x(245);
}
}
unsigned char keyscan(void) //按键扫描消抖
{
if(!SW1)//如果按键值为非
{
delayma(10);//延时10秒 去抖
if(!SW1)
{
while(!SW1) //如果确认按下按键等待释放,没有一直等待
{
}
return 1; //返回值num=1
}
}
if(!SW2)
{
delayma(10);
if(!SW2)
{
while(!SW2)
{
}
return 2;
}
}
if(!SW3)
{
delayma(10);
if(!SW3)
{
while(!SW3)
{
}
return 3;
}
}
if(!SW4)
{
delayma(10);
if(!SW4)
{
while(!SW4)
{
}
return 4;
}
}
return 0;
}
程序没完呀,头文件没包含呀。
看来一下图,P0口应该是上啦呀!就是接Vcc
上拉不行,试过了,价格上拉电阻,就变成了2端都是高电压,下拉电阻刚好。
具体是什么问题?而且程序能弄完整吗
支持一下
不错的资料
现在主要就是独立按键循环扫描的程序自己搞不清,不过刚又研究了一会,又尝试自己自己写了下,打算晚上试试,程序还没有写完,还要接着改。谢谢关心。
我感觉我快疯了,这个程序早上运行正常,流水灯正常,现在再测就不行了,大家帮我看看哪里不对。
#include <reg52.h>
sbit SW1 = P1^2;
sbit SW2 = P1^3;
sbit SW3 = P1^4;
sbit SW4 = P1^5;
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
void main ()
{ unsigned char cnt = 0;
unsigned int i=0;
while(SW1==0)
{
P0 = ~(0x01 <<cnt); //循环测试正确,流水灯正确
for(i=0; i<30000; i++);
cnt++;
if(cnt>=3)
{
cnt = 0;
}
}
}
我是来打酱油的,学习学习
//其实这个实验可以用1个按键就可以解决问题了
//有问题加qq:1334577922备注一下“夜孤影”
#include"reg51.h"
#define uint unsigned int
#define uchar unsigned char
sfr P1M0=0x92;
sfr P1M1=0x91;
sfr P2M0=0x96;
sfr P2M1=0x95;
sbit SW1 = P2^0;
//sbit SW2 = P1^3;
//sbit SW3 = P1^4;
//sbit SW4 = P1^5;
sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit LED3 = P1^2;
void delay(uint time)
{
uchar i;
for(;time>0;time--)
{
for(i=0;i<125;i++);
}
}
void liushuideng(void)
{
LED1 =0;
delay(1000);
LED2 =0;
delay(1000);
LED3 =0;
delay(1000);
LED1 =1;
delay(1000);
LED2 =1;
delay(1000);
LED3 =1;
delay(1000);
}
void main()
{
unsigned char j;
P1M0=0xff;
P1M1=0;
P2M0=0xff;
P2M1=0;
while(1)
{
if(SW1 == 0)
{
delay(200);
if(SW1 == 0)
{
j++;
if(j==5)j=1;
}
}
if(j==1)
{
liushuideng();
delay(1000);
delay(1000);
}
if(j==2)
{
LED1=0;
LED2=1;
LED3=1;
delay(1000);
delay(1000);
}
if(j==3)
{
LED1=1;
LED2=0;
LED3=1;
delay(1000);
delay(1000);
}
if(j==4)
{
LED3=0;
LED1=1;
LED2=1;
delay(1000);
delay(1000);
}
}
}
表示你这不是流水灯,你这是按一下,3个灯依次亮一下。跟我的不太一样。
可以同过延时解决那个问题,并不是3个灯依次亮一下,而是循环点亮
我试过了,把延时时间加大,就差不多可以了
,刚试过了确实是流水灯,但是在我的单片机电路里好像做不出来我要的效果,我决定把四个按键都做成呼吸灯的效果,不要流水灯了,通过PWM来实现。我先试试。
if(num == 1)
{
switch(status1) // #define status1 0
{
case 0:
P0 = ~(0x01 <<cnt);
DelayTime++
while(DelayTime >= const_time_level) //#define const_time_level 1000 延时时间到
{
status1 = 1;
DelayTime = 0;
}
break;
case 1:
cnt++;
if(cnt > 3)
{
cnt = 0;
}
break;
defualt:
break;
}
}
参考 http://bbs.elecfans.com/jishu_406259_1_1.html
swith并行任务处理
哦哦,第一次看到谢谢,我去收藏下。
第二个问题应该是你没有理解好编译器的问题,你的那种写法不规范,编译器应该没有人那么智能,所以,那种写法通过C编译器编译后,就不能实现你想要的功能了。
你说的我知道了,所以我推到了我的写法,重新写了程序,在9楼可以看到,但是后来又出现了无法跳出while(1)的问题。谢谢指点。