twoperson 发表于 2010-1-27 14:25

DIY了一个用14500磷酸铁锂,兼容AA的手电

用的恒流IC是LTC3490,手电分弱(50mA),强(350mA),爆闪,SOS四档,用AA时只有弱、强两档,用磷酸铁锂和AA时均有低电压提醒
稍后上图和源代码

twoperson 发表于 2010-1-27 14:25

单片机是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;
}

twoperson 发表于 2010-1-27 14:30

不会贴图啊。。。
谁对原理图和PCB感兴趣的可以PM我。。。

liangya 发表于 2010-1-27 15:46

这么有技术含量的东西一定要顶!

twtarm 发表于 2010-1-27 17:05

twtarm 发表于 2010-1-27 17:07

test01 发表于 2010-1-27 17:16

twoperson 发表于 2010-1-27 18:13

手电很难被干扰的,而且加看门狗程序就超了。。。用WINAVR20090313编译。。。
弱档电流能通过电位器调节~
锂电和AA的输出差不多

ch611 发表于 2010-3-19 10:49

ak47fans 发表于 2010-3-20 10:55

{:1_268:}
可以出让两个成品来测试吗?

ch611 发表于 2010-3-20 18:23

twoperson 发表于 2010-3-20 19:14

11# ak47fans
没有成品,可以给套材自己焊,你要是要pcb的话可以送1、2个给你

xajh-lwh 发表于 2010-3-21 11:52

铁锂下的电流小了点,600ma左右比较合适,AA时350~450可以,建议中-低-高三档就可以了

映呈 发表于 2010-3-21 12:19

AA的电流不用太大,我认为最大别超450MA,太大了电池支持时间短,而且就是350MA左右,按CREE的LED,也能上100流明的亮度,足够用了,450MA》150MA》50MA,我认为是个合适的档位。

twoperson 发表于 2010-3-21 15:19

我跟楼上的理念差不多,所以弄了350mA-可调-爆闪-SOS四档~

yncgxm 发表于 2010-3-25 17:04

很感兴趣,楼主可以提供套件的话,请PM我,谢谢!

lxqqqqq 发表于 2010-5-9 16:17

楼主,可否发一份原理图和pcb图给我,比较感兴趣,主要是不知道单片机的电源如何保证,谢谢!
shadowmen11@tom.com

artie 发表于 2010-5-9 16:55

本帖最后由 artie 于 2010-5-9 17:08 编辑

用14500磷酸铁锂做LED电源似乎有点尴尬,主要是容量小和其工作电压范围的问题。

磷酸铁锂的工作电压范围是2~3.6V(终止放电电压2V,终止充电电压3.6V,工作平台3.2V),LED的工作电压是3.x V(视不同的LED而定),在铁锂供电时,当电压低到LED不能点亮,控制电路就要工作于升压状态。在升压工作态时电池的输出电流可就很大了哦(由电路转换效率所限),这样就越发显得电池容量小了。
页: [1]
查看完整版本: DIY了一个用14500磷酸铁锂,兼容AA的手电