Jump to content
-=FISHER=-

Спящий режим МК AVR

Recommended Posts

Сегодня пошаманю со спящими режимами. Возможно, это глюк протеуса.

Цитата

if (!(PIND&0x4)) //обработка нажатия основной кнопки

Лучше использовать сдвиг и именованную константу, иначе можно подумать что кнопка висит на PD4, а не на PD2:
 

#define BTN 2

if(! (PIND & (1<<BTN)) )
Цитата

FRONT_LAMP_MODE++; //увеличиваем значение переменной режима

В Си принято капсом обозначать константы, а не переменные.

Цитата

PORTB=0x00; //выключаем все светодиоды
                        STROB_MODE=0; //отключаем режим стробоскопа
                        OCR1A=128; //переводим яркость переднего фонаря в режим "БЛИЖНИЙ СВЕТ"
                        FRONT_LAMP_MODE=0; //устанавливаем нулевой режим
                        sleep_cpu(); //отправляем МК в СОН
                        break;

не увидел запрещения-разрешения прерывания INT0. Без этого оно будет вызываться постоянно пока кнопка нажата.

Цитата

sei(); //глобально разрешаем прерывания
    counter_init(); //инициализируем счетчик    
    port_init(); //инициализируем порты
    PWM_timer_init(); //инициализируем ШИМ
    int_init(); //инициализируем прерырвания
    sleep_init(); //инициализируем режим сна
    sleep_cpu(); //засыпаем

разрешать прерывания стоит после настроек а не до них. Еще неплохо бы явным образом сбросить флаги прерываний.


Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Share this post


Link to post
Share on other sites
55 минут назад, COKPOWEHEU сказал:

Сегодня пошаманю со спящими режимами. Возможно, это глюк протеуса.

Было бы здорово! Заранее спасибо!

55 минут назад, COKPOWEHEU сказал:

не увидел запрещения-разрешения прерывания INT0. Без этого оно будет вызываться постоянно пока кнопка нажата.

Поправил, правда это делается в регистре GICR, то есть

GICR |= (1<<INT0) //разрешаем прерывания

GICR &= ~(1<<INT0) //запрещаем прерывания

При включении прерываний, по умолчанию включено прерывание именно по низкому уровню на INT0, остальные виды прерываний уже настраиваются в регистре  MCUCR.

Так же учту все остальные поправки. Спасибо!

55 минут назад, COKPOWEHEU сказал:

не увидел запрещения-разрешения прерывания INT0. Без этого оно будет вызываться постоянно пока кнопка нажата.

Правда всё равно немного не понимаю, выглядит это всё вот так:

GICR |= (1<<INT0) //разрешаем прерывания
sleep_cpu(); //отправляем МК в сон
GICR &= ~(1<<INT0) //запрещаем прерывания

а как же же МК должен проснуться, если прерывания мы запретили?...Вот сейчас проэксперементировал и сначала запретил прерывания, а потом разрешил, после чего МК у меня успешно заснул. Но теперь не хочет просыпаться, сколько кнопку не тыкай...

GICR &= ~(1<<INT0) //запрещаем прерывания
sleep_cpu(); //отправляем МК в сон
GICR |= (1<<INT0) //разрешаем прерывания

 

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Заметил интересную особенность, в Протеусе у меня МК просыпается даже если я вообще никак не инициализирую прерывания!

То есть даже если закомментировать эти строчки. МК всё равно просыпается при появлении "ЛОГ.0" на PD2.

//GICR |=(1<<INT0);
//sei();

Теоретически это ведь не возможно?

А я понял почему! У меня в процедуре инициализации таймера-счетчика есть вот такая строчка SREG = (0x80), которая устанавливает в единичку бит I, регистра SREG, который в свою очередь и включает глобальные прерывания.

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Вебинар "Разбор новых уникальных модулей FMAC и CORDIC в микроконтроллерах общего назначения STM32G4" (15.07.2020)

Компания КОМПЭЛ приглашает вас принять участие в вебинаре 15.07.2020, посвященном новому семейству микроконтроллеров общего назначения – STM32G4. Вебинар рассчитан на технических специалистов и тех, кто знаком с основами цифровой обработки сигналов. Мы разберем алгоритм работы CORDIC, а также рассмотрим пример создания цифрового фильтра на базе FMAC.

Зарегистрироваться на вебинар

Проверил. Вот этот набросок работает нормально. Единственное что по низкому уровню протеус генерирует всего одно прерывание, хотя должен постоянно. В моем коде используется файл pinmacro.h, это макросы для удобной работы с портами. Он есть по ссылке в моей подписи, но и без того несложно понять.

Прерывание разрешаем только перед уходом в сон. Иначе оно будет отъедать 90% скорости на постоянный вызов пустого обработчика. А после выхода из сна - запрещаем. Грубо говоря, не акцентируясь на конкретном прерывании, так

	sei(); //разрешаем прерывание только когда оно нужно.
	sleep_cpu(); //эта команда не завершится пока контроллер не проснется
	cli(); //и уже когда он проснулся, снова запрещаем прерывание
	

sleep_my.c


Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Share this post


Link to post
Share on other sites
                     

Новые контроллеры VIPerPLUS для ИП – видео и материалы вебинара STMicroelectronics

Видеозапись и материалы вебинара ST о семействе AC/DC регуляторов VIPerPLUS производства компании STMicroelectronics. Инженерами ST было детально рассмотрено новое семейство микросхем VIPerPLUS со встроенным транзистором, их возможности и топологии применения. Продемонстрировано испытание из лаборатории ST в Праге и моделирование в среде E-DesignSuite.

Подробнее

7 часов назад, -=FISHER=- сказал:

Сразу после выхода из сна убеждаемся что кнопка ТОЧНО нажата а не была короткая помеха, иначе снова уходим в сон(цикл постоянного входа в сон, пока не будет установлен фак

Подскажите пожалуйста, как лучше и проще это сделать в моем случае?


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
                     

Конденсаторы ECWFG от Panasonic: теперь и для высоковольтных применений

Компания Panasonic анонсировала существенное расширение серии пленочных конденсаторов ECWFG: на сегодняшний день диапазон рабочих напряжений серии составляет 630…1100 В (DC). Серия ECWFG поддерживает уникальную функцию микропредохранителей.

Подробнее

Цикл на 10 итераций, внутри задержка на 2..4мс и считывание кнопки - если минимум 5 раз подряд кнопка нажата, то засчитать нажатие иначе - переходим к команде входа в спящий режим.


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites
1 час назад, Alexeyslav сказал:

Цикл на 10 итераций, внутри задержка на 2..4мс и считывание кнопки

Цикл for как я понимаю?

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Можешь и for, в языке множество способов организовывать циклы, вплоть до разворачивания в линейный код...


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites
11 час назад, Alexeyslav сказал:

Можешь и for

Этот цикл лучше записать вначале main не трогая весь остальной код что у меня есть уже?


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

А смысл тогда? Проверка нужна везде где ждёшь нажатия а не только на старте...


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites
2 минуты назад, Alexeyslav сказал:

А смысл тогда?

Плоховато понял, не могли бы Вы хотя бы в общих чертах набросать эту мысль в коде?

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Если у тебя проверка на нажатие только в начале цикла, то туда и ставь. А смысл такой проверки - чтобы отсеять ложные срабатывания и не реагировать на дребезг. Иначе, контроллер же очень быстрый - воспримет дребезг как сотню нажатий и за это время 100 раз успеет поспать и что-то сделать согласно алгоритму. В принципе, может хватить лишь одной проверки спустя 20-40 мс после первой регистрации нажатия(срабатывание прерывания и выход из сна), но к хорошему надо привыкать и стараться делать как надо - потом этот алгоритм ещё в какой проект утащишь и т.д.


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites
11 час назад, Alexeyslav сказал:

 но к хорошему надо привыкать и стараться делать как надо - потом этот алгоритм ещё в какой проект утащишь и т.д.

Вчера набросал, вроде работает как надо, когда красиво допишу, здесь выложу для проверки, если вас не затруднит.


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Здравствуйте! Пишу программу для Atmega8a на Atmel Studio 7, эмулирую на Proteus 8. Решил ввести режим СНА так называемый  POWER DOWN для остановки тактового генератора (внутреннего или внешнего- без разницы).  Накидал строки для подготовки, сна и выхода из сна... Но! некорректно работает выход из сна. Родной атмеловский сайт и прочие мурзилки говорят, что при выходе из сна МК должен ПРОДОЛЖИТЬ работу с места спячки, а у меня чего-то поучается сон-и сразу после выхода из сна - в начало заголовка main по коду. Да, еще, выход из сна обеспечивается по INT0- так мне нужно.

Код ниже:

***************

// ATmega8a
#define F_CPU 1000000UL // частота МК 1МГц

#include <avr/interrupt.h>
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/io.h>  //  Подключили описание контроллера
#include <util/delay.h> // Подключили библиотеку задержек

int main(void)
{
    DDRD = 0b00000000;
    DDRC = 0b00110000; 
    PORTC |= (1 << PC4); 
    _delay_ms(1000);
    PORTC &= ~(1 << PC4);
    _delay_ms(1000);
    PORTC |= (1 << PC4);

                                     // set sleep mode
        GICR|=(1<<6);               //разрешаем прерывание по INT0
        GIFR|=(1<<6);
        MCUCR|=((0<<1)|(0<<0));     //прерывание по 0 сигнала на INT0
        sei();                      // разрешаем прерывания глобальные
        
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        cli();
    while(1)
    {
            if (PINC &= 1<<PC0) 
            {
                            // плюс внутри while планируется писат сой код....
                            // sleep_mode() has a possible race condition
        sleep_enable();
        sei();
        _delay_ms(1000);
        sleep_cpu();        // тут засыпаем и с этой же точки проснемся (по идее???   и дальше продолжить вниз по коду, зажечь диод на PC5)
    
        sleep_disable();
        GICR|=(0<<6);       // отключить прерывание по инт0
        GIFR|=(0<<6);
        
        PORTC |=(1<<PC5);     // идентификатор того что программа после сна выполняется дальше не перескакует в начало на main                     
            }
        sei(); 
      }
}

************************************************

Просто нужно именно, чтобы код продолжал выполняться дальше после сна, т.е.  не блымал светодиод на РС5, а не перескакивал на main в начало.

son.c

proteus.PNG

SLEPP_MODE.pdsprj

SLEPP_MODE.pdsprj.AdminPC.Admin.workspace

Share this post


Link to post
Share on other sites

А обработчик прерывания вы написали? При возникновении прерывания идет прыжок именно в обработчик и только после него обратно в программу. Если прерывание не нужно, объявите его как EMPTY_INTERRUPT(INT0_vect); вместо обычного ISR();


Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • Это мертворожденная тема - у ТСа ничего нет, он предполагаемое выдает за наблюдаемое. Зря тратится время на обсасывание технически ничтожной (лишенной смысла) конструкции.  
    • спасибо всем   за  помощь )) 
    • Потому что дешевле купить новое. Хотите возиться сами, - разбирайтесь, учитесь, возитесь. Вон ведь только что вы сабвуфер запустили - нашли схему, более-менее разобрались, пару наводящих ответов получили и справились. Сейчас-то случай чем отличается?  Какой вопрос задали, такие ответы и получили.  
    • Вся ветка и советы бессмысленны, пока реализуемость исходных данных  основана только на слепой вере ТС [во что-то]. Установить это, придав смысл коллективному поиску решения, элементарно - достаточно указать, какой аккумулятор используется. Но ТС упорно нежелает указать основной параметр, от которого зависит все. Интересно, почему?    
    • Да все давным давно всё продрали. Даже ватники и ымперцы. 
    • такое бывает не всегда. я сам был свидетелем, когда уходящий уничтожил все свои наработки - по принципу "кошка бросила котят, пусть .. как хотят". я лично вижу, что есть полезные, рациональные, "зерна" и у одного оппонента и у другого. но мы наблюдаем несовместимость "стандартов" у оппонентов ...
    • Это безусловно не работает. Кругом одни бараны потому что. Предложение байкотировать было внесено и нами тоже, лишь с целью посмотреть, а сколько же людей из баранов вышло? Маловато пока. Всё равно это сование ни на что не повлияет, когда народ подерёт глаза. Уже очень много продрали, но пока не достаточно видимо.
×
×
  • Create New...