Closed yueyuan123 closed 2 years ago
这是main.c:
void delay(int ms); void display1(uchar yi,uchar er,uchar san,uchar si); void display2(uchar wu,uchar liu,uchar qi,uchar ba); void Timer0Init(void); void keyscan();
uchar num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf,0xff}; uchar yi,er,san,si,wu,liu,qi,ba; int led_time=400,mode=0,ss,ssmode,digmode=0,tt; bit spst,sb=1; uchar RB2,led;
int main() { P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; led_time=eeprom_read(0x00)*100;delay(5); mode=eeprom_read(0x01);delay(5); Timer0Init(); while(1) { RB2=ad_read(0x03); if(sb==1){yi=21;er=21;san=21;si=21;wu=21;liu=21;qi=21;ba=21;} if((sb==0)&&(digmode==1)){if(ssmode==0){yi=20;er=mode;san=20;si=21;if(led_time>=1000){wu=led_time/1000;}else{wu=21;}liu=led_time%1000/100;qi=led_time%100/10;ba=led_time%10;} else {yi=21;er=21;san=21;si=21;if(led_time>=1000){wu=led_time/1000;}else{wu=21;}liu=led_time%1000/100;qi=led_time%100/10;ba=led_time%10;}} else if((sb==0)&&(digmode==2)){if(ssmode==0){yi=20;er=mode;san=20;si=21;if(led_time>=1000){wu=led_time/1000;}else{wu=21;}liu=led_time%1000/100;qi=led_time%100/10;ba=led_time%10;} else {yi=20;er=mode;san=20;si=21;wu=21;liu=21;qi=21;ba=21;}}
if((sb==0)&&(digmode==0)&&(mode==1)){yi=21;er=21;san=21;si=21;wu=21;liu=21;qi=21;ba=21;P2=0X80;P0=~(0X01<<led);}
if(spst==0){ET0=1;EA=1;}else {ET0=0;EA=0;}
keyscan();
display1(yi,er,san,si);
display2(wu,liu,qi,ba);
}
}
void keyscan()
{
if(S7==0)
{
delay(5);
if(S7==0)
{if(sb==1){sb=0;}
else {spst=~spst;}
}while(!S7);
}
else if(S6==0)
{
delay(5);
if(S6==0)
{if(sb==1){sb=0;}
else {
digmode++;
if(digmode>2){digmode=0;}}
}while(!S6);
}
else if(S5==0)
{
delay(5);
if(S5==0)
{if(sb==1){sb=0;}
else{
if(digmode==1){mode++;if(mode>4){mode=1;}}
else if(digmode==2){led_time+=100;if(led_time>1200){led_time=400;}}}
}while(!S5);
}
else if(S4==0)
{
delay(5);
if(S4==0)
{if(sb==1){sb=0;}
else{
if(digmode==1){mode--;if(mode<1){mode=4;}}
else if(digmode==2){led_time-=100;if(led_time<400){led_time=1200;}}}
}while(!S4);
}
eeprom_write(0x01,mode);delay(5);
eeprom_write(0x00,led_time/100);delay(5);
}
void time0() interrupt 1
{
ss++;tt++;
if(ss==800){ssmode=~ssmode;ss=0;}
if((digmode==0)&&(mode==1)&&(tt==led_time)){led++;if(led>=8){led=0;}tt=0;}
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初始值
TH0 = 0xD4; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void delay(int ms) { int i,j; for(i=0;i<ms;i++) for(j=0;j<845;j++); }
void display1(uchar yi,uchar er,uchar san,uchar si) { P2=0XC0;P0=0X01; P2=0XE0;P0=num[yi]; delay(2);
P2=0XC0;P0=0X02;
P2=0XE0;P0=num[er];
delay(2);
P2=0XC0;P0=0X04;
P2=0XE0;P0=num[san];
delay(2);
P2=0XC0;P0=0X08;
P2=0XE0;P0=num[si];
delay(2);
} void display2(uchar wu,uchar liu,uchar qi,uchar ba) { P2=0XC0;P0=0X10; P2=0XE0;P0=num[wu]; delay(2);
P2=0XC0;P0=0X20;
P2=0XE0;P0=num[liu];
delay(2);
P2=0XC0;P0=0X40;
P2=0XE0;P0=num[qi];
delay(2);
P2=0XC0;P0=0X80;
P2=0XE0;P0=num[ba];
delay(2);
} 这是iic.c:
//总线引脚定义 sbit SDA = P2^1; / 数据线 / sbit SCL = P2^0; / 时钟线 /
void IIC_Delay(unsigned char i)
{
do{nop();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件 void IIC_Stop(void) { SDA = 0; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 1; IIC_Delay(DELAY_TIME); }
//发送应答 void IIC_SendAck(bit ackbit) { SCL = 0; SDA = ackbit; // 0:应答,1:非应答 IIC_Delay(DELAY_TIME); SCL = 1; IIC_Delay(DELAY_TIME); SCL = 0; SDA = 1; IIC_Delay(DELAY_TIME); }
//等待应答 bit IIC_WaitAck(void) { bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据 void IIC_SendByte(unsigned char byt) { unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
void eeprom_write(unsigned char add,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char eeprom_read(unsigned char add)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return temp;
} unsigned char ad_read(unsigned char add) { unsigned char temp; IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(add); IIC_WaitAck(); IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return temp;
} 这是iic.h:
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
unsigned char eeprom_read(unsigned char add);
void eeprom_write(unsigned char add,unsigned char dat);
unsigned char ad_read(unsigned char add);
我怀疑是中断自身的问题,但是没有仿真没办法证明,也没办法看到底是哪里有问题
老哥儿帮帮我啊,别不理我
兄弟,我仿真了一下,找到问题了,跟你说一下,是因为tt是int,因为设置的时候定时器没停止,tt加到超过我设置的led_time这个值了,所以即便设置完led还是不动,一直tt加到上限回到0,led才开始动。这就是为什么等几分钟led才动。
直接在模式那里写一个tt=0;完美解决
这是好的
我先简单描述一下,就是上电全关,随便按一个独立按键激活,S6键调设置(模式和延时),但是调完设置不是数码管全关嘛,关完led就不动了,等好一会儿才动。我再继续研究半个小时,起床了你看看吧,老哥儿