课设一个星期了,程序和原理图遇到了很多问题,剩这三个还没有解决,麻烦各位大神给点意见,救救孩子!
求解决这三个问题: 倒计时不运 作 ,紧急模式没有反应 ,修改时间也没有反应
#include <iom168v.h>
const unsigned char disp[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //段选码
unsigned char xs[4]= {0xC0,0xC0,0xC0,0xC0};
unsigned char gs=0; //绿灯
unsigned char ys=0; //黄灯
unsigned char green_second = 9 , yellow_second = 3 ; //用于修改时间的变量
unsigned char k=0; //显示刷新标志
unsigned char flag=0; //转换红绿灯标志位
unsigned char flag1=0; //切换交通灯模式标志位
unsigned char flag2=0; //紧急模式下的切换模式
unsigned char flag3=0; //修改时间
unsigned int Udelay = 1000;
//主频为1M
void delay_1us(void) //1us延时,实测8us
{
asm("nop"); //1时钟周期
}
void delay_3us(void) //3us,实8us
{
asm("nop");
}
void delay_10us(void) //10us,实9us
{
asm("nop");
asm("nop");
}
void delay_50us(void) //50us,实47us
{
delay_10us();
delay_10us();
delay_10us();
delay_10us();
delay_10us();
}
void delay_100us(void) //100us,实96us
{
delay_50us();
delay_50us();
}
void delay_n100us(unsigned char n100us) //几百us延时
{
while(n100us--);
delay_100us();
}
//延时函数
void delay(unsigned int x)
{
while(x--);
}
//IO配置函数
void io_init(void)
{
DDRD = 0xFF;
PORTD = 0xFF;
DDRB = 0b00111111;
PORTB = 0xFF;
DDRC = 0b00111100;
PORTC = 0b00111111;
PORTC|=0b00111100;//4位位控总不变
}
//EEPROM写入、读取
void EEPROM_WRITE(unsigned int uiAddress, unsigned char ucData)
{
while(EECR & (1<<EEWE));//等待上一次写操作结束
EEAR = uiAddress;//设置地址和数据寄存器
EEDR = ucData;
EECR |= (1<<EEMWE); //置位EEMWE
EECR |= (1<<EEWE);//置位EEWE 以启动写操作E
}
void EEPROM_READ(unsigned int uiAddress)
{
while(EECR & (1<<EEWE)); //等待上一次写操作结束
EEAR = uiAddress;//设置地址寄存器
EECR |= (1<<EERE); //设置EERE 以启动读操作
return /*EEDR*/; //自数据寄存器返回数据
}
//译码函数
void decode(unsigned char a/*, unsigned char b*/)
{
/*switch(b)
{
case 0 :*/
xs[0] = disp[a / 10];
xs[1] = disp[a % 10];
/*break;
case 1 :*/
xs[2] = disp[a / 10];
xs[3] = disp[a % 10];
/*break;
}*/
}
void shutdownLED(void)
{
xs[0] = 0xff;xs[1] = 0xff;xs[2] = 0xff;xs[3] = 0xff; //关闭显示清空段选段选
TCCR0B = 0x00;
TCCR1B = 0x00;
PORTC|=0b00111100; //关位选
}
//修改时间
/*void changetime(void)
{
//只能在普通模式下改变时间
if( ((PINB & 0x80) == 0) && ((flag1 == 0)||(flag1 == 3)) )
{
PORTB |= 0x3f; //关闭显示灯
flag3 = (flag3 + 1) % 3;
if(flag3 == 0)
{
flag1 = 0;
xs[2] = 0xff;
xs[3] = 0xff;
}
delay(50000);
}
//修改时间
if(flag3 == 1)
{
flag1 = 3;
//绿灯闪
PORTB &= ~0x24;
if((PINC & 0x01) == 0) //+1
{
delay_n100us(100);
if((PINC & 0x01) == 0)
{
green_second++;
EEPROM_WRITE(0x00, green_second);
delay(40000);
}
}
if((PINC & 0x02) == 0) //-1
{
delay_n100us(100);
if((PINC & 0x02) == 0)
{
if(green_second > 0)
{
green_second--;
EEPROM_WRITE(0x00, green_second);
delay(40000);
}
}
}
//数码管2显示绿灯时间
decode(green_second/*, 1*//*);
}
if(flag3 == 2)//2黄灯
{
//黄灯闪
PORTB &= ~0x12;
if((PINC & 0x01) == 0) //+1
{
delay_n100us(100);
if((PINC & 0x01) == 0)
{
yellow_second++;
EEPROM_WRITE(0x02, yellow_second);
UDR0 = 0x02;
delay(10000);
UDR0 = yellow_second;
delay(40000);
}
}
if((PINC & 0x02) == 0) //-1
{
delay_n100us(100);
if((PINC & 0x02) == 0)
{
if(yellow_second > 0)
{
yellow_second--;
EEPROM_WRITE(0x02, yellow_second);
UDR0 = 0x02;
delay(10000);
UDR0 = yellow_second;
delay(40000);
}
}
}
//数码管2显示黄灯时间
decode(yellow_second/*, 1*//*);
}
}*/
//红绿灯显示函数
void led(void)
{
switch(flag1)
{
case 0:
{//日间模式
TCCR0B = 0x03;
TCCR1B = 0x0b;
switch(flag)
{
case 0:
xs[2]= 0xbf;
xs[3]= 0xbf;
decode(gs/*, 0*/);
PORTB |= 0x08; //关闭左右红灯
PORTB |= 0x02; //关闭上下黄灯
PORTB &= ~0x20; //开启左右绿灯
PORTB &= ~0x01; //开启上下红灯
break;
case 1:
decode(ys/*, 0*/);
PORTB &= ~0x01; //开启上下红灯
PORTB |= 0x20; //关闭左右绿灯
PORTB &= ~0x10; //开启左右黄灯
if(ys <= 3)
{
decode(ys/*, 1*/);
}
break;
case 2:
xs[0]= 0xbf;
xs[1]= 0xbf;
decode(gs/*, 1*/);
PORTB |= 0x10; //关闭左右黄灯
PORTB |= 0x01; //关闭上下红灯
PORTB &= ~0x04; //开启上下绿灯
PORTB &= ~0x08; //开启左右红灯
break;
case 3:
decode(ys/*, 1*/);
PORTB &= ~0x08; //开启左右红灯
PORTB |= 0x04; //关闭上下绿灯
PORTB &= ~0x02; //开启上下黄灯
if(ys <= 3)
{
decode(ys/*, 0*/);
}
break;
}
break;}
case 1: //紧急模式
{
PORTB |= 0x3f;
shutdownLED();
switch(flag2)
{
case 0://紧急模式1
{
PORTB &= ~0x08;//开启左右红灯
PORTB &= ~0x01; //开启上下红灯
break;
}
case 1://紧急模式2
{
PORTB &= ~0x20; //开启左右绿灯
PORTB &= ~0x01; //开启上下红灯
break;
}
case 2://紧急模式3
{
PORTB &= ~0x04;//开启上下绿灯
PORTB &= ~0x08;//开启左右红灯
break;
}
//break;//自己加的
}
break;
}
case 2: //夜间模式
{
PORTB |= 0x3f;
shutdownLED();
flag2 = 0;
PORTB &= ~0x02;//开启上下黄灯
PORTB &= ~0x10;//开启左右黄灯
delay(50000);
PORTB |= 0x02;//关闭上下黄灯
PORTB |= 0x10;//关闭左右黄灯
delay(50000);
break;
}
case 3:
{
TCCR1B = 0x00; //关闭计时
xs[0] = 0xbf;
xs[1] = 0xbf;
break;
}
}
}
//主函数
void main(void)
{
gs = green_second;
ys = yellow_second;
io_init(); //IO口初始化
//定时器初始化
timer0_init();
timer1_init();
SREG|=0x80; //开启总中断
//数据写入EEPROM
EEPROM_READ(0x00/*,green_second*/);delay(10);
EEPROM_READ(0x02/*,yellow_second*/);delay(10);
if(green_second>50) EEPROM_WRITE(0x00, gs);
if(yellow_second>50) EEPROM_WRITE(0x02, ys);
EEPROM_READ(0x00/*green_second*/);delay(10);
EEPROM_READ(0x02/* yellow_second*/);delay(10);
gs = green_second;
ys = yellow_second;
delay(10000);
while(1)
{
//修改模式
if( ((PINB & 0x40) == 0) && (flag3 == 0))
{
PORTB |= 0x3f;
flag1 = (flag1 + 1) % 3;
delay(20000);
}
//紧急模式下切换
if( ((PINB & 0x80) == 0) && (flag1 == 1))
{
PORTB |= 0x3f;
flag2 = 0;
delay(20000);
}
//东西方向
if( ((PINC & 0x01) == 0) && (flag1 == 1))
{
PORTB |= 0x3f;
flag2 = 1;
delay(20000);
}
//南北方向
if( ((PINC & 0x02) == 0) && (flag1 == 1))
{
PORTB |= 0x3f;
flag2 = 2;
delay(20000);
}
//led显示函数
led();
//修改时间函数
//changetime();
}
}
// 定时器0的初始化
void timer0_init(void)
{
TCCR0A = 0x02; //CTC模式
TCCR0B = 0x03; //64分频
OCR0A = 78; //5ms 78.125
TIMSK0 = 0x02;/*比较中断A允许*/
TIFR0 = 0x02;
}
//定时器1的初始化
void timer1_init(void)
{
TCCR1A = 0x00; //CTC模式
TCCR1B = 0x0b; //64分频
OCR1A = 15625; //1s = 15625
TIMSK1 = 0x02; /*比较中断A允许*/
TIFR1 = 0x02;
}
extern unsigned char k;
extern unsigned char xs[4];
extern unsigned char green_second, yellow_second;
extern unsigned char gs;
extern unsigned char ys;
extern unsigned char flag;
extern unsigned char flag1; //切换交通灯模式标志位
extern unsigned char flag2; //紧急模式下的切换模式
extern unsigned char flag3; //修改时间
#pragma interrupt_handler Int_TCCR1A:12
void Int_TCCR1A(void)
{
switch(flag)
{
case 0 :
gs--;
//decode(gs);//zi+
ys = yellow_second;
if(gs == 0)
{
flag = 1;
}
break;
case 1 :
ys--;
//decode(ys);//+
gs = green_second;
if(ys == 0)
{
flag = 2;
}
break;
case 2 :
gs--;
//decode(gs); //+
ys = yellow_second;
if(gs == 0)
{
flag = 3;
}
break;
case 3 :
ys--;
//decode(ys);//+
gs = green_second;
if(ys == 0)
{
flag = 0;
}
break;
}
}
// 中断服务程序的功能:刷新段码与位控制,用变量 K 实现轮流刷新的目的
#pragma interrupt_handler Int_TCCR0A:15
void Int_TCCR0A(void)
{
k=(++k)%4;
PORTC|=0b00111100;//关位选
PORTD=xs[4];
switch(k)
{
case 0:
PORTC &= ~0x04;
//PORTD &= ~0x04;//显示千位
break;
case 1:
PORTC &= ~0x08;
//PORTD &= ~0x08;//显示百位
break;
case 2:
PORTC &= ~0x10;
//PORTD &= ~0x80;//显示十位
break;
case 3:
PORTC &= ~0x20;
//PORTC &= ~0x08;//显示个位
break;
default: ;
}
}
复制代码