- #include
- 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<
- EEAR = uiAddress;//设置地址和数据寄存器
- EEDR = ucData;
- EECR |= (1<
- EECR |= (1<
- }
- void EEPROM_READ(unsigned int uiAddress)
- {
- while(EECR & (1<
- EEAR = uiAddress;//设置地址寄存器
- EECR |= (1<
- 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: ;
- }
- }
复制代码
倒计时不能成功运作(一直显示88 88),紧急模式没有反应,修改时间也没有反应
求解决
0
已退回5积分
|
|
|
|