任务:
基本要求:
摁键流水灯,上电后LED不亮,摁下s1,LED从d1亮到d8,摁下S5,停下来。再次摁一下S1,从上次停下来的地方继续向原来方向闪烁
看来仅需要 矩阵按键的库啊
不过首先我需要写流水灯;
首先我是这么想的
for(int i=0;i<8;i++)
{
P2=~(0x01<<i);
Delay(500);
}
这时我意识到了一个问题:这样子的流水灯是“一次性”的,我无法重新流一遍,那么自然而然想到了无限循环的while(1),于是天坑来了;
int i=0;
while(i++)
{
P2=~(0x01<<(i-1));
Delay(500);
if(i==8)
{
i=0;
}
}
这里有两个问题:
1.当i=0时,while里面i先给while其值=0再自增,直接跳出。
所以我又改进了一下:
int i=0;
while(++i)
{
P2=~(0x01<<(i-1));
Delay(500);
if(i==8)
{
i=0;
}
}
好!噩梦开始!
while死循环跳不出去!!!
最后是这样解决的:
while(++i)
{
if(MatrixKey()==5)
{
while(1)
{
if(MatrixKey()==1)
goto T;
}
}
T: P2=~(0x01<<(i-1));
while(k--);
if(i==9)
{
i=0;
}
}
由题当s5按下时暂停,所有我不得不用了goto。目前来看成功了。
总代码:
#include <regx52.h>
#include "MatrixKey.h"
int count=0;
int moshi=0;
void main () {
int k=2500;
int i;
int j=100;
while(1){
if(MatrixKey()==1)
{
while(++i)
{
if(MatrixKey()==5)
{
while(1)
{
if(MatrixKey()==1)
goto T;
}
}
T: P2=~(0x01<<(i-1));
while(k--);
if(i==9)
{
i=0;
}
}
}
}
}
但是还是有两个问题:
1.我不想用goto
2.s5按下时间要长才能成功。
如果不用定时器,要在按键按下后用Delay函数进行软件消抖,还要用while(P1_7==0)来判断是否松手,如果长期不松手,则CPU会卡在该死循环里,不能执行其他代码,造成某些功能代码失效。
于是我想到了定时器扫描按键:(一开始没用,这个是错的,我当时并没有意识到)
void time_routine() interrupt 1{
TH0=0xFC;
TL0=0x18;
count++;
if(count==20)
{
t=MatrixKey();
}
}
在主函数中进行判断那一个键
再想着
定时器中断里面加入变量j,j++; 定时器是循环往复的,而且不被while框死
并将LED移动用if(j>500)括起来
这样当j=500时 让j=0,完成一个循环 这样就能延时了
这样是没有问题的。算是成功了(并未用扫描,先解决的如何不被while卡死)
#include <regx52.h>
#include "MatrixKey.h"
int t;
int k=2500;
int j=0;
int moshi=4;
int count=0;
int b=0;
int i=0;
void time_init()
{
TMOD=0x01;
TF0=0;
TR0=1;
TH0=0xFC;
TL0=0x18;
ET0=1;
EA=1;
}
void main()
{
time_init();
while(1)
{
t=MatrixKey();
if(t)
{
if(t==1)
{
moshi=0;
}
if(t==5)
{
moshi=1;
}
if(t==9)
{
moshi=2;
}
if(t==13)
{
moshi=3;
}
}
if(j==500)
{
if(moshi==0)
{
P2=~(0x01<<i);
i++;
if(i==9)
{
i=0;
}
}
j=0;
}
}
}
void time_routine() interrupt 1{
TH0=0xFC;
TL0=0x18;
count++;
j++;
}
也可以将LED放在中断里面,
但当扫描按键放在中断时候要注意:
错误如下:
void time_routine() interrupt 1{
TH0=0xFC;
TL0=0x18;
count++;
j++;
if(count==2){
t=MatrixKey(); //错误!不能放中断里(起码我失败了)
if(t)
{
if(t==1)
{
moshi=0;
}
if(t==5)
{
moshi=1;
}
if(t==9)
{
moshi=2;
}
if(t==13)
{
moshi=3;
}
}
count=0
}
if(j==500)
{
if(moshi==0)
{
P2=~(0x01<<i);
i++;
if(i==9)
{
i=0;
}
}
j=0;
}
}
if(count==2){
t=MatrixKey(); //错误!!!!!!
不能这么写!
要这么写
中断中:
if(count==2){
MatrixKey();
count==0;
}
主函数中:
while(1)
{
t=MatrixKey();//接收按键状态
if(t==1)
{
moshi=0;
}
if(t==5)
{
moshi=1;
}
if(t==9)
{
moshi=2;
}
if(t==13)
{
moshi=3;
}
}
在定时器里面疯狂扫描,按键中的delay也可以删掉了
在主函数while里面一直判断MatrixKey()的返回值!
作用:你可以快快乐乐的把一个按键【想按多长时间就按多长时间】了
(按下不停止,松开才停止)
或许是用在闹钟上面???