找回密码
 立即注册

QQ登录

只需一步,快速开始

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

可定义亮度的PWM调光LED灯制作 附pic单片机源程序

[复制链接]
跳转到指定楼层
楼主
一直想打造一个自己的调光台灯,于是动手焊接硬件,编写自己的单片程序,经过调试初步达到要求,没有条件打板,自己用万能板焊接的电路,用来控制12V的长条LED实际效果还行!
主要功能:
1、  关机时短按一次开灯,亮度为关机时的档位,开机时长按三秒关灯,关灯时为渐灭灯的效果;
2、  开机时单按为亮度档位切换,分为1,2,3档;
3、  开机时连按三次按键,可进入当前档位的亮度PWM值设定,此时led闪烁,单击按键为亮度增加,双击按键为亮度减小,长按则快速增加亮度(类似呼吸灯的效果),再次三击为保存PWM值退出亮度设置;
4、  可以分别对三个档位的PWM亮度值进行设定,以适合不同的LED组合;
5、  增加了7805稳压,输入电压为6~30V;
6、  TIP31加散热片后电子负载测试电流800mA有微热,基本可满足常用台灯的要求;

焊接完成的图片:
线路图:
测试效果:

如下程序主要体现为PWM调光的部分,按键功能部分请参考我的另一个贴子:
PIC单片机单个按键实现多功能:长按、短按次数识别程序

单片机源程序如下:
  1.     PWM程序部分:
  2.     #include<pic.h>
  3.     //PIC16F690 PWM三档自定议台灯
  4.     voidmain(void)

  5.     {
  6.          IRQ_init();
  7.          port_init();
  8.          RC4            =0;
  9.          pwm_cnt     =0;
  10.          CCPR1        =pwm_hz+5;  //开机的瞬间LED输出最大亮,设为65可以改善为开机即为程序默认亮度级
  11.          dan            =1;
  12.          
  13.          
  14.         pwm_1=    eeprom_read(0x01); if(pwm_1>pwm_hz+5 ||pwm_1 <0) pwm_1 = 115;
  15.         pwm_2=    eeprom_read(0x02); if(pwm_2>pwm_hz+5 ||pwm_2 <0) pwm_2 = 60;
  16.         pwm_3=    eeprom_read(0x03); if(pwm_3>pwm_hz+5 ||pwm_3 <0) pwm_3 = 10;
  17.         dan =     eeprom_read(0x04);if(dan> 3 ||dan <1) dan = 1;


  18.       
  19.     while(1)
  20.     {
  21.           key_scan();    //对应按次处理
  22.          write_eeprom();
  23.     }
  24.     }  

  25.     ////////////////////////////////////////////////////////////////
  26.     voidinterrupt init1(void)
  27.     {
  28.     /***用TIMER0中断作的24H计时程序***/
  29.         if(T0IF)
  30.         {            
  31.       TMR0=61;
  32.       T0IF=0;
  33.            ss_2++;if(ss_2>5){ss_2=0;}   //1/4秒 2500ms
  34.            ss_4++;if(ss_4>80){ss_4=0;}  //1/2秒 5000ms
  35.        ss++;if(ss>80) s_led=1;
  36.       if(ss>=160){s_led=0;
  37.                 ss=0;
  38.                 s++;
  39.                 if(s>=60) {
  40.                          s=0;
  41.                          m++;
  42.                   if(m>=60){
  43.                                   m=0;
  44.                                   h++;
  45.                                   if(h>=24)h=0;}
  46.                          }
  47.                       }
  48.     /***用TIMER0中断作的24H计时程序***/


  49.     /******设置时的快亮度加效果******/
  50.     if(set_mode==1)
  51.     {
  52.                 if(key_long_flag&&sw1==0)
  53.                 {
  54.                 if(ss_2==0) CCPR1++;
  55.                 if(CCPR1>pwm_hz+5)CCPR1=0;
  56.                
  57.                 } elseif(sw1==1&&key_long_flag) {key_long_flag=0;save_flag=1;}  
  58.     }
  59.     /******设置时的快亮度加效果******/
  60.                            
  61.     /**********关机渐灭控制**********/

  62.             if(on_flag){//if(CCPR1>50&&CCPR1<64){if(s%6==0){CCPR1++;}}
  63.                         if(CCPR1<pwm_hz+5){if(ss_2==0){CCPR1++;}
  64.                         }
  65.     /**********关机渐灭控制**********/
  66.       
  67.        }
  68.          
  69.          }

  70.     //////////////////////////////////////////////////////////////
  71.            


  72.     //**************************************//
  73.     //Write eeprom
  74.     //**************************************//
  75.     void write_eeprom()
  76.     {
  77.       if(save_flag)
  78.        {
  79.                         if(dan==1){pwm_1=CCPR1;}
  80.                else if(dan==2){pwm_2=CCPR1;}
  81.                else if(dan==3){pwm_3=CCPR1;}
  82.        eeprom_write(0x01,pwm_1);
  83.        eeprom_write(0x02,pwm_2);
  84.        eeprom_write(0x03,pwm_3);
  85.        eeprom_write(0x04,dan  );
  86.         delay_ms(1);
  87.         save_flag=0;
  88.       
  89.        }
  90.     }
  91.     //**************************************//



  92.     //////长短按键处理end///////

  93.     void key_scan()
  94.     {
  95.        push_scan();
  96.       
  97.        //----开关机键处理-----//
  98.       if(set_mode==0){
  99.        se_flag=key_long_flag; key_long_flag=0; //长按开关机键
  100.       if((yao_se_flag||se_flag)&&on_lock_flag==0)
  101.       {
  102.          //////////关机前先灭下灯
  103.           CCPR1=pwm_hz+5;delay_ms(30);

  104.           if(dan==1)CCPR1=pwm_1;
  105.           else if(dan==2)CCPR1=pwm_2;
  106.           else if(dan==3)CCPR1=pwm_3;
  107.             on_flag=~on_flag;
  108.           on_lock_flag=1;
  109.               se_flag=0;
  110.               yao_se_flag=0;
  111.       }else if(se_flag==0&&on_lock_flag==1) on_lock_flag=0;
  112.     }
  113.     //---------------------//

  114.     if(on_flag)//关机状态下
  115.     {
  116.     set_mode=0;
  117.     if(key_num==1) { up_flag=1;key_num=0;}   //单击加键识别
  118.     //关机状态单按即开机
  119.     if(up_flag)
  120.     {
  121.     up_flag=0;
  122.     //dn_flag=0;
  123.     on_flag=0;
  124.     }
  125.     }

  126.     //---------------------//
  127.     else if(on_flag==0)  //开机状态下 进下如下按键操作
  128.     {
  129.        if(key_num==1) { up_flag=1;key_num=0;}   //单击加键识别
  130.        if(key_num==2) { dn_flag=1;key_num=0;}   //双击减键识别
  131.        if(key_num==3) {thr_flag=1;key_num=0;}   //三击设置识别
  132.        //---------------------//
  133.        //三按在正常工作模式与设置模式切换
  134.         if((yao_thr_flag||thr_flag)&&set_sw_flag==0/*&&dismode==0*/)  
  135.         {
  136.           set_mode++;
  137.           if(set_mode>1)set_mode=0;
  138.           set_sw_flag=1;
  139.           thr_flag=0;yao_thr_flag=0;
  140.           } else if(thr_flag==0&&set_sw_flag==1) set_sw_flag=0;
  141.        //---------------------//
  142.       
  143.        //---------------------//
  144.       
  145.        if(set_mode==0)//档位加处理
  146.        {
  147.           if((yao_dn_flag||yao_up_flag||up_flag||dn_flag)&&short_temp_flag==0)
  148.           {
  149.           dan++;
  150.           if(dan>3)dan=1;
  151.           short_temp_flag=1;
  152.           up_flag=0;
  153.           dn_flag=0;
  154.           yao_up_flag=0;
  155.           yao_dn_flag=0;
  156.           save_flag=1;
  157.          
  158.          } else {if(up_flag==0&&short_temp_flag==1) short_temp_flag=0;}  
  159.          
  160.                    if(dan==1) CCPR1=pwm_1;
  161.                 else if(dan==2)CCPR1=pwm_2;
  162.                 else if(dan==3)CCPR1=pwm_3;
  163.                
  164.       
  165.        }
  166.         //---------------------//
  167.       
  168.         //---------------------//
  169.        else if(set_mode==1)//设置各档位的PWM值
  170.        {

  171.          
  172.          
  173.             if(up_flag||yao_up_flag)
  174.                 {
  175.                 CCPR1++;
  176.                 up_flag=0;
  177.                 yao_up_flag=0;
  178.                 if(CCPR1>pwm_hz+5)CCPR1=0;
  179.                 save_flag=1;
  180.                 }        
  181.               if(dn_flag||yao_dn_flag)
  182.                 {
  183.                 CCPR1--;
  184.                 dn_flag=0;
  185.                 yao_dn_flag=0;
  186.                 if(CCPR1<1)CCPR1=pwm_hz+5;
  187.                 save_flag=1;
  188.                 }   
  189.       
  190.        else{if(s_led){
  191.                      pwm_stop=0;
  192.                      if(dan==1){pwm_1=CCPR1;}
  193.                else if(dan==2){pwm_2=CCPR1;}
  194.                else if(dan==3){pwm_3=CCPR1;}
  195.              }
  196.       
  197.        else if(key_long_flag==0){pwm_stop=1;}SCR_OUT=0;}
  198.        }
  199.       
  200.        //---------------------//
  201.       

  202.     }   
  203.       /////////////////////  

  204.     }

  205.     void port_init(void)
  206.     {

  207.        TRISA=0b00010100; //RA0,1为PWM设置键
  208.        TRISB=0x01;       //RBO为中断输入
  209.        TRISC=0b00000000;

  210.        ANSEL=0b00000000;
  211.        ANSELH=0X00;

  212.        PORTA=0X00;
  213.        PORTB=0X00;
  214.        PORTC=0X00;

  215.     }
  216.     ///////////////////////////
复制代码

//------------------------------------------------------------------------------------------------------------   void IRQ_init(void)//定时A和外部中断1初始化   {   GIE=0;      //关总中断   //RBIE=0;     //RB口电平变化中断禁止   //---------CPU频率配置-------  //IRCF<2:0>:内部振荡器频率选择位  IRCF2= 1 ;  IRCF1= 1 ;  IRCF0= 1 ;   //000 = 31 kHz  //001 = 125 kHz  //010 = 250 kHz  //011 = 500 kHz  //100 = 1 MHz  //101 = 2 MHz  //110 = 4 MHz (缺省值)  //111 = 8 MHz   RABPU=0; //AB口上拉起动  WPUA0=1;  WPUA1=1;  //WPUA4=1;  //WPUA5=1;  WPUA2=1;   //-------定时器time0的配置-----  T0IF=0;     //清中断标志  T0IE=1;     //允许Time0中断    TMR0=61;    //256-61    T0CS=0;     //Time0选择内部时钟  T0SE=0;     //外部电平低至高变化递增  PSA =0;     //预分频给Time0  PS2 =1;     //111为1:256分频   PS1 =0;  PS0 =1;  //PS<2:0>:预分频器比选择位  //000 1 : 2  //001 1 : 4  //010 1 : 8  //011 1 : 16  //100 1 : 32  //101 1 : 64  //110 1 : 128  //111 1 : 256 //----------------------------  PEIE=1; //允许外围中断   GIE=1; //开总中断    }

台灯Layout-3.jpg (129.63 KB, 下载次数: 91)

台灯Layout-3.jpg

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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