模拟路灯控制系统.C

来源:互联网 发布:细分算法 编辑:程序博客网 时间:2024/05/01 17:59

 #include "iom16v.h"
#include "macros.h"
#include "delayms.h"
#include "avrbit.h"
#include "时钟模块.C"
#include "液晶显示模块.C"
#include "ADC_模块.c"
//变量定义================================================================================
uchar t1_n[12]="T1-ON: 00:00";
uchar t1_f[12]="T1-OFF:00:00";
uchar t2_n[12]="T2-ON: 00:00";
uchar  t2_f[12]="T2-OFF:00:00";
uchar power[12]="POWER: 00%  ";
uchar *p_shuzu;
uchar num=0;//num为地址指针变量
uchar temp_1;//选定设置选项
uchar test_bit=0x00;//低三位(0,1,2)确定菜单顺序
      //BIT(7)是否让表显示,BIT(6)检测下翻是否按下
      //BIT(5)第一次让表停,第二次显光标
      //BIT(4)开始调表确认位
      //BIT(3)定时时间到判断位
uchar f_xiang=0x00;//0,1,2,3,4判断小车走路方向,位7决定'+','-'键在确认键之后  
uchar num_time=0;//时间数组访问变量   
//端口初始化================================================================================
void port_init(void)
{
 PORTA = 0x38;
 DDRA  = 0xC8;
 PORTB = 0xFF;
 DDRB  = 0x00;
 PORTC = 0x00;
 DDRC  = 0xFF;
 PORTD = 0xFC;
 DDRD  = 0xFF;
    w_com(0x38);
    w_com(0x0c);
    w_com(0x01);
}
//外中断初始化================================================================================
void int_init(void)
{
 MCUCR |= 0x00;
 MCUCSR|= 0x00;
 GICR  |= 0x20;
}
//定时T1初始化================================================================================
void timer1_init(void)
{
 TCCR1A = 0xA1;
 TCCR1B = 0x0A;//启动定时器//8bit,5%=12,100%=255
 OCR1A = 128;//匹配A值,50%
 OCR1B = 128;//匹配B值,50%
}

//下翻函数================================================================================
void p_fun()
{
  uchar i;
  w_com(0xC0);
  p_shuzu[9]=':';
    for(i=0;i<12;i++)
     w_data(p_shuzu[i]);
  num_time=20;
  w_com(0x80);
}
void p_jian()
{
  p_shuzu[6+num]--;
    if((p_shuzu[6+num]>'9')||(p_shuzu[6+num]<'0'))p_shuzu[6+num]='9';    
    w_data(p_shuzu[6+num]);
    w_com(0xC6+num);
}
void p_jia()
{
  p_shuzu[6+num]++;
    if((p_shuzu[6+num]>'9')||(p_shuzu[6+num]<'0'))p_shuzu[6+num]='0';    
    w_data(p_shuzu[6+num]);
    w_com(0xC6+num);
}
//外中断2服务程序================================================================================
#pragma interrupt_handler int2_isr:19
void int2_isr(void)
{
   uchar temp;
  delayms(100);
  temp=PINA&0X38;//PA5~3三位
  switch(temp)
  {
   case 0x00://确认
   {
    if(test_bit&BIT(6))//检测下翻是否按下
    {
     if(test_bit&BIT(5))//先停表
     {
      if(!num)
      {
       num_time=20;
       w_com(0x0D);//光标闪烁
       w_com(0xCF);//地址指针
       test_bit|=BIT(4);//开始调整
      }
      else
      {
       f_xiang&=~BIT(7);
       test_bit&=0x0F;//清4,5,6,7位
       num=0;
       w_com(0x0C);//关闭光标闪烁
       w_com(0x01);
      }     
     } 
     else
     {
      test_bit|=BIT(7);//停表
      test_bit|=BIT(5);
     } 
    }
    break;
   } 
   case 0x08://下翻
   {
    test_bit|=BIT(6);//确认下翻键按下
    temp_1=test_bit&0x07;
    if(test_bit&BIT(4))//开始调表确认位
    {
     num++;
     if(num==6)num=1;
     w_com(0xC6+num);//地址指针,num为地址指针变量
     f_xiang|=BIT(7);//位7决定'+','-'键在确认键之后  
    }
    else
    {
     switch(temp_1)
       {
        case 0x00://调时间
        {
         p_shuzu=time;
       p_fun();    
         test_bit|=BIT(0);//001  
         break;
        }
        case 0x01://调T1-ON
        {
         p_shuzu=t1_n; 
       p_fun();
         test_bit|=BIT(1);//011
         break;
        }
        case 0x03://调T1-OFF
        {
         p_shuzu=t1_f;
       p_fun();
         test_bit&=~BIT(0);//010
         break;
        }
        case 0x02://调T2-ON
        {
         p_shuzu=t2_n;
       p_fun();
         //test_bit&=~BIT(1);
         test_bit|=BIT(2);//110
         break;
        }
        case 0x06://调T2-OFF
        {
         p_shuzu=t2_f;
       p_fun();
         test_bit&=~BIT(1);//100
         break;
        }
      case 0x04://调POWER
        {
         p_shuzu=power;
       p_fun();
       w_com(0xC9); 
       w_data('%');
       w_data(' ');
       w_data(' ');
       w_com(0x80);
         test_bit&=~BIT(2);//000
         break;
        }
      default : break;
       } 
    }     
    break;
   }   
   case 0x10://减1
   {
      if((test_bit&BIT(6))&&(f_xiang&BIT(7)))//检测下翻是否按下
      { 
     switch(temp_1)
       {
        case 0x00://POWER
        {
         p_shuzu=power;
         p_jian();
        }
        break;
        case 0x01://调时间
        {
         p_shuzu=time;
         p_jian();
        }
        break;
        case 0x02://调T1-OFF
        {
         p_shuzu=t1_f;
         p_jian();
        }
        break;
        case 0x03://调T1-ON
        {
         p_shuzu=t1_n;
         p_jian();
        }
        break;
        case 0x04://T2-OFF--
        {
         p_shuzu=t2_f;
         p_jian();
        }
        break;
      case 0x06://调T2-ON
        {
         p_shuzu=t2_n;
         p_jian();
        }
        break;
      default : break;
       }      
      }
    break; 
   } 
   case 0x18://加1
   {
      if((test_bit&BIT(6))&&(f_xiang&BIT(7)))//检测下翻是否按下
      { 
     switch(temp_1)
       {
        case 0x00://POWER
        {
         p_shuzu=power;
         p_jia();
        }
        break;
        case 0x01://调时间
        {
         p_shuzu=time;
         p_jia();
        }
        break;
        case 0x02://调T1-OFF
        {
         p_shuzu=t1_f;
         p_jia();
        }
        break;
        case 0x03://调T1-ON
        {
         p_shuzu=t1_n;
         p_jia();
        }
        break;
        case 0x04://T2-OFF--
        {
         p_shuzu=t2_f;
         p_jia();
        }
        break;
      case 0x06://调T2-ON
        {
         p_shuzu=t2_n;
         p_jia();
        }
        break;
      default : break;
       }      
      }
    break;
   }
   case 0x20://光电1
   {
    if(!(f_xiang&BIT(0)))
    {
     PD0_1;//开灯1
     f_xiang|=BIT(0);
     f_xiang|=BIT(1);
    }
    if(f_xiang&BIT(4))
    {
     PD0_0;//关灯1
     f_xiang&=0xEA;//清0,2,4位
    }
    break;
   }
   case 0x28://光电2
   {
    if(f_xiang&BIT(1))
    {
     PD0_0;//关灯1
     PD1_1;//开灯2
     f_xiang|=BIT(3);
    }
    if(f_xiang&BIT(2))
    {
     PD1_0;//关灯2
     PD0_1;//开灯1
     f_xiang|=BIT(4);
    }
    break;
   }
   case 0x30://光电3
   {
    if(!(f_xiang&BIT(0)))
    {
     PD1_1;//开灯2
     f_xiang|=BIT(0);
     f_xiang|=BIT(2);
    }
    if(f_xiang&BIT(3))
    {
     PD1_0;//关灯2
     f_xiang&=0xF4;//清0,1,3位
    }
    break;
   }
   default : break;    
  }
}
//定时时间到了===================================================================================
void ding_shi(uchar temp_p[])
{
  if(time[7]==temp_p[7])
   if(time[8]==temp_p[8])
    if(time[10]==temp_p[10])
     if(time[11]==temp_p[11])
      test_bit|=BIT(3);
}
void bao_jing()
{
  PD7_0;//报警
    w_com(0x01);   
  w_com(0xC0);   
  w_data('L');
    w_data('I');   
  w_data('G');   
  w_data('H');
    w_data('T');   
  w_data('-');
    w_data(' ');//6
    w_data(' ');   
  w_data('!');   
  w_data('!');
    w_data('!');
}
void init_devices(void)
{
 CLI(); //禁止所有中断
 MCUCR  = 0x00;
 MCUCSR = 0x80;//禁止JTAG
 GICR   = 0x00;
 port_init();
 int_init();
 adc_init();
 timer0_init();
 timer1_init();
 SEI();//开全局中断
}
//主函数=========================================================================================
void main()
{
  uint ada;
  init_devices();
   while(1)
   {
     if(!(test_bit&BIT(7)))
   {
    w_com(0x80);
    time[9]=':';
     for (num_time=0;num_time<15;num_time++)
      w_data(time[num_time]);

    
      ding_shi(t1_n);
      if(test_bit&BIT(3))//灯1开时间到了
       { OCR1B=130; PD0_1; test_bit&=~BIT(3);}
      ding_shi(t1_f);
      if(test_bit&BIT(3))//灯1关时间到了
       {
      while(OCR1B>10)
       {OCR1B-=10;delayms(500);}
      PD0_0;
      test_bit&=~BIT(3);
     }
      ding_shi(t2_n);
      if(test_bit&BIT(3))//灯2开时间到了
       { OCR1B=130; PD1_1; test_bit&=~BIT(3);} 
      ding_shi(t2_f);
      if(test_bit&BIT(3))//灯2关时间到了
       {
      while(OCR1B>10)
       {OCR1B-=10;delayms(500);}
      PD1_0;
      test_bit&=~BIT(3);
     }    
   } 
   
/*
   DDRA&=~BIT(0);
   PORTA&=~BIT(0);
   ADMUX=0X00;//----------------------单端0输入,选择外部参考电压
   ada=mega16_adc();
   if(t1_n[7]=='0')
    if(t1_n[8]=='0')
     if(t1_n[10]=='0')
      if(t1_n[11]=='0')
      if(ada>500)
       {PD0_1; PD1_1;}//开灯
      else      
       {PD0_0; PD1_0;}//关灯 
*/       
     
   DDRA&=~BIT(1);
   PORTA&=~BIT(1);
   ADMUX=0X01;//----------------------单端1输入,选择外部参考电压 
   ada=mega16_adc();  
   if(PD0)
   {
    if(ada>500)
    {
    bao_jing();
    w_com(0xC6);
    w_data('1');//6
    delayms(5000);//报警3秒
    w_com(0x01);
    PD7_1;//报警
    PD0_0;
    }
   } 
      
   DDRA&=~BIT(2);
   PORTA&=~BIT(2);
   ADMUX=0X02;//----------------------单端2输入,选择外部参考电压 
   ada=mega16_adc();
   if(PD1)
   {
      if(ada>500)
       {
       bao_jing();
       w_com(0xC6);
       w_data('2');//6
       delayms(5000);//报警3秒
       w_com(0x01);
     PD7_1;//报警
       PD1_0;
       }
   }    
  }  
}

原创粉丝点击