单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 88|回复: 0
收起左侧

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

[复制链接]
哈哈151- 发表于 2019-5-14 18:06 | 显示全部楼层 |阅读模式
这是最近做的自动浇花系统,用atmega16内部定时器做的。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

单片机源程序如下:
  1. #include <iom16v.h>
  2. #include <macros.h>
  3. #define  key_bz   0b00000111
  4. #define uchar  unsigned char
  5. #define  uint_16  unsigned short
  6. char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x37};// 全局变量
  7. char smg_wx[]={0B00000001,0B00000010,0B00000100,0b00001000};
  8. char  smg_oFF[]={0x3f,0X71,0X71};
  9. unsigned int flag_10ms=0,flag_1s=0,on=0,buff[]={0,0,0},mode=0;
  10. unsigned  int jh_hour1=2,u=0,count=0,count1=2,on_sec=0;
  11. unsigned int jh_sec1=5,jh_hour=0,jh_sec=0,flag=0;


  12. unsigned long int jishi_sec=0;
  13. void delay_ms(unsigned int k)                       
  14. {
  15.     unsigned int i,j;
  16.     for(i=0;i<k;i++)
  17.     {
  18.       for(j=0;j<570;j++);
  19.     }
  20. }
  21. // 用定时器实现定时
  22. void T0_init(void)// 端口初始化函数
  23. {
  24. TIFR=0XFF;
  25. TCCR0=0X0B; //64FENPIN, CTC MODE
  26. TCNT0=0;
  27. OCR0=250;
  28. TIMSK=0X02;
  29. }

  30. void port_init(void)// 端口初始化函数
  31. {
  32.   DDRC|=0b10001111;  // PC4 5 OUT PUT
  33.   PORTC=0b11110000; //m103 output only

  34. PORTD= 0xFF;
  35. DDRD= 0xff;
  36. DDRB&= 0b11111000;  
  37. PORTB|=0B00000111;

  38. }

  39. void init_devices(void)
  40. {

  41. CLI(); //disable all interrupts
  42. port_init();//smg_zx[0]=1;
  43. T0_init();
  44. SEI(); //re-enable interrupts

  45. }



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

  47. void xs_buff(uchar va1, uchar va2)
  48. {
  49.   buff[0]=va1/10;
  50.   buff[1]=va1%10;
  51.   buff[2]=va2/10;
  52.   buff[3]=va2%10;
  53.   
  54. }
  55. void xs_buff_on( uchar va2)
  56. {
  57.   buff[0]=0;
  58.   buff[1]=10;
  59.   buff[2]=va2/10;
  60.   buff[3]=va2%10;
  61. }


  62. void xs_smg()
  63. {//char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
  64.   // 0x7d,0x07,0x7f,0x6f};// 局部变量
  65.   static unsigned char  posit=0;
  66.     PORTC&=0X80; // turn off
  67.      
  68.           PORTC|=smg_wx[posit];//selecting led 7-segment
  69.          PORTD=~smg_zx[buff[posit]];  //
  70.        
  71.   if(posit++>=3)posit=0;
  72.        
  73.          }



  74. ////////////////////////////////////////////////////////////
  75. void smg_xs(void)
  76. {

  77. if((count<=20)||(flag==1))
  78. {
  79. if((on!=1)&&(on!=2))
  80. {
  81. xs_buff(jh_hour,jh_sec);
  82. xs_smg();
  83. }
  84. else
  85. {
  86. if((on==1))
  87. { xs_buff_on(on_sec);
  88.    xs_smg();
  89. }
  90. else if(on==2)
  91. {PORTC&=0X80;on_sec=0;
  92. PORTD=~smg_oFF[u];
  93. PORTC|=smg_wx[u];if(u++>=2)u=0;
  94. }
  95. }
  96. }
  97. else
  98. {PORTC&=0X80;count1=0;}
  99. }
  100. ////////////////////////////////////////////////////////////////////////////////////

  101. ////////////////////////////////////////////////////////////////////////////////////
  102. void motor(void)
  103. {
  104. if(on==1)
  105. {PORTC|=0X80;flag=1;
  106. }
  107. else
  108. {
  109. on_sec=0;
  110. if(on==2){PORTC&=0X7F;flag=0;}//off状态下关闭电机
  111. else if((jishi_sec>jh_hour1*3600)&&(jishi_sec<=jh_hour1*3600+jh_sec1))//大于设定的时间间隔和浇花时长

  112. {PORTC|=0X80;//开电机
  113. flag=1;}
  114. else
  115. {   
  116.      PORTC&=0X7F;flag=0;
  117.    if(jishi_sec>jh_hour1*3600+jh_sec1)
  118.    jishi_sec=0;
  119.    
  120. }


  121. }
  122.   }
  123. ///////////////////////////////////////////////////////////////////////////////////
  124.         /// 按键子程序,实现按键值返回
  125. uchar  key(void)
  126. { static uchar  key_zt=1, key_value;
  127.    uchar  returnvalue=100; // 100表示无按键对应的一个数值
  128.    switch(key_zt)  // 0b00000111  /0b00000110  //0b00000110
  129.     {
  130.         case 1:if((PINB&key_bz)!=key_bz)
  131.                  {key_value=PINB&key_bz;
  132.                            key_zt=2;}  
  133.                            break;
  134.     case 2:  if((PINB&key_bz)==key_value)
  135.                  {key_zt=3;
  136.                   switch(key_value)
  137.                   {
  138.                    case 0b00000110:  
  139.                                 returnvalue=1; //切换模式
  140.                                         break;
  141.                    case 0b00000101:
  142.                                 returnvalue=2;//在时分之间切换
  143.                                         break;
  144.                   case 0b00000011:  
  145.                                 returnvalue=3;//在时分之间切换
  146.                                         break;
  147.                        }
  148.                        }else key_zt=1;  
  149.                                  break;
  150.     case 3:
  151.                 if((PINB&key_bz)==key_bz)
  152.                 key_zt=1;  
  153.                         break;
  154.              }
  155.       return  returnvalue;
  156.        }
  157. // 根据按键子程序返回的按键值去执行相应的功能
  158. void key_process(void)
  159. {  
  160.    switch(key())
  161.      {   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闹钟  // 模式切换

  162.         case 2:count=0;count1++;if(count1>1){count1=2;if(on++>=2){on=0;jishi_sec=0;}}break;//每手动开启电机,jishi_sec就赋零
  163.             case 3:count=0;count1++;if(count1>1){count1=2;if(on==0)/*只有on=0,回归正常显示界面才能加*/{if(jh_sec++>=99)jh_sec=0;}}break;
  164.                 }
  165.                 }
  166. ///////////////////////////////////////////////////////////////////////////////////////////////////
  167. void sj_lj(void)
  168.   {
  169.   jishi_sec++;
  170.   if(jishi_sec%3600==0&&jishi_sec!=0)jh_hour--;
  171.   if(jh_hour==0){if(jh_sec--<=0){jh_hour=jh_hour1;jh_sec=jh_sec1;}}
  172. }
  173. //主函数////////////////////////////////////////////////////////////////////////////////////
  174. void main(void)
  175. {
  176. jh_hour=jh_hour1;
  177. jh_sec=jh_sec1;
  178. init_devices();

  179.    while(1)
  180.    {
  181.       
  182.             motor();
  183.                 smg_xs();
  184.        if(flag_1s==1)
  185.            {flag_1s=0;
  186.            sj_lj();}
  187.        if(flag_10ms==1)
  188.            {flag_10ms=0;
  189.            key_process();}
  190.    }
  191.   }

  192. /////////////////
  193. //////////////
  194.        
  195. //T0中断服务程序 //  2ms 进入中断
  196.    #pragma interrupt_handler timer0_ocf_isr:20
  197.   void timer0_ocf_isr(void)
  198.   {static uint_16  count_1s=0,count_10ms=0,count_5s=0;

  199.    if(++count_10ms>=5)
  200.    { count_10ms=0;
  201.      flag_10ms=1;
  202.      if(++count_1s>=100)
  203.      {count_1s=0;
  204.           flag_1s=1;
  205.           count++;
  206.           if(on==1)
  207.           on_sec++;
  208.           }
  209.           }
  210.           }
复制代码

所有资料51hei提供下载:
新建文件夹.rar (32.6 KB, 下载次数: 2)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛5群 联系QQ:125739409;技术交流QQ群174280738

Powered by 单片机教程网

快速回复 返回顶部 返回列表