#include <REGX52.H>
#include"key.h"
#include"seg.h"
//变量
//按键状态
unsigned char down,up,val,old;
//减速
unsigned char key_10;
unsigned int seg_500;
//数码管
unsigned char seg_pos;
unsigned char seg_buff[6]={10,10,10,10,10,10};
unsigned char jie = 1;//1,2,3三个界面
//LED灯
bit rs;//开关
unsigned char p = 0xfe;//中间变量
unsigned int sudu[4] = {400,400,400,400};//间隔
unsigned int s ;//间隔计时器
unsigned char liu = 1;//1,2,3,4流水灯模式
unsigned char deng[4] = {0x7e,0xbd,0xdb,0xe7};
unsigned char de;//流水灯索引0,1,2,3
//按键函数
void key_proc()
{
if(key_10)
return;
key_10 = 1;
val = key_read();
down = val & (val ^ old);
up = ~val & (val ^ old);
old = val;
switch(down)
{
case 7:
rs ^= 1;
break;
}
}
//处理函数
void seg_proc()
{
if(seg_500)
return ;
seg_500 = 1;
switch(jie)
{
case 1:
seg_buff[0] = rs?11:5;
seg_buff[1] = liu;
seg_buff[2] = (sudu[liu-1]>=1000)?1:10;
seg_buff[3] = sudu[liu-1]/100%10;
seg_buff[4] = sudu[liu-1]/10%10;
seg_buff[5] = sudu[liu-1]%10;
break;
case 2:
break;
case 3:
break;
}
}
//其他显示函数
void led_proc()
{
P1 = p;
if(s != sudu[liu-1])
return;
s = 0;
switch(liu)
{
case 1:
if(p == 0x7e)
{
p = 0xfe;
}
else
{
p = (p<<1) | (p>>7);
if(p == 0x7f) liu = 2;
}
break;
case 2:
p = (p<<7) | (p>>1);
if(p == 0xfe) liu = 3;
break;
case 3:
p = deng[de];
if(++de == 4)
{
liu = 4;
de = 3;
}
break;
case 4:
p = deng[de];
if(--de == 255)
{
liu = 1;
de = 0;
}
break;
}
}
//定时器中断
void Timer0_Isr(void) interrupt 1
{
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
if(rs) s++;
if(++key_10 == 10) key_10 = 0;
if(++seg_500 == 500) seg_500 = 0;
if(++seg_pos == 6) seg_pos = 0;
seg_read(seg_pos,seg_buff[seg_pos]);
}
//定时器
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
ET0 = 1;
EA = 1;
}
//main
void main ()
{
Timer0_Init();
while(1)
{
key_proc();
seg_proc();
led_proc();
}
}
这是我的一道作业题,内容是流水灯的四种运行模式,数码管显示流水灯的运行情况,对此我有疑问,为什么这段代码if(p == 0x7f) liu = 2在检测到组末的状态的时候立即切换了模式,为什么没有导致数码管超前显示,这是我写的,总是超前显示
```c
#include <REGX52.H>
#include"key.h"
#include"seg.h"
//按键沿
unsigned char down,up,val,old;
bit rs;//开关
//减速
unsigned char key_10;//按键减速
unsigned int seg_500;//数码管减速
//LED灯
unsigned char de = 1;//led模式1,2,3,4
unsigned char p = 0xfe;//LED值
unsigned char led[4] = {0x7e,0xbd,0xdb,0xe7};//L18,L27,L36,L45
unsigned char le = 255;//数组索引0,1,2,3
unsigned int led_v[4] = {400,400,400,400};//流转间隔
unsigned int led_t = 0;//流转计时
//数码管
unsigned char jie = 1;//界面123
unsigned char t = 1;
unsigned char seg_pos;//数码管索引
unsigned char seg_buff[] = {10,10,10,10,10,10};//数码管数组
//key
void key_proc()
{
if(key_10) return ;
key_10 = 1;
val = key_read();
down = val & (val ^ old);
up = ~val & (val ^ old);
old = val;
switch(down)
{
case 7:
rs ^= 1;
break;
case 6:
if(++jie == 4) jie = 1;
break;
}
}
//led
void led_proc()
{
if(rs == 0)
return;
if(led_t)
return;
led_t = 1;
P1 = p;
switch(de)
{
case 1:
if(le == 255)
{
p = 0xfe;
le = 0;
}
else
p = (p<<1) | (p>>7);
if(p == 0x7f) de = 2;
break;
case 2:
p = (p<<7) | (p>>1);
if(p == 0xfe) {de = 3; le = 0;}
break;
case 3:
p = led[le];
if(++le == 4) {le = 3; de = 4;}
break;
case 4:
p = led[le];
if(--le == 255) {de = 1;}
break;
}
}
//数码管
void seg_proc()
{
if(seg_500) return;
seg_500 = 1;
switch(jie)
{
case 1:
if(rs == 0)
seg_buff[0] = 11;
else
seg_buff[0] = 5;
seg_buff[1] = de;
if(led_v[de-1] >= 1000)
seg_buff[2] = 1;
else
seg_buff[2] = 10;
seg_buff[3] = led_v[de-1] /100%10;
seg_buff[4] = led_v[de-1] /10%10;
seg_buff[5] = led_v[de-1] %10;
break;
case 2:
seg_buff[0] = 12;
seg_buff[1] = de;
if(led_v[de-1] >= 1000)
seg_buff[2] = 1;
else
seg_buff[2] = 10;
seg_buff[3] = led_v[de-1] /100%10;
seg_buff[4] = led_v[de-1] /10%10;
seg_buff[5] = led_v[de-1] %10;
break;
case 3:
seg_buff[0] = 13;
seg_buff[1] = 14;
seg_buff[2] = 12;
seg_buff[3] = de;
if(de<2)
{
seg_buff[4] = 0;
t = 0;
while(~p>>t)
{
t++;
}
seg_buff[5] = t + 1;
}
else
{
t = 0;
while((~p & 0xf)>>t)
{
t++;
}
seg_buff[4] = t+1;
seg_buff[5] = 8-t;
}
}
}
//定时器
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
//中断
void Timer0_Isr(void) interrupt 1
{
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
if(++led_t == led_v[de-1]) led_t = 0;
if(++key_10 == 10) key_10 = 0;
if(++seg_500 == 500) seg_500 = 0;
if(++seg_pos == 6) seg_pos = 0;
seg_read(seg_pos,seg_buff[seg_pos]);
}
//main
void main()
{
Timer0_Init();
while(1)
{
key_proc();
seg_proc();
led_proc();
}
}
```