DIY了一个用14500磷酸铁锂,兼容AA的手电
用的恒流IC是LTC3490,手电分弱(50mA),强(350mA),爆闪,SOS四档,用AA时只有弱、强两档,用磷酸铁锂和AA时均有低电压提醒稍后上图和源代码 单片机是ATtiny 13A,代码如下
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#define LOW 0x00
#define HIGH 0x01
#define FLASH 0x02
#define SOS 0x03
volatile unsigned char status;
ISR(INT0_vect)
{
//low battery warning
DDRB |= 0x01;
for (char i = 0; i < 12; i++)
{
PORTB |= 0x01;
_delay_ms(200);
PORTB &= 0xfe;
_delay_ms(50);
PORTB |= 0x01;
}
if (status == LOW) DDRB &= 0xfe;
if (status == HIGH) PORTB |= 0x01;
if ((status == LOW) || (status == HIGH))
for (char i = 0; i < 60; i++) _delay_ms(1000);
else cli();
}
int main()
{
unsigned char address, readData, writeData, i, pAddress;
//read eeprom
pAddress = 0x00;
address = eeprom_read_byte((uint8_t *)pAddress);
readData = eeprom_read_byte((uint8_t *)address);
switch (readData)
{
case 0x00:
status = LOW;
writeData = 0x55;
break;
case 0x55:
status = HIGH;
writeData = 0xaa;
break;
case 0xaa:
status = FLASH;
writeData = 0xff;
break;
case 0xff:
status = SOS;
writeData = 0x00;
break;
default://eeprom exception
status = LOW;
writeData = 0x00;
address += 1;
if (address >= 0x40) address = 0x01;
eeprom_write_byte((uint8_t *)pAddress, address);
eeprom_busy_wait();
}
//initial
//PB: ADC2 NC CELLS /LOBAT CTRL
//CELLS 0: 1cell 1: 2cell
DDRB = 0x04;//CELLS = 1
PORTB = 0x0a;//NC = 1, /LOBAT = 1
//measure the voltage of battary
ADMUX = 0x42;//0100_0010 - REFS0 ADLAR - - - MUX1 MUX0
DIDR0 = 0x08;//0001_0000 - - ADC0 ADC2 ADC3 ADC1 - -
ADCSRA = 0xc7;//1100_0111 ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
while (!(ADCSRA & 0x10));
//set CELLS if ADC_result > 0.55V
if (ADCH & 0x02) PORTB |= 0x04;//cell = 1
else if ((status == FLASH)||(status == SOS))
{
status = LOW;
writeData = 0x55;
}
ADCSRA &= 0x7f;
//close ADC
eeprom_write_byte((uint8_t *)address, writeData);
eeprom_busy_wait();
//set status and delay 2s
switch (status)
{
case LOW:
_delay_ms(4000);
break;
case HIGH:
DDRB |= 0x01;
PORTB |= 0x01;
_delay_ms(4000);
break;
case FLASH:
DDRB |= 0x01;
for (i = 0; i < 40; i++)
{
PORTB |= 0x01;
_delay_ms(10);
PORTB &= 0xfe;
_delay_ms(90);
}
break;
case SOS:
DDRB |= 0x01;
//send a SOS
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
break;
default:
break;
}
//write eeprom
eeprom_write_byte((uint8_t *)address, LOW);
eeprom_busy_wait();
//sleep, flash or SOS
if ((status == LOW)||(status == HIGH))
{
//low battery detect and warning
//set int0 interrupt to detect low battery
GIMSK |= 0x40;//enable int0
sei();//enable interrupt
for(;;)
{
//sleep
PRR |= 0x02;//set sleep mode as power down
sleep_enable();
//sleep...
sleep_cpu();
sleep_disable();
}
}
else if (status == FLASH) for(;;)
{
PORTB |= 0x01;
_delay_ms(10);
PORTB &= 0xfe;
_delay_ms(90);
}
else for(;;)
{
//send SOSs
_delay_ms(1900);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
}
return 0;
} 不会贴图啊。。。
谁对原理图和PCB感兴趣的可以PM我。。。 这么有技术含量的东西一定要顶! 手电很难被干扰的,而且加看门狗程序就超了。。。用WINAVR20090313编译。。。
弱档电流能通过电位器调节~
锂电和AA的输出差不多 {:1_268:}
可以出让两个成品来测试吗? 11# ak47fans
没有成品,可以给套材自己焊,你要是要pcb的话可以送1、2个给你 铁锂下的电流小了点,600ma左右比较合适,AA时350~450可以,建议中-低-高三档就可以了 AA的电流不用太大,我认为最大别超450MA,太大了电池支持时间短,而且就是350MA左右,按CREE的LED,也能上100流明的亮度,足够用了,450MA》150MA》50MA,我认为是个合适的档位。 我跟楼上的理念差不多,所以弄了350mA-可调-爆闪-SOS四档~ 很感兴趣,楼主可以提供套件的话,请PM我,谢谢! 楼主,可否发一份原理图和pcb图给我,比较感兴趣,主要是不知道单片机的电源如何保证,谢谢!
shadowmen11@tom.com 本帖最后由 artie 于 2010-5-9 17:08 编辑
用14500磷酸铁锂做LED电源似乎有点尴尬,主要是容量小和其工作电压范围的问题。
磷酸铁锂的工作电压范围是2~3.6V(终止放电电压2V,终止充电电压3.6V,工作平台3.2V),LED的工作电压是3.x V(视不同的LED而定),在铁锂供电时,当电压低到LED不能点亮,控制电路就要工作于升压状态。在升压工作态时电池的输出电流可就很大了哦(由电路转换效率所限),这样就越发显得电池容量小了。
页:
[1]