上一个是讲的是元件,这里是代码篇
这里再放一下原图
#include"iom48v.h"
//#include"eeprom.h"
unsigned int ytemp=3;//黄灯初始值是三秒
unsigned int rtemp=15;//红灯初始值是20秒
unsigned int gtemp=12;//绿灯初始值是15秒
unsigned int shine=1;//用于更改时实现闪烁
unsigned char k=0;//用于刷新输出
unsigned char i=0;//用于搞时间
unsigned char a=0;//用于闪烁
unsigned char change=0;//用于更换调节模式
unsigned char emergency=0;//紧急模式的切换
unsigned char em=0;//紧急模式的应用
unsigned int z;//显示红灯
unsigned int x;//显示绿灯
unsigned char b;
//IO口设置
void io(void)
{
DDRB=0x0F;//B口第四位设置为输出 高四位设置为输入
PORTB=0xff;//第四位为低电平,高四位为高电平内部上拉
DDRC=0xFF;//C口全设置为输出
PORTC=0x00;
DDRD=0x0f;
PORTD=0xff;
}
//数码管的显示
const unsigned char disp[] = {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9}
//数码管初始化
unsigned char led[]={0xff,0xff};
unsigned char led1[]={0xff,0xff};
//数码管的代码
void decode(int b)
{
led1[0]=disp[b%10];//显示在数码管个位,存放数据的个位
b=b/10;
led1[1]=disp[b%10]; //显示在数码管十位,存放数据的个位
}
void adecode(int b)
{
led[0]=disp[b%10];//显示在数码管个位,存放数据的个位
b=b/10;
led[1]=disp[b%10]; //显示在数码管十位,存放数据的个位
}
//延时程序
void delay(int x)
{
while(x--);
}
//T0定时器 CTC模式
void T0(void)
{
TCCR0A =0x00; //定时器0 模式:CTC模式
TCCR0B =0x0A; //定时器0 64分频
OCR0A =78; //比较值 20ms
TIMSK0 = 0x02; //中断允许
TIFR0 = 0x02;
}
//T0中断服务程序
#pragma interrupt_handler int_T0:15
void int_T0(void)
{
shine++;//每中断一次,shine的值就自增一次;
shine%=100;//每100次中断为一个周期
k++;
k%=2;
if(shine==0)//每经过100次中断,a的值就自增一
{a++;
a%=2;}
//关闭所有位
PORTC|=0x03;//关闭所有为控
PORTB=led1[k];
PORTD=led[k];
switch(k)
{
case 0:if(change==0){PORTC&=0xfd;}//非调节模式,正常显示
if(change>0)//调节模式,用于实现闪烁
{
switch(a)
{
case 0:PORTC&=0xfd;break;
case 1: PORTC|=0x02;break;
}
}
break;//非调节模式,正常显示
case 1:if(change==0){PORTC&=0xfe;}
if(change>0)
{
switch(a)
{
case 0:PORTC&=0xfe;break;
case 1:PORTC|=0x01;break;
}
}
break;
}
}
//T1定时器
void T1_(void)
{
TCCR1A =0x00; //定时器1 模式:CTC模式
TCCR1B =0x0B; //定时器1 64分频
OCR1A =15625; //比较值
ICR1 =15625; //计数最大值
TIMSK1 = 0x02; //定时器1中断允许
TIFR1 = 0x02;
}
//T1定时器中断服务程序
#pragma interrupt_handler Int_T1:12
void Int_T1(void)
{
if(i==0)
{
z=rtemp;
x=gtemp;
}
i++;
i=i%(rtemp+gtemp+ytemp+1);
if((i>=0)&&(i<=rtemp))//red light
{ z=z-1;
if(z==0)
{ z=gtemp;}
if((i>=0)&&(i<=gtemp))//一边红灯的开始就是另一边绿灯的开始和黄灯的结束
{
x--;//这是另一边绿灯的开始
if(x==0)
{x=ytemp;}
}
if((i>gtemp)&&(i<=(ytemp+gtemp)))//这是另一边的黄灯
{x--;
if(x==0)
{x=rtemp;}
}
}
if((i>rtemp)&&(i<=(gtemp+rtemp)))//绿灯
{
z=z-1;
if(z==0)
{z=ytemp;}
x--;
}
if((i>(rtemp+gtemp))&&(i<=(rtemp+gtemp+ytemp)))//黄灯
{
z=z-1;
if(z==0)
{z=rtemp;}
x--;
if(x==0)
{
x=gtemp;
PORTC&=0x03;
}
}
}
//主程序
void main(void)
{
io();
T0();
T1_();
SREG|=0x80; //中断总开关打开
while(1)
{
f((PINB&0x10)==0)
{delay(50000);
change++;
change%=4;
}
if((PIND&0x10)==0)
{delay(40000);
emergency++;
emergency%=2;
}
if((PIND&0x20)==0)
{delay(40000);
em++;
em%=2;
}
if((PINB&0x80)==0x80)
{
if(emergency==0)//非紧急模式下
{//decode(15);
switch(change)
{
case 0://正常显示
decode(z);
adecode(x);
if((i>=0)&&(i<rtemp))//红灯
{
if((i>=0)&&(i<gtemp))//一边红灯的开始就是另一边绿灯的开始和黄灯的结束
{
PORTC&=0x03;
}
if((i>=gtemp)&&(i<(ytemp+gtemp)))//这是黄灯
{
PORTC|=0x04;
}
}
if((i>=rtemp)&&(i<(gtemp+rtemp)))//绿灯
{
PORTC|=0x08;//另一边的红灯亮和绿灯亮
}
if((i>=(rtemp+gtemp))&&(i<(rtemp+gtemp+ytemp)))//黄灯
{
PORTC|=0x10;//另一边的红灯亮和黄灯亮
}
break;
case 1://用于实现红灯的更改
decode(rtemp);
adecode(rtemp);
if((PINB&0x20)==0)
{delay(50000);
rtemp+=1;
i=0;
}
if((PINB&=0x40)==0)
{
delay(50000);
rtemp-=1;
i=0;
}
break;
case 2://用于实现绿灯的更改
decode(gtemp);
adecode(gtemp);
if((PINB&0x20)==0)
{delay(50000);
gtemp+=1;
i=0;
}
if((PINB&=0x40)==0)
{
delay(50000);
gtemp-=1;
i=0;}
break;
case 3://用于实现黄灯的更改
decode(ytemp);
adecode(ytemp);
if((PINB&0x20)==0)
{delay(50000);
ytemp+=1;
i=0;}
if((PINB&=0x40)==0)
{
delay(50000);
ytemp-=1;
i=0;}
break;
}
}
if(emergency==1)//紧急模式
{
PORTB&=0x00;
PORTD&=0x00;
if(em==0)
{
PORTC=0x00;
}
if(em==1)
{
PORTC=0x0c;
}
i=0;
}
}
if((PINB&0x80)==0)//夜间模式
{
PORTC|=0x1B;
delay(20000);
PORTC&=0x0F;
delay(20000);
i=0;
}
}
}