×
单片机 > 单片机程序设计 > 详情

avr单片机atmega16自动浇花器Proteus仿真+源程序

发布时间:2020-08-27 发布时间:
|

 

单片机源程序如下:

#include

#include

#define  key_bz   0b00000111

#define uchar  unsigned char

#define  uint_16  unsigned short

char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x37};// 全局变量

char smg_wx[]={0B00000001,0B00000010,0B00000100,0b00001000}; 

char  smg_oFF[]={0x3f,0X71,0X71};

unsigned int flag_10ms=0,flag_1s=0,on=0,buff[]={0,0,0},mode=0;

unsigned  int jh_hour1=2,u=0,count=0,count1=2,on_sec=0;

unsigned int jh_sec1=5,jh_hour=0,jh_sec=0,flag=0;



unsigned long int jishi_sec=0;

void delay_ms(unsigned int k)                        

{

    unsigned int i,j;

    for(i=0;i

    {

      for(j=0;j<570;j++);

    }

}

// 用定时器实现定时

void T0_init(void)// 端口初始化函数

{

TIFR=0XFF;

TCCR0=0X0B; //64FENPIN, CTC MODE

TCNT0=0;

OCR0=250;

TIMSK=0X02;

}


void port_init(void)// 端口初始化函数

{

  DDRC|=0b10001111;  // PC4 5 OUT PUT

  PORTC=0b11110000; //m103 output only


PORTD= 0xFF; 

DDRD= 0xff;

DDRB&= 0b11111000;  

PORTB|=0B00000111;


}


void init_devices(void)

{


CLI(); //disable all interrupts

port_init();//smg_zx[0]=1;

T0_init();

SEI(); //re-enable interrupts


}




////多位数拆分函数///////*/


void xs_buff(uchar va1, uchar va2)

{

  buff[0]=va1/10;

  buff[1]=va1%10;

  buff[2]=va2/10;

  buff[3]=va2%10;

  

}

void xs_buff_on( uchar va2)

{

  buff[0]=0;

  buff[1]=10;

  buff[2]=va2/10;

  buff[3]=va2%10;

}



void xs_smg()

{//char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,

  // 0x7d,0x07,0x7f,0x6f};// 局部变量

  static unsigned char  posit=0;

    PORTC&=0X80; // turn off

     

          PORTC|=smg_wx[posit];//selecting led 7-segment 

         PORTD=~smg_zx[buff[posit]];  // 

        

  if(posit++>=3)posit=0;

        

         }




////////////////////////////////////////////////////////////

void smg_xs(void)

{


if((count<=20)||(flag==1))

{

if((on!=1)&&(on!=2))

{

xs_buff(jh_hour,jh_sec);

xs_smg();

}

else

{

if((on==1))

{ xs_buff_on(on_sec);

   xs_smg();

}

else if(on==2)

{PORTC&=0X80;on_sec=0;

PORTD=~smg_oFF[u];

PORTC|=smg_wx[u];if(u++>=2)u=0;

}

}

}

else

{PORTC&=0X80;count1=0;}

}

////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////

void motor(void)

if(on==1)

{PORTC|=0X80;flag=1;

}

else 

on_sec=0;

if(on==2){PORTC&=0X7F;flag=0;}//off状态下关闭电机

else if((jishi_sec>jh_hour1*3600)&&(jishi_sec<=jh_hour1*3600+jh_sec1))//大于设定的时间间隔和浇花时长


{PORTC|=0X80;//开电机

flag=1;}

else 

{   

     PORTC&=0X7F;flag=0;

   if(jishi_sec>jh_hour1*3600+jh_sec1)

   jishi_sec=0;

   



  }

///////////////////////////////////////////////////////////////////////////////////

        /// 按键子程序,实现按键值返回

uchar  key(void)

{ static uchar  key_zt=1, key_value;

   uchar  returnvalue=100; // 100表示无按键对应的一个数值

   switch(key_zt)  // 0b00000111  /0b00000110  //0b00000110

    {

        case 1:if((PINB&key_bz)!=key_bz) 

                 {key_value=PINB&key_bz;

                           key_zt=2;}  

                           break;

    case 2:  if((PINB&key_bz)==key_value) 

                 {key_zt=3;

                  switch(key_value)

                  {

                   case 0b00000110:  

                                returnvalue=1; //切换模式

                                        break;

                   case 0b00000101:

                                returnvalue=2;//在时分之间切换

                                        break; 

                  case 0b00000011:  

                                returnvalue=3;//在时分之间切换

                                        break; 

                       }

                       }else key_zt=1;  

                                 break;

    case 3: 

                if((PINB&key_bz)==key_bz)

                key_zt=1;  

                        break;

             }

      return  returnvalue;

       }

// 根据按键子程序返回的按键值去执行相应的功能

void key_process(void)

{  

   switch(key())

     {   case 1:count=0;count1++;if(count1>1){count1=2;if(on==0)/*只有on=0,回归正常显示界面才能加*/{if(jh_hour++>=99)jh_hour=0;}}break; //mode:0-计时,1,校准,2闹钟  // 模式切换


        case 2:count=0;count1++;if(count1>1){count1=2;if(on++>=2){on=0;jishi_sec=0;}}break;//每手动开启电机,jishi_sec就赋零

            case 3:count=0;count1++;if(count1>1){count1=2;if(on==0)/*只有on=0,回归正常显示界面才能加*/{if(jh_sec++>=99)jh_sec=0;}}break;

                }

                }

///////////////////////////////////////////////////////////////////////////////////////////////////

void sj_lj(void)

  {

  jishi_sec++;

  if(jishi_sec%3600==0&&jishi_sec!=0)jh_hour--;

  if(jh_hour==0){if(jh_sec--<=0){jh_hour=jh_hour1;jh_sec=jh_sec1;}}

}

//主函数////////////////////////////////////////////////////////////////////////////////////

void main(void)

{

jh_hour=jh_hour1;

jh_sec=jh_sec1;

init_devices();


   while(1)

   {

       

            motor();

                smg_xs();

       if(flag_1s==1)

           {flag_1s=0;

           sj_lj();}

       if(flag_10ms==1)

           {flag_10ms=0;

           key_process();}

   }

  }


/////////////////

//////////////

        

//T0中断服务程序 //  2ms 进入中断

   #pragma interrupt_handler timer0_ocf_isr:20

  void timer0_ocf_isr(void)

  {static uint_16  count_1s=0,count_10ms=0,count_5s=0;


   if(++count_10ms>=5)

   { count_10ms=0;

     flag_10ms=1;

     if(++count_1s>=100)

     {count_1s=0;

          flag_1s=1;

          count++;

          if(on==1)

          on_sec++;

          }

          }

          }



关键字:avr单片机  atmega16  自动浇花器  Proteus仿真 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单