10F322 не хочет спать, помогите.

Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить
foton6
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

10F322 не хочет спать, помогите.

Сообщение foton6 »

Доброго времени суток!

Подскажите пожалуйста!
Не могу заставить уйти МК в сон. Точнее могу, во всех частях программы где есть сон все ок!
Но вот в одном месте хоть убей не засыпает, как будто игнорирует строки со сном.
Хотя в симуляторе все норм.
Отслеживаю эту ситуацию осциллографом.
Ниже приведен кусок кода который не корректно отрабатывается, данный кусок кода вызывается через "GOTO",
"SLEEP" не выполняет а все остальное отрабатывает. В другой части кода есть также слипы собранные из разных
интервалов времени и все прекрасно работает. ДШ читал, никаких оговор не увидел(
В дизассемблере все норм, строки не выкинуты)
Спойлер

Код: Выделить всё

asm_MARK(sleep_89ms);
        LATA1 = 0;              //__Отключение ИК приемника.
        T2CONbits.TMR2ON = 0;

        WDTCON = 0x0D;  //__Сон на 64мс.
        asm("SLEEP");   //
        asm("nop");     //__Последняя инструкция до сна.


        WDTCON = 0x09;  //__Сон на 16мс.
        asm("SLEEP");   //
        asm("nop");     //__Последняя инструкция до сна.


        WDTCON = 0x07;  //__Сон на 8мс.
        asm("SLEEP");   //
        asm("nop");     //__Последняя инструкция до сна.
 
        OPTION_REG = 0b01000111;        //__Настройка таймера (делитель = 256),               
        TMR0 = 225;                     //__960мкс.                                           
        INTCONbits.TMR0IF = 0;
        asm_MARK(rec_6);                        //__Ожидание флага переполнения таймера.
        asm_BTFSS(rec_6, INTCON, d_TMR0IF);     // 
        asm("GOTO rec_0");   //__Возврат в начало подпрограммы приемника.
Аватара пользователя
shindax
Потрогал лапой паяльник
Сообщения: 378
Зарегистрирован: Сб сен 19, 2009 07:02:19

Re: 10F322 не хочет спать, помогите.

Сообщение shindax »

А какой именно из SLEEP не выполнятся? По коду не очень понятно. И для чего для получения задержек в одних местах используется WDT, а в других TMR0? Я подобные вещи делал не ассемблерными вставками, а раз уж за такты приходится бороться, на asm-е, в отдельной функции, в отдельном asm-файле. А вызывалась эта функция уже из Си. Всё работало так, как было написано. Делать goto в ассемблерной вставке, IMHO, как-то через задницу, мягко говоря. :) Ну и для общего развития, где описаны функции asm_MARK и asm_BTFSS? Хотелось-бы посмотреть. Это Вы сами писали? Или с компилятором идёт? Проект на этом МК вырисовывается. И код целиком нужно смотреть, х.з. где эта метка rec_0 и какие ещё прерывания разрешены.
foton6
Встал на лапы
Сообщения: 146
Зарегистрирован: Вс сен 16, 2012 22:00:40

Re: 10F322 не хочет спать, помогите.

Сообщение foton6 »

Все 3 "sleep" не выполняются, выяснил это тем что питание отключается только на то время что сформировано таймером.
Задержки на слипах только на "большие" интервалы времени для экономии батарейки, а так как отрезки фиксированные,
то недостающее (до алгоритма) добираю таймером.

Знал бы я asm достаточно то на нем бы и накатал) Но дело в том что я знаю только те инструкции которые описаны в ДШ.
Не знаю как память размечать, как инклюдить внешние файлы, ну короче не уметь)
Вызовы вроде как тоже тратят время))))
Прерываний нет вообще, по крайней мере нету ухода на вектор, только анализ флагов.
Да функции сам писал, и не функции а дефайны. Работает все отлично, в дизассемблере именно то что задумано)
Собственно дефайны:
Спойлер

Код: Выделить всё

#define asm_BSF(adr, bit)    asm("BSF " #adr "," #bit)      //__Устанавливает указанный бит по адресу.
#define asm_BCF(adr, bit)    asm("BCF " #adr "," #bit)      //__Сбрасывает указанный бит по адресу.
#define asm_MARK(mark)       asm(" " #mark)                 //__Устанавливает метку строки.

/*
 Проверяет установлен ли бит по указанному адресу.
 adr - адрес регистра или переменной.
 bit - номер бита.
 mark - метка строки для команды GOTO в процессе сравнения. Необходима
        метка строки, установить ее можно макрасом asm_MARK.
*/
#define asm_BTFSS(mark, adr, bit)   asm("BTFSS " #adr "," #bit);  \
                                    asm("GOTO " #mark)                 

/*
 Проверяет установлен ли бит по указанному адресу.
 adr - адрес регистра или переменной.
 bit - номер бита.
 mark - метка строки для команды GOTO в процессе сравнения. Необходима
        метка строки, установить ее можно макрасом asm_MARK.
*/   
#define asm_BTFSC(mark, adr, bit)   asm("BTFSC " #adr "," #bit);  \
                                    asm("GOTO " #mark)


Остальной код тут не причем думаю, так как выполняется все за тем исключением того что питание приемника
отключается не на 89мс как задумано, а на ~1ms (то что таймер формирует после слипов).

Да эти "goto" все равно появляются при использовании IF, FOR, WHILE, но дело в том что при дизассемблировании
происходит не очень хорошая их замена и где можно было обойтись 2 инструкциями может и по 6 висеть((((
Потому все ветвления сделаны через вставки, и приведенный кусок кода как раз является одной из веток
при проверке флага переполнения таймера.

В общем выяснил, что "слипы отмирают" когда соединяю вместе RA1(дискретный выход) и RA2(дискретный вход с подтяжкой внутренней). Как с этим бороться?
То есть если я запитываю приемник с пина и соединяю другой пин с выходом приемника, начинается этот баг.
Аватара пользователя
4uvak
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт авг 16, 2012 10:41:42

Re: 10F322 не хочет спать, помогите.

Сообщение 4uvak »

Я писал прошивку для лед драйвера на этом же контроллере и столкнулся с аналогичной проблемой. Контроллер засыпает, но почему то не с первого раза.
Решил вот как

Код: Выделить всё

            bcf         WDTCON,0      ; отключаем сторожевой таймер на период сна
            sleep
            clrf        IOCAF         ; сбрасываем флаг IOCAF (свидетельствующий о прерывании RA3)
            btfsc       button        ; опрашиваем кнопку
            goto        $-3           ; отправляем спать, если кнопка отжата

Ну а в вкратце в вашей ситуации нужно добавить флаг определяющий режим сна. Если после режима сна проверяется этот флаг и выясняется что контроллер должен спать, то должна исполниться команда goto $-х переводящая контроллер в режим сна (закольцовка)
Аватара пользователя
Zhuk72
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Ср янв 29, 2014 08:41:31
Откуда: Баку
Контактная информация:

Re: 10F322 не хочет спать, помогите.

Сообщение Zhuk72 »

4uvak, WDT можно не отключать вручную перед сном, если в конфиге выставить биты 4-3 в позицию

10 = WDT enabled while running and disabled in Sleep


И, хотя явного указания по данному МК нет, желательно следующей после sleep командой ставить nop.
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Аватара пользователя
4uvak
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт авг 16, 2012 10:41:42

Re: 10F322 не хочет спать, помогите.

Сообщение 4uvak »

Я знаю, можно проще в конфигурации написать _WDTE_NSLEEP
Но мне по ходу программы нужно было отключать/включать WDT. WDT же здесь универсальный перестраиваемый от 1мсек до 256сек. В некоторых режимах в SLEEP соответственно можно установить периоды пробуждения от 1мсек до 256сек. Ну а nop после SLEEP ничего не значит, я экспериментировал
Ответить

Вернуться в «PIC»