Главная » Статьи » Proton PICBasic

Зарядное устройство для литиевой АКБ напряжением 8,4В

История создания этого устроиства как всегда банальна .

Принес знакомый на ремонт китайскую зарядку для LiIo напряжением 8,4В . Для вот таких АКБ .



Так и не отремонтировав предложил сделать свое . Причин для этого было несколько . И одна из них - надо применять знания , приобретенные на этом сайте .

Знакомый согласился . Осталось дело за малым - подбор комплектации .

За основу взял PIC18F1220 так как он у меня уже был . Так как зарядка используется свадебным оператором на место питания без вариантов выбран БП от МeanWell cс параметрами 12В 3,7А

http://www.rcscomponents.kiev.ua/product/PS-45-12.html

Корпус от сд - рома пошел сюда как никак другой . В меру компактный и который не занимал бы много места в сумке .

Сразу предупреждаю что это уже второй вариант . Первый не прошел боевых испытаний .

Схема



Плата



Дополнительно был прибретен на Ебей модуль зарядки лития .

http://www.ebay.com/itm....rdc%3D1

С его помощью уже дело пошло на ура .

Логика работы выбрана следующая :

1 Если нет АКБ - ничего не работает , ждем

2 Если посоеденили АКБ но он настолько сел , что плата защиты отключила его - для этого есть предзаряд . В котором заряд идет циклами 5 секунд заряд , 5 секунд пауза . И так до тех пор пока напряжение не вырастет выше 6,5В . После этого идет переход в обычную зааарядку .

Для того что бы попасть - нужно нажать кнопку .

3 Если напряжение выше 6,5В сразу попадаем в заряд .

4 После окончания заряда переход в подпрограмму CHARGEEND . Где также отслеживается напряжение . Как только оно станет ниже 2В - переход в начало .

Сам код

Код

 Device = 18F1220

    Xtal 12

'    Include "hpwm10.inc"
'    Include "PID.inc"                           ' Load the PID routine into the program

    Config_Start
    OSC = HS
    FSCM = OFF ; Fail-Safe Clock Monitor disabled
    IESO = OFF ; Internal External Switch Over mode disabled
    PWRT = OFF ; Enabled
    BOR = OFF ; Disabled
    WDT = OFF ; Disabled
    MCLRE = On ; Enabled
    STVR = OFF ; Disabled
    LVP = OFF ; Disabled
    Debug = OFF ; Disabled
    Cp0 = On ; Enabled
    CP1 = On ; Enabled
    CPB = On ; Enabled
    CPD = On ; Enabled
    WRT0 = OFF ; Disabled
    WRT1 = OFF ; Disabled
    WRTB = OFF ; Disabled
    WRTC = OFF ; Disabled
    WRTD = OFF ; Disabled
    EBTR0 = OFF ; Disabled
    EBTR1 = OFF ; Disabled
    EBTRB = OFF ; Disabled
    Config_End

'-------------------------- Настройки АЦП ------------------------------------

    Declare  Adin_Res 10                     ' Разрядность результата преобразования АЦП
    Declare  Adin_Tad = 16_FOSC              ' Источник тактирования АЦП
'     Declare  Adin_Tad = FRC            ' Источник тактирования АЦП
    Declare  Adin_Stime  50                 ' Время на подготовку АЦП к новому измерению

'-------------------------- Настройки портов ---------------------------------

    TRISA = %00000011                           ' Сделать каналы (вывод) AN0,AN1 (PORTA.0 ,PORTA.1) входом
    LATA  = %00000000
    TRISB = %00000101
    LATB  = %00000000

'============================Определение переменных============================
    Dim   VAR1             As  Word          ' Напряжение с АКБ
    Dim   UBATTERY         As  Float         '
    Dim   VAR2             As  Word          '
    Dim   TOKCHARGE        As  Float         '
    Dim   TOKCHARGEEND     As  Float         '
'    Dim   TOKBATCHARGE     As  Float         ' Ток заряда АКБ
'    Dim   TOKCHARGEPIDU    As  Word          '
'    Dim   MyRequired       As  Word          ' The value required by the PID
'    Dim   MyInput          As  Word          ' Input to the PID, which is the output from the sensor
'    Dim   MyOutput         As  Word          ' The outut from the PID
'    Dim   PWMOUT1          As  Word          ' ШИМ 1 ЗАРЯД
    Dim   BIG              As  Dword         ' переменная для счета секунд
    Dim   BIG1             As  BIG.HighWord  '                                        '
    Dim   Secunda          As  Byte          '
    Dim   Secunda1         As  Byte          '
    Dim   Minute           As  Byte          '
    Dim   NO_BATTERY       As  Bit           '

'-------------------------- Определение символов -----------------------------

    Symbol   LED_NOBAT      = PORTB.7         ' LED Нет АКБ
    Symbol   LED_PredCrg    = PORTB.6         ' LED Предзаряд
    Symbol   LED_CRG        = PORTB.5         ' LED Заряд
    Symbol   LED_COPL_CRG   = PORTB.4         ' LED Окончание заряда
    Symbol   Charge_ON      = PORTB.3         ' Включение заряда
    Symbol   PRED_CrgButton = PORTB.0         ' Предзард
    
'-------------------------- ADCON0, ADCON1 -----------------------------------

                                             '  Vref + = Vdd. Vref - = Vss
    ADCON0 = %00000101                       '  ADCON0
    ADCON1 = %11111100                       '  ADCON1
    ADCON2 = %10000111                       '
    ADRESL = %00000011                       '
    ADRESH = %00000000                       '

'-------------------------- INTCON --------------------------------------------

    Symbol RBIF = INTCON.0                  ' Флаг внешнего прерывания по PORTB.4-PORTB.7
    Symbol INTF = INTCON.1                  ' Флаг внешнего прерывания по PORTB.0(INT)
    Symbol T0IF = INTCON.2                  ' Флаг переполнения TMR0
    Symbol RBIE = INTCON.3                  ' Бит разрешения прерывания по PORTB.4-PORTB.7
    Symbol INTE = INTCON.4                  ' Бит разрешения прерывания по PORTB.0(INT)
    Symbol T0IE = INTCON.5                  ' Бит разрешения прерывания по переполнению TMR0
    Symbol PEIE = INTCON.6                  ' Бит разрешения прерывания от периферийных устройств
    Symbol GIE = INTCON.7                   ' Бит глобального разрешения прерываний

'==============================================================================
'OPTION_REG = %10000111
'TMR0 = $00' TMR0 register value
    T0CON = %11010111
    T0IE = 1                            ' Разрешение глобального прерывания
    BIG = 3000000
    INTCONbits_GIE = 1                             ' Enable global interrupts
    On_Interrupt GoTo  Int_Label
'=============================================================================
    init:
    DelayMS 1000
    LED_NOBAT     = 1
    DelayMS 1000
    LED_PredCrg   = 1
    DelayMS 1000
    LED_CRG       = 1
    DelayMS 1000
    LED_COPL_CRG  = 1
    DelayMS 1000
    LED_NOBAT     = 0
    LED_PredCrg   = 0
    LED_CRG       = 0
    LED_COPL_CRG  = 0
    Clear

'==============================================================================
    START:

    Charge_ON = 0       ' выкл заряд на всякий

    LED_CRG = 0         ' выключаем св-диод

    LED_NOBAT = 1       ' вкл св-диод
    
    LED_PredCrg = 0      ' выключаем св-диод
    
    Secunda = 0          ' скидываем
    
    Secunda1 = 0         ' скидываем
    
    Minute = 0           ' скидываем
        
    GoSub ADC

    If UBATTERY < 6.01 Then                '  Если напряжение меньше 6 В
        If PRED_CrgButton = 0 Then         '  нажимаем кнопку
            DelayMS 2000                   '  ждем 2с
            GoTo PRED_CHARGE               '  переходим в подпрограмму
        EndIf
    EndIf

    If UBATTERY > 8.5 Then DelayMS 2000 : GoTo START ' Больше 8,5В - переход в начало

    If UBATTERY >= 6.05 And UBATTERY < 8.41 Then DelayMS 2000 : GoTo Charge_PROGRAM ' переход в заряд

    GoTo START

'-------------------------- Подпрограмма прерывания--------------------------
    Int_Label:                                            '

    Context Save                                          ' Сохраним значения системных регистров

    If T0IF = 1 Then Dec BIG1                              ' Если сработал TMR0, то отнимаем единицу из старшего байта переменной BIG1,
                                                          'то же самое, что и вычесть 65536 из BIG, но занимает меньше места

    If BIG < 0 Then BIG = BIG + 3000000 : Inc Secunda : Inc Secunda1    ' Если BIG < 0 то значит прошла секунда, К этому отрицательному числу
                                                          '   прибавляем 1000000
    If Secunda > 59 Then Secunda = 0 : Inc Minute         ' Если прошло 60 сек , сбрасываем их в ноль , инкрементируем минуты
    If Minute > 250 Then Minute = 0                       ' Если прошло 60 минут , то сбрасываем в 0 , инкрементируем часы

    T0IF = 0                                              ' Сбросим флаг прерывания

    Context Restore

    Retfie                                                ' Возврат из обработчика

'==============================================================================
    PRED_CHARGE:        ' Предварительный заряд 

    LED_NOBAT = 0       ' выключаем св-диод 
    
    LED_PredCrg = 1     ' вкл светлодиод
    
    Secunda = 0         ' скидываем
    
    Secunda1 = 0        ' скидываем
    
    Minute = 0          ' скидываем

    While 1 = 1

        VAR1 = ADIn 0              '  считываем с 0- канала и записываем VAR1
        DelayUS 2
        UBATTERY = VAR1 / 50       '  получаем 20.46V
        
        VAR2 = ADIn 1                '  считываем с 1- канала и записываем VAR2
        DelayUS 2
        TOKCHARGE = VAR2 / 200     ' получаем 5 А 
        
        If Secunda1 < 6 Then           ' если меньше 6 секунд 
            Charge_ON = 1              ' включаем заряд        
            LED_CRG = 1                ' включаем св-диод заряда
        EndIf
        
        If Secunda1 = 4 And TOKCHARGE > 4.5 Then Clear : NO_BATTERY = 1 : GoTo CHARGEEND ' Прошло больше 4 секунд и ток больше 4,5А - выключаем 
                             
        If Secunda1 > 5 Then           ' если больше 5 секунд
            Charge_ON = 0              ' выключаем заряд
            LED_CRG = 0                ' выключаем св-диод заряда
        EndIf
        
        If Secunda1 = 10 Then          ' прошло 10 секунд
            Secunda1 = 0               ' скидываем
        EndIf        

        If Minute > 9 And UBATTERY >= 6.50 Then DelayMS 2000 : Clear : GoTo START ' прошло больше 9 минут и напряжение больше 6,5В - переход в начало 

        If UBATTERY > 10.0 Then DelayMS 2000 : Clear : NO_BATTERY = 1 : GoTo CHARGEEND ' Если больше 10В - выключаем заряд 



    Wend

    GoTo PRED_CHARGE

'==============================================================================
    Charge_PROGRAM:

    LED_NOBAT = 0       ' гасим светлодиод

    LED_CRG = 1         ' включаем светлодиод инд заряд

    Charge_ON = 1       ' включаем заряд 
    
    LED_PredCrg = 0     '  гасим светлодиод
    
    Secunda = 0          ' скидываем
    
    Secunda1 = 0         ' скидываем
    
    Minute = 0           ' скидываем

    While 1 = 1

        VAR1 = ADIn 0              ' считываем с 0- канала и записываем VAR1
        DelayUS 2
        UBATTERY = VAR1 / 50       ' получаем 20.46V
        
        VAR2 = ADIn 1                ' считываем с 1- канала и записываем VAR2
        DelayUS 2
        TOKCHARGE = VAR2 / 200     ' получаем 5 А
        
        If Minute > 10  Then        ' 
            If TOKCHARGE < 0.4   Then
            
            If TOKCHARGE < 0.120 Then '
                DelayMS 2000        '
                Clear
                GoTo CHARGEEND      '
            EndIf
        EndIf
        
        If Secunda1 > 3 And TOKCHARGE > 4.5 Then Clear : NO_BATTERY = 1 : GoTo CHARGEEND ' Прошло больше 3 секунд и ток больше 4,5А - выключаем
        
        If UBATTERY > 10.0 Then DelayMS 2000 : Clear :NO_BATTERY = 1 : GoTo CHARGEEND  ' Если больше 10В - выключаем заряд

    Wend

    GoTo Charge_PROGRAM

'==============================ADC=============================================
    ADC:

    VAR1 = ADIn 0              ' считываем с 0- канала и записываем VAR1
    DelayUS 2
    UBATTERY = VAR1 / 50       ' получаем 20.46V

    VAR2 = ADIn 1                ' считываем с 1- канала и записываем VAR2
    DelayUS 2
    TOKCHARGE = VAR2 / 200     ' получаем 5 А

    Return

'==============================================================================
    CHARGEEND:

    Charge_ON = 0     ' выкл заряд на всякий

    LED_CRG = 0       '  гасим светлодиод
    
    LED_PredCrg = 0   '  гасим светлодиод
    
    Secunda = 0        ' скидываем
    
    Secunda1 = 0       ' скидываем
    
    Minute = 0         ' скидываем

    GoSub ADC

    If UBATTERY < 2 Then DelayMS 3000 : LED_COPL_CRG = 0 : GoTo START   ' переход в начало 
        
    If NO_BATTERY = 1 Then   ' если установлен бит что нет АКБ
        LED_NOBAT = 0        ' моргаем св-диодом
        DelayMS 1000         '
        LED_NOBAT = 1        '
        DelayMS 1000         '   
        LED_COPL_CRG = 0     '
    EndIf
        
    If NO_BATTERY = 0 Then   ' если закончился заряд
        LED_NOBAT = 0        ' гасим св-диод
        LED_COPL_CRG = 1     ' вкл св-диод окончания зарядки 
    EndIf
              
    GoTo CHARGEEND

'==============================================================================



Код выложен для ознакомления . Форматирование пропало . Лучше скачать по ссылке внизу статьи .

Этот вариант работы зарядки работает уже полгода .

Подстроечным резистором R2 на плате выставляем напряжение . В такой последовательности :

1 Включаем в сеть .

2 С внешнего БП подаем напряжение 10,26В на предохранитель и общий , согласно полярности . Предварительно выкрутив движок подстроечного резистора в нижнее положение , если смотреть по схеме .

3 Выставляем на выводе 1 МК напряжение 2,5В . Эту операцию можно произвести и без МК .

Метод настройки модуля для зарядки определен методом проб и ошибок . Какой из резисторов и за что отвечает уже не скажу .

1 Выставляем напряжение одним из подстроечников . В моем случае это было - 8,4В

2 Цепляем нагрузку на выход . Последовательно включаем амперметр . Вторым подстроечником выставляем ток заряда .

Модуль сам переходит с заряда током на заряд напряжением . Применил для этого дела переменный проволочный резистор номиналом 10Ом .

Уменшением сопротивления и подстроечником добиваемся нужного значения . У себя выставил 2А . Подстроечным резистором R12 выставляем напряжение на выводе 2 , которое численно будет равно току заряда . Тоесть если я выставил 2А , то и напряжение должно быть 2В на выводе 2 . Для измерения тока используеться резистор из модуля . Который при измерении составил 0,5Ом .

Модуль был при заряде практически холодный .

Фото того что получилось





На инструкцию наклееную не обращать внимание . Надо исправить . Но зарядки у меня уже нет на руках .

Файл Протеуса , код и ориналы схемы и платы можно скачать отсюда

Оригинальные фото можно скачать отсюда . Размер папки под 40МБайт .

От первого варианта отказалься по причине невыясненных проблем . Использовался ШИМ и ПИД регулятор . Были скачки напряжения , что срабатывала защита от превышения напряжения на выходе . Под 10В . А времени для долгих эксперементов не было . Зарядка нужна была владельцу .

Принято предосторожности - если нет питание , реле отключит АКБ от зарядного . Питание на модуль поступит с ключа при наличии АКБ .

Вроде все . Возможно что вышло немного сумбурно .

Спасибо всем кто дочитал статью до конца .

Если будут изменение в коде - сообщу в коментариях .

 




Категория: Proton PICBasic | Добавил: Andriy76 (09.03.2014) E
Просмотров: 4594 | Комментарии: 5 | Теги: LiIon, зарядное устройство, PROTON, PIC18F1220 | Рейтинг: 5.0/1
Всего комментариев: 5
1 Andriy76   (16.03.2014 18:46)
Немного исправил в коде . Уменшил ток отключения . Сейчас стал 0,3А , было 0,4А . Убрал лишнее . 
Код
Видимо тема зарядок не интересна ?

2 xvovanx   (25.03.2014 10:57)
При работе зарядки не проявляется недозаряд? При зарядке напруга растет не идеально гладко, а небольшими скачками - "бульками" электролита. Скажем так, усредненная напруга на аккуме не дошла до нормы, хотя отдельные "бульки" могут перескочить порог сравнения и отключить зарядку. Я в своих зарядках всегда делаю контроль нескольких замеров в цикле и усредняю их.

3 Andriy76   (25.03.2014 11:38)
Посмотрю в коде . Много осталось лишнего .

4 Andriy76   (25.03.2014 22:51)
Вот вроде исправил 

Что все-таки прибавляется? 3 или 1 миллион? 

Прибавляем в 4 раза меньшое число от частоты кварца . Многое идет из проекта в проект - вот и накладки .

If Minute > 250 Then Minute = 0 ' Если прошло 60 минут , то сбрасываем в 0 , инкрементируем часы ?

На всякий случай скидываем . Что бы избежать переполнения переменной , размером в Байт . Здесь для часов используються секунды и минуты . Часы нет . 
Вроде так .

5 Andriy76   (26.03.2014 23:23)
АДМИН спасибо за Ваш труд . 
И зернышко знаний не пропадает , а надеюсь прорастет и даст много нужных статей на сайте .

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]