基于ATmega48单片机的交通灯系统(二)

上一个是讲的是元件,这里是代码篇
这里再放一下原图在这里插入图片描述

#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;
			}
  }

}             
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
摘 要 电动自行车由于轻便灵活、节能环保、价格适中而得到人们的广泛使用,成 为人们短途出行的理想交通工具。同时中国具有世界上最庞大的自行车市场,电 动自行车产业在中国有着非常广阔的应用前景。因此发展电动自行车具有良好的 社会意义和可观的经济效益。 目前电动自行车的动力驱动主要是轮毂式无刷直流电动机。电动自行车控制 器作为电动自行车的控制核心,是电动自行车的关键部件,与无刷直流电动机一 起构成电动自行车的动力驱动系统。为了提高电动自行车的的骑行舒适性、安全 性,本文对电动自行车的动力驱动系统进行了深入的研究,并简要介绍了电动自 行车控制器的功能构成和软硬件设计。 首先简要介绍了无刷直流电动机的基本结构和工作原理,并求出了其数学模 型;分析了无刷直流电动机换相转矩脉动产生的原因,提出了采用延时导通重叠 换相法对转矩脉动进行抑制;同时阐述了无刷直流电动机能量回馈制动的原理, 得出能量回馈制动的控制规律;最后给出了电动自行车功能设计的要求。 其次详细介绍了无刷直流电动机的控制策略,根据无刷直流电动机的调速特 性,采用PWM调制方式,通过调节电机电枢电压调节电机速度。并对速度电流双 闭环调速系统进行了详细的论述,通过采用模糊-PI控制算法调节速度,提高了电 机转速的控制精度。 最后介绍了电动自行车控制器的软硬件设计,并给出样机运行的实验结果。 硬件设计以单片机ATmega48为核心,包括电源电路、三相全桥逆变电路及其驱动 保护电路、电流检测等部分。软件设计采用“时间片”分时思想和模块化结构, 根据控制需求编写了各个模块程序,如驱动换相、柔性电子刹车(EABS)、欠 压保护;并实现“速度-电流”双闭环的控制功能;给出了各模块详细的程序流程 图。 实验结果表明:控制器较好地实现了对无刷直流电动机的控制,各项性能达 到预定要求,电机启动迅速、转矩脉动较小、速度跟踪性能良好、运行平稳可靠。 关键词:电动自行车;无刷直流电动机;转矩脉动;能量回馈制动;模糊-PI控制
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值