电路功能:单锂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) 引用图片
用户441826 2013-10-7 21:13