Перейти к содержанию

Программа Выхода Из Спящего Режима Для Atmega


Гость Гость

Рекомендуемые сообщения

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов 58
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

А где вы нашли регистр GICR в меге88? За прерывания там отвечает регистр EIMSK – External interrupt mask register

Изменено пользователем Goodefine

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Понял. Пошол гуглить.

Понимаю что Вам мои ошибки кажутся нелепыми, но не судите строго. Была бы возможность- пошел бы на курсы. Но у нас в глубинке их нет

Второй вопрос. Если не GICR, то как разрешить внешние прерывания в 88 меге?

Спасибо за ответы.

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

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

Эмулировал в протеус. На нажатие кнопки эффекта нет

/*

* GccApplication1.c

*

* Created: 25.02.2014 22:57:11

* Author: user

*/

#include <avr/io.h>

#include <avr/interrupt.h>

#include <stdio.h>

volatile unsigned long X = 1;

void int0_init( void )

{

//настраиваем на срабатывание INT0 по переднему фронту

MCUCR |= (0<<ISC01)|(0<<ISC00);

//разрешаем внешнее прерывание INT0

EIMSK |= (1<<INT0);

}

//функция обработчик внешнего прерывания INT0

ISR( INT0_vect )

{

X++;

}

int main(void)

{

DDRD = 0x00;

PORTD = 0xFF;

DDRB = 0xFF;

PORTB = 0x00;

sei();

while(1)

{

cli();

if(X == 2)

{

PORTB|= (1 << PB0);

X = 0;

}

if(X == 1)

{

PORTB&= ~(1 << PB0);

}

if(X == 0)

{

PORTB|= (1 << PB0);

}

sei();

//TODO:: Please write your application code

}

}

Ссылка на комментарий
Поделиться на другие сайты

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

Потому что реализованно через одно место.

Если ты используешь прерывание, не имеет смысла делать проверки в главном цикле.

Смотри, сейчас на словах объясню, а ты в код переведи.

Выкинь нафиг переменную X. Все проверки лучше делать в обработчике прерываний (ОП).

По нажатию кнопки вызывается ОП, там ты проверяешь включен светодиод или нет, если нет- то включаешь, есть да- то выключаешь. То то и всего. Главный цикл (while(1){}) оставь пока пустым.

Ссылка на комментарий
Поделиться на другие сайты

БЛин. Даже это не идет. Компилиться без ошибок. Но не фачит в протеусе.3 часа над 3 строчками . Просто ж...

/*

* GccApplication1.c

*

* Created: 25.02.2014 22:57:11

* Author: user

*/

#include <avr/io.h>

#include <avr/interrupt.h>

#include <stdio.h>

void int0_init( void )

{

//настраиваем на срабатывание INT0 по переднему фронту

MCUCR |= (0<<ISC01)|(0<<ISC00);

//разрешаем внешнее прерывание INT0

EIMSK |= (1<<INT0);

}

//функция обработчик внешнего прерывания INT0

ISR( INT0_vect )

{

if(PORTB== ~(1 << 0))//проверяем состояние PB0

{

PORTB |= (1 << 0);//если PB0 = 0, ставим 1

}

else

{

PORTB &= ~(1 << 0);//иначе - 0

}

}

int main(void)

{

DDRD = 0x00;

PORTD = 0xFF;

DDRB = 0xFF;

PORTB = 0x00;

while(1)

{

//TODO:: Please write your application code

}

Ссылка на комментарий
Поделиться на другие сайты

Гость Прохожий

А так?

#include <avr/io.h>
#include <avr/interrupt.h>
ISR(INT0_vect)
{
if(PORTB == (0 << 0))//проверяем состояние PB0
{
PORTB = (1 << 0);//если PB0 = 0, ставим 1
}
else
{
PORTB = (0 << 0);//иначе - 0
}
}
int main(void)
{
PORTD = 0xFF;
DDRB = 0xFF;

MCUCR |= (0<<ISC01)|(0<<ISC00);
EIMSK |= (1<<INT0);
sei();
while(1){}
}

Ссылка на комментарий
Поделиться на другие сайты

Снимаю шляпу!

Спасибо! Если честно, очень многое понял благодоря Вам!

Буду пытаться дальше, хочу попробовать внедрить спящий режим. Если не совсем достал, то буду продолжать спрашивать по ходу действия.

Ссылка на комментарий
Поделиться на другие сайты

Гость Прохожий

Если не совсем достал, то буду продолжать спрашивать по ходу действия.

Спрашивай конечно, чем смогу помогу.

P.S В студии есть свой дебаггер, вполне себе замена протеусу. Советую его освоить, ибо в протеусе не видно содержание регистров, портов PINx, DDRx; PORTx и т.д.

При отладке в студии намного легче понять в чем именнотвоя ошибка. А в протеусе только два варианта, либо работает, либо нет, никакой дополнительной информациию

Ссылка на комментарий
Поделиться на другие сайты

Советую его освоить, ибо в протеусе не видно содержание регистров, портов PINx, DDRx; PORTx и т.д.

При отладке в студии намного легче понять в чем именнотвоя ошибка. А в протеусе только два варианта, либо работает, либо нет, никакой дополнительной информациию

А пацаны то не знают...

post-20311-0-49029500-1393710633_thumb.gif

if(PORTB == (0 << 0))//проверяем состояние PB0
{
PORTB = (1 << 0);//если PB0 = 0, ставим 1
}
else
{
PORTB = (0 << 0);//иначе - 0
}

Сколько понаписано, вместо

PORTB^=1<<0;

Изменено пользователем Goodefine

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Появилось немного свободного времени и смог заняться делом

И снова у меня нейкая хрень. Ошибок нет, но и не фачит.

Хочу чтобы контроллер засыпал по нажатии кнопки на выводе PD0.

Вроде все биты прописал. А эффекта нет

#include <avr/io.h>

#include <avr/interrupt.h>

ISR(INT0_vect)

{

if(PORTB == (0 << 0))//проверяем состояние PB0

{

PORTB = (1 << 0);//если PB0 = 0, ставим 1

}

else

{

PORTB = (0 << 0);//иначе - 0

}

}

int main(void)

{

PORTD = 0xFF;

DDRB = 0xFF;

MCUCR |= (0<<ISC01)|(0<<ISC00)|(1 <<SE)|(0 << SM2)|(1 << SM1)|(0 << SM0) ;//разрешаем спящий режим, выставлчем его как Power Down

EIMSK |= (1<<INT0);

sei();

while(1){

if(PORTD == (1 << 0))//условия входа в спящий

{

asm("sleep");

}

//мигалка. Просто для отслеживания спящего

if(PORTB == (0 << 1))

{

PORTB = (1 << 1);

}

else

{

PORTB &= ~(1 << 1);

}

}

}

Ссылка на комментарий
Поделиться на другие сайты

Не забыли что данные на пинах надо в регистре PIN смотреть? и не используйте никогда сравнение типа if(PORTD == (1 << 0)) - если любой бит порта, кроме нулевого будет равен 1, то оно не выполниться никогда. Биты проверяются через логическое И учтите еще, что при нажатии на кнопку на пине будет 0.

if(!(PIND& (1 << 0)))//условия входа в спящий
{
asm("sleep");
}


Выше было сказано, что простыни типа

if(PORTB == (0 << 0))//проверяем состояние PB0
{
PORTB = (1 << 0);//если PB0 = 0, ставим 1
}
else
{
PORTB = (0 << 0);//иначе - 0
}

Легко заменяются на

PORTB^=1<<0;

Тогда имеем

#include <avr/io.h>
#include <avr/interrupt.h>
ISR(INT0_vect)
{
PORTB^=1<<0;
}
int main(void)
{
PORTD = 0xFF;
DDRB = 0xFF;
MCUCR |= (0<<ISC01)|(0<<ISC00)|(1 <<SE)|(0 << SM2)|(1 << SM1)|(0 << SM0) ;//разрешаем спящий режим, выставлчем его как Power Down
EIMSK |= (1<<INT0);
sei();
while(1){
if(!(PIND& (1 << 0)))//условия входа в спящий
{
asm("sleep");
}
//мигалка. Просто для отслеживания спящего
PORTB^=1<<1; //не забудьте что без задержки в цикле моргать будет очень быстро, может казаться что диод просто горит
}
}

Правильность настроек не смотрел

Изменено пользователем Goodefine

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Понял, спасибо. Сегодня уже башка не варит, по основной работе 14 часов отпахал. А завтра попробую вписать и эмулировать.

Простыню не заменял потому что учусь и оно так как-то лучше воспринимаеться. И пример наглядный.

Не сомневайтесь, PORTB^=1<<0; я запомнил.

В общем понял.Утром буду штурмовать

Ссылка на комментарий
Поделиться на другие сайты

Всеравно не засыпает.

Настройки взял отсюда из таблицы http://samou4ka.net/...ontrollerov-avr

И еще один вопрос.

По поводу задержки

Пытался так, но не канает.

#include <util/delay.h>

_delay_ms(200);

Как на 88 меге правильно вписать задержку? Хочу знать на будущее

Ссылка на комментарий
Поделиться на другие сайты

Простыню не заменял потому что учусь и оно так как-то лучше воспринимаеться. И пример наглядный.

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

Всеравно не засыпает.

Настройки взял отсюда из таблицы http://samou4ka.net/...ontrollerov-avr

Научитесь пользоваться даташитом, ведь был же уже пример с прерываниями. Посмотрите за что отвечает регистр MCUCR в mega88. Никаких режимов энергосбережения там нет и в помине. Потом найдите нужный регистр (подсказываю - SMCR)

По поводу задержки

Пытался так, но не канает...

Что значит "не канает"? Не компилируется или не то время получается или еще что?

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Гость Прохожий

Всеравно не засыпает.

Настройки взял отсюда из таблицы http://samou4ka.net/...ontrollerov-avr

Вот мой пример на Atmega8, тут контроллер спит все время, а по нажатию кнопки просыпается. Под mega88 думаю сам сможешь перевести..

#define F_CPU 1000000UL // 1 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
ISR(INT1_vect)
{
PORTB^=(1<<1);
_delay_ms(100);
}
int main(void)
{
PORTD = (1 << PD3);
DDRB = (1 << PB1);

MCUCR |= (1 << SE) | (1 << SM1);
GICR |= (1 << INT1);
sei();

while (1)
{
asm("sleep");
}
}

Как на 88 меге правильно вписать задержку? Хочу знать на будущее

Ошибки так читать и не научились.

Вот эту строку в самое начало вставь "#define F_CPU 1000000UL" :)

И вообще выложи свою схему подключения (мк, кнопки и светодиоды).

P.S

Сколько понаписано, вместо

PORTB^=(1<<0);

Угу, но помоему эта команда лищена какого либо лог. смысла. А именно из-за конструкции (1<<0), которая на окончательный результат вообще не влияет.

Ссылка на комментарий
Поделиться на другие сайты

Угу, но помоему эта команда лищена какого либо лог. смысла. А именно из-за конструкции (1<<0), которая на окончательный результат вообще не влияет.

Это называется первый класс вторая четверть. Так пишут для унификации, PORTB^=(1<<1) - тоже не имеет смысла? А еще лучше так PORTB^=(1<<PB1);

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Спасибо, заработало!

И засыпает, и прасыпаеться))

Прохожий, я уже про схему и забыл. Просто учусь. Схемки кидаю сразу по месту в протеусе. Думаю что выкладывать нет смысла. Если что поправьте, и я сразу выложу.

"#define F_CPU 1000000UL" - как я понимаю это частота тактового генератора. А во фьюзах почему нельзя выставить?

Goodefine, и к Вам вопрос

строка

if(!(PIND& (1 << 0)))//условия входа в спящий - для чего здесь "!" ?

Ссылка на комментарий
Поделиться на другие сайты

Гость Прохожий

Спасибо, заработало!

Думаю что выкладывать нет смысла.

Ну если заработало, то да, смысла уже мало..

"#define F_CPU 1000000UL"- это предпологаемая частота процессора. Нужна для правильного расчета задержек _delay_ms(), а реальная ставиться как раз таки через фьюзы.

Не Goodefine, но и на последний отвечу. Восклицательный знак (!) - это оператор "Нет/Not", или как-то так.. Вот здесь ты проверяешь есть ли на пине PINB0 лог. единица (PIND& (1 << 0)), но так как у тебя кнопка подключена к земле (лог.нуль) то при помощи ! ты всю конструкцию переворазиваешь.

Если все еще не понял, смотри.

if(1==1) ; верно

if(1!=1);не верно

if(1!=5); верно и тд

Ссылка на комментарий
Поделиться на другие сайты

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

В общем, для полной проверки, решил я проделать засыпание-просыпание меги 88 в железе....и облом.

Сразу скажу, что в протеусе все работает без вопросов.

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

Изначально залил такой код...ну почти изначально, он уже упрощен удалением всех задержек. Хотел максимально упростить и получить хоть что-то:

/*

* _001.c

*

* Created: 16.03.2014 1:10:30

* Author: user

*/

#include <avr/interrupt.h>

#include <avr/io.h>

#include <util/twi.h>

ISR(INT0_vect);

int main(void)

{

PORTD |= (1<<2) ;//выставляем INT0 на вход

DDRB = 0xFF;

SMCR |= (1 << SE)|(1 << SM1);//разрешаем спящий режим, выставлчем его как Power Down

EIMSK |= (1<<INT0);

while(1)

{

PORTB^=1<<1;

if((PIND& (1 << 2)))//условия входа в спящий

{

sei();

asm("sleep");

}

//TODO:: Please write your application code

}

}

Эффекта ноль. Я прифигел т.к. в протеусе все работало, а в схеме состоящей из контроллера, одной кнопки и диода запутаться тяжело. Перепроверил осцилографом.....пусто.

Тогда залил код еще проще:

#include <avr/interrupt.h>

#include <avr/io.h>

#include <util/twi.h>

ISR(INT0_vect);

int main(void)

{

PORTD |= (1<<2) ;//выставляем INT0 на вход

DDRB = 0xFF;

SMCR |= (1 << SE)|(1 << SM1);//разрешаем спящий режим, выставлчем его как Power Down

EIMSK |= (1<<INT0);

while(1)

{

if(!(PIND& (1 << 2)))//условия входа в спящий

{

PORTB^=1<<1;

}

else

{

PORTB |= (1 << 1) ;

}

//TODO:: Please write your application code

}

}

И также эффекта ноль.

Методом научного тыка определил что если закоментить //EIMSK |= (1<<INT0); второй вариант кода начинает работать. Первый, понятное дело, нет.

В протеусе работают оба варианта((

Подскажите пожалуйста, что сейчас не так? В чем конфликт? Мега 88 20PU в дипе

Ссылка на комментарий
Поделиться на другие сайты

Гость Прохожий

Ты не отдаешь себе отчет о том что пишешь и для чего. Твой код исправлять не буду, дам только подсказку- пустой ISR(INT0_vect); - надеюсь сам до завтра догадаешься.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...