找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3812|回复: 1
打印 上一主题 下一主题
收起左侧

PIC12F629单片机定时器1控制3个LED循环源程序,且时间可调

[复制链接]
跳转到指定楼层
楼主
ID:815949 发表于 2020-9-5 22:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PIC12F629不用外振即可正常运行,低成本首选,原理如下:按键按一次LED1低亮,按两次LED2亮,按三次LED3亮,一直循环, 按键长按3秒松开则可以计入自动循环模式,再次长按3秒则退出,进入待机模式;2脚接轻触开关到地,可以做为设置键(原理图来自网上故VDD接﹢5V,漏画,SET设置键没有画,有时间修正下原理图),用来设置每个LED亮的时间,互不影响!源码已经编译通过,洞洞板做了一个PCB, 正常运行,新手贴勿喷。

单片机源程序如下:
  1. /******************************************************************************
  2. 设计要求:按一次按键是打开第一个摄像头,按两次开第二个摄像头,按三次打开第三个摄像头,
  3. 长按3秒则开启循环模式,每次开启时间30秒,一直循环,直到按下按键为止.
  4. * IC: PIC12F629        OSC: 片内4MHz
  5. *****************************************************************************/
  6. #include <pic.h>

  7. #define uchar unsigned char
  8. #define uint unsigned int

  9. #define LED1  GPIO0
  10. #define LED2  GPIO1
  11. #define LED3  GPIO2
  12. #define KEY    GPIO4
  13. #define SET    GPIO5

  14.            

  15. __CONFIG(FOSC_INTRCIO & WDTE_ON & PWRTE_ON & MCLRE_OFF &  BOREN_ON);

  16. /*********  配置字 ************/


  17. void interrupt ISR( void) ;
  18. void delay(uint x);
  19. void IOinit (void) ;
  20. void TMR1init(void) ;

  21. uint  time = 0;
  22. uint  t =0;
  23. uchar cnt =0;
  24. uchar  cnt1 = 0;
  25. uchar  cnt2 = 0;
  26. uchar  i , k = 0;


  27. void IOinit (void)
  28. {
  29.        PCON = 0X00;                  // 电源控制全关
  30.        CMCON = 0X07;               //关模拟器
  31.          TRISIO = 0X38;                // 00111000 GP<5:3>输入 GP<2:0>输出
  32.          GPIO = 0X3F;                   // 00111111 GP<2:0>输出高电平
  33.          WPU = 0X30;                   // GP<5:4>内部弱上拉开启
  34.          IOC = 0X30;                     //GP<5:4>端口电平变化中断使能
  35.   }


  36. void TMR1init (void)
  37. {
  38.        OPTION_REG = 0X0F;     //  PSA =1, PS2:PS0 =111  开看门狗  预分频128 其余的关
  39.          INTCON = 0XC0 ;              // GIE = 1 , PEIE = 1    开全局中断  开外设中断  其余的关
  40.          PIE1 = 0X01;                    // 外设中断使能
  41.          PIR1 = 0X00;                    // TMR1IF = 1   开TIMR1 外设中断标志位,需要软件清零
  42.          TMR1H = 0X3C;               //TIMER1初值 溢出时间是50000(50ms)
  43.          TMR1L = 0XB0;               // 65536- 50000 = 15536 (0x3CB0)
  44.          T1CON = 0X01;                 // 开TIMR1
  45. }






  46. void main ( )
  47. {   
  48.       IOinit () ;
  49.       TMR1init() ;

  50. //主循环
  51.     while(1)
  52.     {      
  53.            if(i==0 )
  54.               {
  55.                  if(SET==0)
  56.                     {
  57.                     delay(10);
  58.                     if(SET==0)
  59.                         {
  60.                         
  61.                         while(!SET);
  62.                         k=!k;
  63.                         cnt=0;
  64.                         cnt1=0;
  65.                         LED3=!LED3;
  66.                          }
  67.                       }
  68.            
  69.                }
  70.             if(KEY == 0)        //如果按键按下
  71.               {   
  72.                      delay(20);
  73.                      if(KEY == 0)
  74.                        {  
  75.                         time = 0;        //延时标志位清零
  76.                         while(!KEY);    //等待按键被松开,由中断函数计数

  77.                         if(time<40)     //按下时间不足50ms*40=2000毫秒(2秒)
  78.                            {
  79.                                if (k==0)
  80.                                   {
  81.                                      cnt1++;      //按键次数加1,改变工作状态
  82.                                      if(cnt1>3)  cnt1 = 0;
  83.                                     }
  84.                                else if( k==1)  
  85.                                      {
  86.                                      cnt++;
  87.                                      if (cnt>10) cnt=0;
  88.                                      t=cnt*100;
  89.                                      LED1 =0;
  90.                                      delay(20);
  91.                                      LED1 =1;
  92.                                       }
  93.                                }
  94.                          if(time >= 40 && time < 100)   //按住时间2秒到5秒之间
  95.                              {
  96.                                                 i = !i;
  97.                                                 time =0;
  98.                                                 cnt2 =0;
  99.                                                 cnt1=0;
  100.                                         }
  101.                          else if (time >=100)
  102.                               {
  103.                                break;
  104.                               }
  105.                           }
  106.                       
  107.                                             
  108.                   }
  109.              if (k==0 )  
  110.                  {
  111.                            if (i == 1)
  112.                          { switch (cnt2)
  113.                            { case 0:
  114.                           
  115.                             GPIO  =0X3E;  //00111110  开1号继电器
  116.                             break;
  117.                           
  118.                             case 1:
  119.                         
  120.                             GPIO  =0X3D;  //00111101  开2号继电器
  121.                             break;
  122.                         
  123.                             case 2:
  124.                         
  125.                             GPIO  =0X3B;  //00111011  开3号继电器
  126.                               break;
  127.                                      
  128.                               default:
  129.                               break;
  130.                                 }
  131.                                }
  132.                           if (i==0  )
  133.                           {
  134.                             switch(cnt1)             //检测按键按下次数
  135.                              {
  136.                             case 0:
  137.                                     GPIO = 0x3F;
  138.                                     
  139.                                     break;   // 没有按键按下 全关
  140.                                 case 1:
  141.                                     GPIO  =0X3E;  //00111110  开1号继电器
  142.                                     break;  //  按一下打开RELAY1  2,3关
  143.                             case 2:
  144.                                     GPIO  =0X3D;  //00111101  开2号继电器
  145.                                     break;         
  146.                             case 3:
  147.                             GPIO  =0X3B;  //00111011  开3号继电器
  148.                                   break;
  149.                                
  150.                             default:
  151.                             break;
  152.                                }
  153.             



  154.                            }
  155.                
  156.                   }   
  157.      
  158.             
  159.         }
  160. }
  161. /******************************************************************************
  162. *                           中断处理函数
  163. *****************************************************************************/
  164. void interrupt ISR( void)
  165. {
  166.     if(TMR1IF == 1)      //定时器1溢出中断
  167.     {
  168.         asm ("CLRWDT");     //定时喂狗
  169.         ++time;             //延时计数
  170.                 if (time == t)    //t 是设定时间
  171.                     {
  172.                               time = 0;
  173.                         cnt2++;
  174.                               if( cnt2 > 2 )  //每加一次是t 秒
  175.                                  {
  176.                                     cnt2 = 0;
  177.                                
  178.                                   }
  179.                                
  180.                     }
  181.         TMR1H = 0x3C;       //重设TIMER1初始值使TMR1溢出时间为50000个时钟周期
  182.         TMR1L = 0xB0;
  183.         TMR1IF = 0;         //定时器1溢出中断标志位清零
  184.     }
  185. }


  186. void delay(uint x)
  187. {
  188.         uint a,b;
  189.         for(a=x;a>0;a--)
  190.                 for(b=71;b>0;b--);       
  191. }
复制代码

所有资料51hei提供下载:
KEY for DELAY.zip (70.56 KB, 下载次数: 37)
原理图.pdf (158.07 KB, 下载次数: 29)
12F629.pdf (2.41 MB, 下载次数: 13)



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:815949 发表于 2020-9-13 10:19 | 只看该作者
PC12F629使用的IO口弱上拉,主要是考虑到输出电流小的原因,外接的限流电阻尽量选大一点,保证IO口灌电流<5mA
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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