原创 3W LED手电筒驱动电路

2010-7-12 21:48 8048 4 5 分类: 消费电子
电路功能:单锂3WLED恒流驱动,3.0V-4.2V全程恒流,最大可输出700mA(实际可达1000mA);
          四种档位模式:1.三档调光+暴闪+慢闪+SOS+信标;
                        2.三档调光+暴闪+SOS;
                        3.二档调光;
                        4.六档调光+暴闪+慢闪+SOS+信标;
          有记忆功能;
          只有一个电源开关控制,关机关电源,完全不耗电;
          电池过放保护,电压低于3V进入应急模式自动切换到30mA,电压低于2.7V进入休眠模式。 

点击看大图
 (原文件名:3454.jpg) 

引用图片


有两种不同的代码,开机记忆或关机记忆
/*****************************************************
Chip type           : ATtiny13
Clock frequency     : 4.800000 MHz
Memory model        : Tiny
External SRAM size  : 0
Data Stack size     : 16
四组档位模式,关闭2秒记忆
*****************************************************/
//#define DEBUG2
//#define debug
#include <tiny13.h>
#include <delay.h>
#define CHANGE_WAITING  62
#define MAX_CURRENT  920
#define VOLTAGE_LIMIT_TO_30mA   5233  //5233=3.2V 4812=3.0V
#define VOLTAGE_OUT_OFF         4331  //4331=2.7V
#define VOLTAGE_CHANGE          1000  //定义开机后是否变换档位的电压值,如大于此值则变换档位,否则用上次关机时的档位
#define K1 318682                     //由于3454在压控恒流模式工作时输出电流会随电池电压降低而升高,为了做到真正的恒流,引入K1、K2根据电池电压对控制电压进行修正。
#define K2 341
#define XINGBIAO 3
#define MAX_DANGWEI  9 

#define ADEN ADCSRA.7
#define ADSC ADCSRA.6
#define EN_30mA PORTB.5
#define EN_PWM  PORTB.1
#define WDCE 4
#define WDE  3
eeprom unsigned char null;
eeprom unsigned char circle=2;
flash unsigned char time_set[3][18]=
                                      {
                                       {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},       // bao frash
                                       {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16},        // flash
                                       {4,8,4,8,4,25,12,8,12,8,12,25,4,8,4,8,4,50}    // sos  亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(3.5秒)-〉亮(1.5秒)-〉暗(1秒)-〉亮(1.5秒)-〉暗(1秒)-〉亮(1.5秒)-〉暗(3.5秒)-〉亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(3.5秒)
                                      };    

flash unsigned int i_set[MAX_DANGWEI+1]=
                                   {
                                    920,
                                    700,
                                    700,
                                    50,     //xingbiao
                                    920,
                                    700,
                                    480,
                                    348,
                                    135,
                                    20
                                   };   
                                  

bit flashing_on_off;
bit adc_busy;
bit check_change_circle;
unsigned char temp;
unsigned char lower_times;
unsigned char time_flash,frash_count;

// Watchdog timeout interrupt service routine
interrupt [WDT] void wdt_timeout_isr(void)
{

if( temp!=XINGBIAO)
{
 time_flash++;
 WDTCR|=0x40;
 
 if( temp<3)
    {
     if(time_flash>time_set[temp][frash_count])
        {
         time_flash=0;
         frash_count++;
         if(frash_count>17)
           { 
            frash_count=0;
            flashing_on_off=1;
           }
         else
           flashing_on_off=~flashing_on_off; 
        
        }
    }
 }     
}
#ifndef DEBUG2
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
unsigned int  adc_result;
adc_result=10*ADCW;
if(check_change_circle==1)
  {
   check_change_circle=0;
   if(adc_result>VOLTAGE_CHANGE)
      {
       temp++;
       switch (PINB&0x18)
         {
          case 0x08:           //PB4 接地,三档调光+暴闪+慢闪+SOS+信标
               {
               if(temp>4)
                 temp++;
               }break;
          case 0x10:          //PB3 接地, 三档调光+暴闪+SOS
               {
                 temp++;
               }break; 
          case 0x00:          //PB3、PB4 接地,二档调光
               {
                temp=temp==5?7:4;
               }break;
          default: break;     //没有连接,六档调光+暴闪+慢闪+SOS+信标 
         } 
       
       if(temp>MAX_DANGWEI)
          temp=0;  
       circle=temp; 
      }   
  } 

 if(adc_result<VOLTAGE_OUT_OFF)
   {
    EN_PWM=0;
    #ifndef debug
    EN_30mA=0;
    #endif 
   }
 else
   {
    if(adc_result<VOLTAGE_LIMIT_TO_30mA)
       {
        lower_times++;
        if(lower_times>10)
           {
            TCCR0B=0x00;
            EN_PWM=0;
            #ifndef debug
            EN_30mA=flashing_on_off;
            #endif 
           } 
       }
    else
       {
        lower_times=0;
        EN_PWM=flashing_on_off;
        #ifndef debug
        EN_30mA=0; 
        #endif
        OCR0A=(unsigned char)((K1-(unsigned long)K2*i_set[temp])/(adc_result));
       }   
   }   
 
  adc_busy=0;
}
#endif
// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{

 if(adc_busy==0) 
    {
    ADSC=1;
    adc_busy=1;
    }
}

void main(void)
{

#pragma optsize-
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

//PORTB=0x19;
//DDRB=0x23;



flashing_on_off=1;
lower_times=0;
time_flash=0;
frash_count=0;
#asm("sei")
temp=circle;

TIMSK0=0x04;
DIDR0=0x0F;
ADMUX=0x41;
ADCSRA=0x8D;

#pragma optsize-
WDTCR |= (1<<WDCE) | (1<<WDE);
WDTCR=0x41;   //64ms
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif 

OCR0A=200;
TCCR0A=0x83;
TCCR0B=0x01;
   
check_change_circle=1;
ADSC=1;
adc_busy=1;
while(check_change_circle==1)
     ; 
     
delay_ms(1);   
  
while (1)
    {
     if(temp==XINGBIAO)
      {
       EN_30mA=1;
       delay_ms(50);
       EN_30mA=0;
       #pragma optsize-
       WDTCR |= (1<<WDCE) | (1<<WDE);
       WDTCR=0x60;   //4s
       #ifdef _OPTIMIZE_SIZE_
       #pragma optsize+
       #endif
       MCUCR=0x20;
       #asm("sleep");
       #asm("NOP");
      }
     
    } 
}


/*****************************************************
Chip type           : ATtiny13
Clock frequency     : 4.800000 MHz
Memory model        : Tiny
External SRAM size  : 0
Data Stack size     : 16  
四组档位模式,两秒连续内按开关换档,点亮超过2秒记忆当前档,
*****************************************************/
//#define DEBUG2
//#define debug
#include <tiny13.h>
#include <delay.h>
#define CHANGE_WAITING  62
#define MAX_CURRENT  920
#define VOLTAGE_LIMIT_TO_30mA   5233  //5233=3.2V 4812=3.0V
#define VOLTAGE_OUT_OFF         4331  //4331=2.7V
#define K1 333167       //由于3454在压控恒流模式工作时输出电流会随电池电压降低而升高,为了做到真正的恒流,引入K1、K2根据电池电压对控制电压进行修正。
#define K2 292
#define XINGBIAO 3
#define MAX_DANGWEI  9 

#define ADEN ADCSRA.7
#define ADSC ADCSRA.6
#define EN_30mA PORTB.5
#define EN_PWM  PORTB.1
#define WDCE 4
#define WDE  3
eeprom unsigned char null;
eeprom unsigned char change_needed=0;
eeprom unsigned char circle=2;
flash unsigned char time_set[3][18]=
                                      {
                                       {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},       // bao frash
                                       {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16},        // flash
                                       {4,8,4,8,4,25,12,8,12,8,12,25,4,8,4,8,4,50}    // sos  亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(3.5秒)-〉亮(1.5秒)-〉暗(1秒)-〉亮(1.5秒)-〉暗(1秒)-〉亮(1.5秒)-〉暗(3.5秒)-〉亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(1秒)-〉亮(0.5秒)-〉暗(3.5秒)
                                      };    

flash unsigned int i_set[MAX_DANGWEI+1]=
                                   {
                                    650,
                                    650,
                                    650,
                                    50,     //xingbiao
                                    1000,
                                    750,
                                    520,
                                    350,
                                    180,
                                    50
                                   };   
                                  

bit flashing_on_off;
bit adc_busy;
unsigned char temp;
unsigned char time,lower_times;
unsigned char time_flash,frash_count;

// Watchdog timeout interrupt service routine
interrupt [WDT] void wdt_timeout_isr(void)
{

if( temp!=XINGBIAO)
{
 time_flash++;
 WDTCR|=0x40;
 if(time<CHANGE_WAITING)
   time++;
 else
   {
    if(change_needed!=0)
       change_needed=0; 
   }    
 if( temp<3)
    {
     if(time_flash>time_set[temp][frash_count])
        {
         time_flash=0;
         frash_count++;
         if(frash_count>17)
           { 
            frash_count=0;
            flashing_on_off=1;
           }
         else
           {
            
            flashing_on_off=~flashing_on_off; 
            
           } 
        
        }
    }
 }     
}
#ifndef DEBUG2
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
unsigned int  adc_result;
adc_result=10*ADCW;

{
 if(adc_result<VOLTAGE_OUT_OFF)
   {
    EN_PWM=0;
    #ifndef debug
    EN_30mA=0;
    #endif 
   }
 else
   {
    if(adc_result<VOLTAGE_LIMIT_TO_30mA)
       {
        lower_times++;
        if(lower_times>10)
           {
            TCCR0B=0x00;
            EN_PWM=0;
            #ifndef debug
            EN_30mA=flashing_on_off;
            #endif 
           } 
       }
    else
       {
        lower_times=0;
        EN_PWM=flashing_on_off;
        #ifndef debug
        EN_30mA=0; 
        #endif 
        if(flashing_on_off==0)
            {
            OCR0A=200;
            }
        else
            {
            OCR0A=(unsigned char)((K1-(unsigned long)K2*i_set[temp])/(adc_result));
            }   
        
       }   
   }   
 }
  adc_busy=0;
}
#endif
// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{

 if(adc_busy==0) 
    {
    ADSC=1;
    adc_busy=1;
    }
}

void main(void)
{

#pragma optsize-
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

//PORTB=0x19;
//DDRB=0x23;

TCCR0A=0x83;

flashing_on_off=1;
time=0;
lower_times=0;
time_flash=0;
frash_count=0;

#asm("sei") 
temp=circle;

if(change_needed==0)
   {
    change_needed=1;
   }
else
   {
    temp++;
    switch (PINB&0x18)
       {
         case 0x08:           //PB4 接地,三档调光+暴闪+慢闪+SOS+信标
               {
               if(temp>4)
                 temp++;
               }break;
         case 0x10:          //PB3 接地, 三档调光+暴闪+SOS
               {
                 temp++;
               }break; 
         case 0x00:          //PB3、PB4 接地,二档调光
               {
                temp=temp==5?7:4;
               }break;
         default: break;     //没有连接,六档调光+暴闪+慢闪+SOS+信标 
               
                                
       } 
   
    if(temp>MAX_DANGWEI)
        temp=0;  
    circle=temp; 
   } 

   
if(temp!=XINGBIAO)
      {
      //GIMSK=0x20;
      //PCMSK=0x10;
      //GIFR=0x20;

      TIMSK0=0x04;
      
      DIDR0=0x0F;
      ADMUX=0x41;
      ADCSRA=0x8D;
      #pragma optsize-
      WDTCR |= (1<<WDCE) | (1<<WDE);
      WDTCR=0x41;   //64ms
      #ifdef _OPTIMIZE_SIZE_
      #pragma optsize+
      #endif
      OCR0A=250;
      TCCR0B=0x01;
      delay_ms(5); 
      adc_busy=0;
      }
  
while (1)
    {
     if(temp==XINGBIAO)
      {
       EN_30mA=1;
       delay_ms(100);
       EN_30mA=0;
       #pragma optsize-
       WDTCR |= (1<<WDCE) | (1<<WDE);
       WDTCR=0x60;   //4s
       #ifdef _OPTIMIZE_SIZE_
       #pragma optsize+
       #endif
       MCUCR=0x20;
       #asm("sleep");
       #asm("NOP");
      }
     
    } 
}

程序中系数K1、K2计算:

点击看大图
 (原文件名:1.jpg) 

引用图片
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户441826 2013-10-7 21:13

可惜看不到图片
相关推荐阅读
用户289015 2015-06-26 17:58
触摸按键检测 IC的通病
                          触摸按键检测 IC的通病         项目需要用到触摸按键检测,由于项目应用领域问题,存在有触摸按键按下的时候上电,结果问题来了; ...
用户289015 2014-07-31 10:45
PCB设计黄金法则永不改变
       尽管目前半导体集成度越来越高,许多应用也都有随时可用的片上系统,同时许多功能强大且开箱即用的开发板也越来越可轻松获取,但许多使用案例中电子产品的应用仍然需要使用定制PCB。在一次性开...
用户289015 2014-05-23 09:34
失而复得
     可别2年,这两年当中多次想登录博客更新,可惜忘记了帐号,一直无法登录。这次下了狠心,想尽多种办法终于找回。后面要好好的分享分享心得。珍惜拥有。...
用户289015 2012-02-02 23:29
“临时应急可以使用,需要负-负串接,改造成无极性电容,注意串接后电容容量会减少,只要搭配合理就可以.”
刘志斌积分:10198 11 楼 回复时间:2008-4-12 11:48:34 “临时应急可以使用,需要负-负串接,改造成无极性电容,注意串接后电容容量会减少,只要搭配合理就可以.”   ...
用户289015 2011-07-18 11:42
转:贴片电阻的另外一种标准阻值表
  133K电阻,结果发现电阻上面标注的是13D, 回来查了一下,原来有种标准是这样的,真的是很奇怪的标准, 一点没有数字标注的直观方便,下面就是阻值表,以备自己查验: 标准阻值表 E-96   06...
用户289015 2011-06-14 17:53
转:RS485总线究竟能挂接多少个设备?
 N年前做门禁系统上位机软件开发的时候突击培训过串口通信编程基础。后来在我的脑海里一直认为RS485总线能且只能挂接256个设备(因为地址是1byte,取值范围也就0-255)。     后来经过几...
EE直播间
更多
我要评论
1
4
关闭 站长推荐上一条 /3 下一条