Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

PIC10F222 SLEEP MODE

Пн янв 14, 2019 19:30:24

Добрый день форумчане! Обращаюсь за помощью к любителям PIC. Являюсь новичком в программировании контроллеров, но есть большое желание научиться. Делаю устройство на PIC10F222 - эдакий BMS контроллер для свинцовой батареи на 6В, чтоб не допускать глубокого разряда. Столкнулся с проблемой работы режима сна. Вот мой код:
Код:
#pragma config IOSCFS = 8MHZ    // Internal Oscillator Frequency Select bit (8 MHz)
#pragma config MCPU = OFF       // Master Clear Pull-up Enable bit (Pull-up disabled)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config CP = OFF         // Code protection bit (Code protection off)
#pragma config MCLRE = ON       // GP3/MCLR Pin Function Select bit (GP3/MCLR pin function is MCLR)

#include <xc.h>

#define _XTAL_FREQ 8000000
#define OUT GP2

void main(void)
{
            ADCON0 = 0b01000001; //вкл АЦП, канал А0
            OPTION = 0b00111111; //тактирование сторожевого таймера, предделитель 1:128 (2.3с)
            TRIS = 0b11111011; //GP2 выход, остальные вход
            GPIO = 0b00000000; //обнулить
            while(1)
            {
                CLRWDT(); //сброс сторожевого таймера
                ADCON0 = 0b01000001;//включение АЦП, после сна выключается
                GO_nDONE = 1; //начать преобразование
                while(GO_nDONE); //ждать, пока АЦП преобразует
                if(ADRES < 167) //если ниже 5.3В, АКБ выкл
                {
                    OUT = 0;
                }
                if(ADRES > 189) //если выше 6В, АКБ вкл
                {
                    OUT = 1;
                }
                SLEEP(); //заснуть
                NOP();
            }
}

Измеряю через делитель напряжение на АКБ и при понижении его ниже допустимого АКБ отключается от нагрузки. Так как контроллер всегда будет питаться от АКБ, нужен режим сна. Без него все работает, АЦП измеряет, нагрузка отключается. Но при использовании режима сна все работает не так, как должно. Пробуждаться контроллер должен по таймауту сторожевого таймера. Он просыпается, но АЦП измеряет как будто неверное значение, отключение нагрузки происходит на напряжении, ниже установленного. К примеру - загружаю программу без режима сна - отключение происходит на 5.3В, включение при 6. Загружаю программу с режимом сна - отключение при 5.2В, включение при 5.5В...... Кто укажет мне на мои ошибки? Какие ньюансы есть у этого режима? Что я упускаю?
Применять другой контроллер не предлагать :tea:

Re: PIC10F222 SLEEP MODE

Вт янв 15, 2019 08:47:38

Какие ньюансы есть у этого режима? Что я упускаю?

ньюанс из документации:
8.9.2
Пробуждение от сна
Устройство может выйти из спящего режима через одно из следующих событий:
...
2.Сброс тайм-аута сторожевого таймера (если WDT был включен).
...
Эти события вызывают сброс устройства.
биты ТО, PD, GPWUF могут использоваться для определения причины cброса устройства.

т.е. после пробуждения от WDT микроконтроллер сбрасывается (не останется в цикле while(1)), источник сброса можно "увидеть" в вышеуказанных битах.
Посоветую делать несколько измерений АЦП (кратное двум), суммировать и поделить на количество измерений (сделать сдвиг).

Re: PIC10F222 SLEEP MODE

Вт янв 15, 2019 16:58:49

И в правду, программа не остается в цикле while! Спасибо! Подправил, заработало :beer:
Рабочий код, мало ли, кому пригодится 8)
Код:
#include <xc.h>

#pragma config IOSCFS = 8MHZ    // Internal Oscillator Frequency Select bit (8 MHz)
#pragma config MCPU = OFF       // Master Clear Pull-up Enable bit (Pull-up disabled)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config CP = OFF         // Code protection bit (Code protection off)
#pragma config MCLRE = OFF       // GP3/MCLR Pin Function Select bit (GP3/MCLR pin function is MCLR)

#define _XTAL_FREQ 8000000
#define OUT GPIObits.GP2
void main(void)
{
    OPTION = 0b11001111;
    TRIS = 0b11111011; 
    ADCON0 = 0b01000001;
    GO_nDONE = 1;
    while(GO_nDONE);
    if(ADRES<173)//Нижний порог 5,2В
    {
        OUT = 0;
    }
    if(ADRES>200)//Верхний порог 6В
    {
        OUT = 1;
    }
    GPIO=GPIO;
    SLEEP();
    NOP();
}
Ответить