Atmega 8. Выход из режима power-down.

Обсуждаем контроллеры компании Atmel.
Ответить
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Добрый день!
Использую в своем девайсе контроллер Atmega8 совместно с часами реального времени DS1339. По задумке, будильник часов должен выводить контроллер из спящего режима, с помощью подтяжки линии прерывания к земле. Линия также подтянута к питанию через резистор. Использую режим power-down, как самый экономичный. Согласно даташиту, из этого режима контроллер выходит с помощью внешнего прерывания или ресета. Прерывание настроено на срабатывание по перепаду из 1 в 0, однако он категорически отказывается из него выходить. Без использования спящего режима все в порядке, прерывание срабатывает. В чем может быть дело?
Заранее благодарен.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

kushman писал(а):Прерывание настроено на срабатывание по перепаду из 1 в 0, однако он категорически отказывается из него выходить.
Естессно отказывается. Читайте в ДШ раздел вывода из сна по прерываниям внимательней (сноки и пр.).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

данный МК не пробуждается из Power Down по внешнему прерыванию, настроенному на перепад (фронт) - настройте прерывание на УРОВЕНЬ и будет вам счастье.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Да, извиняюсь за свою невнимательность, пропустил это в даташите.
Но возникла другая проблема, МК вообще не хочет генерировать прерывание по уровню.
Хотя часы притягивают линию к земле, это точно, тестером проверял. Может маленькая длительность?
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

kushman писал(а):Может маленькая длительность?
Может, прерывание не настроено?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
akl
Друг Кота
Сообщения: 4462
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

kushman писал(а):Хотя часы притягивают линию к земле, это точно, тестером проверял. Может маленькая длительность?
Может это поможет.
Реклама
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Да нет, все вроде настроено, я только поменял пару битов в регистре MCUCR, настроил их на работу по низкому уровню (ISC11=0, ISC10=0). По перепаду без использования спящего режима срабатывает на ура, а по уровню, что со спящим, что без спящего - никакой реакции.
akl
Друг Кота
Сообщения: 4462
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

С примером кода было бы проще.
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Вот кусок кода (лишнее выкинул).

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

interrupt [EXT_INT1] void INT1_ISR(void)
{  
    normal_mode();
}  

void sleep_mode(void) {

   MCUCR = MCUCR|0xA0; //SE=1, power-down mode
   #asm 
   sleep 
   #endasm

}

void normal_mode(void) {
   
   #asm
   nop
   nop
   nop
   nop
   nop
   #endasm
   MCUCR = MCUCR&0x7F; //SE=0;            

}

void INT_Init(void) {
   
     GICR=0xC0; 
     MCUCR=0x00;   
}

void main(void) {
   
    INT_Init();
    SREG.7=1; 
    sleep_mode();
}

akl
Друг Кота
Сообщения: 4462
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

В принципе нормально. Если бы ещё сделали так
void sleep_mode(void) {

MCUCR = MCUCR|0xA0; //SE=1, power-down mode
; #asm
; sleep
; #endasm

- при высоком уровне на входах INTx сбросить флаги
GIFR=0xC0
- глобально разрешить прерывания
SREG.7=1
- и только теперь
#asm
SLEEP
#endasm
то камень обязан уйти в POWER DOWN
Но, вопрос корректного выхода из POWER DOWN остался.
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Пробовал сгенерировать прерывание по уровню без спящего режима - не срабатывает. По перепаду - пожалуйста, по уровню - ни в какую. Вот в чем проблема. С чем это может быть связано?
Линия то притягивается к земле, это точно.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

А ДО этого, она удерживается в плюсе? Может попробовать не прерывание от порта, а специальный вход внешнего прерывания INT0/INT1?
Последний раз редактировалось Alexeyslav Чт мар 27, 2014 15:43:59, всего редактировалось 2 раза.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Alexeyslav писал(а):Может попробовать не прерывание от порта, а специальный вход внешнего прерывания INT0/INT1?
В смысле? Из PD только INT0/INT1 и выводят.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Alexeyslav писал(а):А ДО этого, она удерживается в плюсе? Может попробовать не прерывание от порта, а специальный вход внешнего прерывания INT0/INT1?
Так и и использую вход INT1. А как от порта можно прерывание получить? Или может я что-то не понял. :)
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

kushman писал(а):А как от порта можно прерывание получить?
В других МК есть прерывания от портов.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Вымогатель припоя
Сообщения: 541
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

kushman писал(а):

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


     GICR=0xC0; 

0xC0 == 11000000 , значит разрешены прерывания INT0,INT1 , а обработчик прерывания только для INT1.
Если раньше возникнет INT0, то начнется цирк.

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

MCUCR = MCUCR&0x7F;
Чего этим хотите достичь?

Попробуйте оформлять в виде

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

	MCUCR &= ~((1<<ISC11) | (1<<ISC10)); //INT1 low level
	GICR     |=    (1<<INT1);           // разрешить прерывание INT1

Сразу видно что к чему.

Я бы советовал изменить логику программы, изменения режимов работы производите в маин, а в прерывании устанавливайте информационный флаг.
Вымогатель припоя
Сообщения: 541
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Гляньте на пример.

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

/*
 * main.c
 *
 *  Created on: 27.03.2014
 *      Author: Marian
 */

#include <avr/io.h>
#include <avr/interrupt.h>
 #include <avr/sleep.h>

volatile uint8_t flag1;
uint8_t musor;


ISR(INT1_vect )
{
    // user code here
	flag1=0;
}

int main(void)
{
	DDRB = 0xFF;//na vyvod

	DDRD  &=~((1<<PD3)|(1<<PD0)); //na vvod
	PORTD |= (1<<PD3)|(1<<PD0);   //vkl podciazku

	MCUCR &= ~((1<<ISC11) | (1<<ISC10)); //INT1 low level
	GICR     |=    (1<<INT1);           // разрешить прерывание INT1

	flag1=1;//dla otslezivanija prerywanija
	musor=0; //dla primera;

	set_sleep_mode(SLEEP_MODE_PWR_DOWN);

	while (1)
	{

			musor++;
			PORTB = musor;
			if((PIND & 0x01)!= 0x01 )
			{
				flag1=1;
				sei();
				sleep_mode();
				cli();
			}

		}

} //


В архиве проект для протеуса
temp.rar
(42.9 КБ) 234 скачивания
Вымогатель припоя
Сообщения: 541
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Тут присутствует одна особенность, прерывания (если назначены по низкому уровню) происходят до тех пор, пока на ноге низкий уровень.
Значит проц будет постоянно выходить из повер довн.
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Попробовал выводить контроллер из спящего режима по любому логическому изменению на INT1 - и все в порядке, выходит и работает. Единственная загвоздка в том, что возникает два прерывания, несмотря на то, что они глобально запрещены на время обработки.
Сегодня еще попробую вышеприведенный код, посмотрим что получится.
Вымогатель припоя
Сообщения: 541
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Не ясно для чего вы выставляете "по любому логическому изменению на INT1", если есть возможность выставить по фронту или по спаду на INT1.
kushman писал(а): Единственная загвоздка в том, что возникает два прерывания, несмотря на то, что они глобально запрещены на время обработки.
Флаг прерывания устанавливается, даже если они глобально запрещены, если есть необходимость выполните ручной сброс флага прерывания, перед разрешением прерываний.
Ответить

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