atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Обсуждаем контроллеры компании Atmel.
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

Доброго времени суток. Проектирую простенькую схемку в Proteus для 8 меги. Вообщем, это бомбочка для страйк-бола. Итак, (омсяпишу, дабы оставить лишние вопросы позади)

инициализируемся()
засыпаем()
просыпаемся по INT0()
включаем таймер ноль на отсчет секунд()
начинаем контроллировать выведенные провода на разрыв()
//один на обезвреживание, один на взрыв, пустышка 2 штука и ускорение в два раза таймера тоже 2 штука
и соответствено по окончанию таймера - взрываемся и ,соответственно, если перерезаются провода, тоже выполняем необходимое.


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

Так вот в чем проблема, после засыпания мы уже не просыпаемся ни в какую. Таймеры со внешними прерываниями тоже тормозятся. Недосланyый асинхронный UART остается недосланным. -_-
Вообщем прошу помощи.
Пишу на AVR-GCC в Atmel studio. Из средств отладки на руках, что знаю, только proteus и uart-terminal в нем. Железо на мега8 тоже не собрано, да и в отладке это не особо и поможет. Студия отказывается отлаживать в симуляторе(свою неопытность не отрицаю), но она мне намекнула, что точки останова на этом контроллере не поддерживаются.

(еще были проблемы в proteus с прерываниями по возрастающему фронту с подтяжкой ноги к питанию и соединением ее через разрывной тумблер с корпусом. Просто подтянул к земле в протеусе, убрал подтяжку в порте, настроил на ниспадающий фронт-_-)

вот схема из протеуса и код, проект протеуса тоже.

Изображение

приведу весь код

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

/*
 * theBomb.c
 *
 * Created: 12.03.2015 20:37:09
 *  Author: andre
 */ 
/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#define _IN 0
#define _OUT 1
#define _PULLUP 1
#define _LOW 0
#define _HIGH 1
/* 9600 baud */
#define UART_BAUD_RATE      9600

#define uart_nextline uart_putc(13);


#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/cpufunc.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include "uart/uart.h"

volatile unsigned int cnt = 0;
volatile unsigned int seconds_counter =0;
volatile bool check_pull = false;
volatile unsigned int freq = 30;



void enable_timer0(bool enable);
void enable_int0(void);
void disable_int0(void);
void init_timer0(void);
void init_ports(void);
void set_check_led(void);
void do_explode(void);
void read_ports_work(void);
bool is_in_service_mode(void);

//названия портов в/в

//#define loop_until_bit_is_clear(port,bit) \ __asm__ __volatile__ ( \ "L_%=: " "sbic %0, %1" "\n\t" \ "rjmp L_%=" \ : /* no outputs */ : "I" (_SFR_IO_ADDR(port)), "I" (bit) )

//#define loop_until_bit_is_clear(port,bit) __asm__ __volatile__ ( "1: " "sbic %0, %1" "\n\t" "rjmp 1b" : /* no outputs */ : "I" (_SFR_IO_ADDR(port)), "I" (bit) )


//Interrupt Service Routine for INT0
ISR(INT0_vect)
{
	
	//check service mode
	//if (is_in_service_mode())
		//return;
	
	uart_puts("in INT0 ISR");
	uart_nextline
	disable_int0();
	enable_timer0(true); // enable timer0
	check_pull=true;
	
}


// Timer 0 overflow interrupt service routine
ISR(TIMER0_OVF_vect) 

{
	
	enable_timer0(false); // disable timer0
	cnt++;
	if (cnt>=freq)
	{

		cnt=0;
		uart_puts("timer0 interrupt approx 1 sec");
		uart_nextline
		seconds_counter++;
		if (seconds_counter>=30)
			do_explode();
		else 
			read_ports_work();
			
		cli();
		TCNT0 = 0;
		sei();

	}
	enable_timer0(true);
}


//check all wires to be connected
bool check_system(void)
{
	
	return true;
}

void enable_timer0(bool enable)
{
	if (enable)
		TIMSK |= ( 1 << TOIE0); // enable timer0;
	else 
		TIMSK &= ~( 1 << TOIE0); // disable timer0
	
}

void enable_int0(void)
{
	//initialize interrupts
	GICR = (1<<INT0);					// Enable INT0
	MCUCR =( 1<<ISC01) | (0<<ISC00);	// Trigger INT0 on falling edge
}

void disable_int0(void)
{
	GICR&= ~(1<<INT0);	
}


void init_timer0(void)
{
	//initialize timers
	// Timer/Counter 0 initialization
	// Clock source: System Clock
	// Clock value: 7,813 kHz     (/255/30 to approx 1 sec) (tim0 ovf even 30 interrupt)
	TCCR0=(1<<CS02) | (0<<CS01) | (1<<CS00);

	// initialize counter
	TCNT0 = 0;
}

void init_ports(void)
{
	// Input/Output Ports initialization
	// Port B initialization
	// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
	DDRB=(_IN<<DDB7) | (_IN<<DDB6) | (_IN<<DDB5) | (_IN<<DDB4) | (_IN<<DDB3) | (_IN<<DDB2) | (_IN<<DDB1)| (_IN<<DDB0);
	// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=P Bit1=P Bit0=P
	PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (_PULLUP<<PORTB0);

	// Port C initialization
	// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=Out
	DDRC=(_IN<<DDC6) | (_IN<<DDC5) | (_IN<<DDC4) | (_IN<<DDC3) | (_IN<<DDC2) | (_IN<<DDC1) | (_OUT<<DDC0);
	// State: Bit6=T Bit5=P Bit4=P Bit3=P Bit2=P Bit1=P Bit0=0
	PORTC=(0<<PORTC6) | (_PULLUP<<PORTC5) | (_PULLUP<<PORTC4) | (_PULLUP<<PORTC3) | (_PULLUP<<PORTC2) | (_PULLUP<<PORTC1) | (_HIGH<<PORTC0);

	// Port D initialization
	// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
	DDRD=(_IN<<DDD7) | (_IN<<DDD6) | (_IN<<DDD5) | (_IN<<DDD4) | (_IN<<DDD3) | (_IN<<DDD2) | (_IN<<DDD1) | (_IN<<DDD0);
	// State: Bit7=0 Bit6=0 Bit5=0 Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
	PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
	
	
	
}

void set_check_led(void)
{
	
}

bool is_in_service_mode(void)
{
	
	
	return false;
}


void do_explode(void)
{
	//check service mode
	if (is_in_service_mode())
		return;
		
		
}

void read_ports_work(void)
{
	
	
	
}


int main(void)
{
	
	init_ports();
	enable_int0();
	init_timer0();

	
	//initialize UART on 9600
	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
	
	//enable interrupts
	sei();
	
	
	uart_puts("Initializing...");
	uart_puts("Ok.");
	uart_nextline
	
	
      
    // sleep_mode() has a possible race condition
	

	
	//checking system wires
	if (check_system())
	{
		set_check_led();
		uart_puts("System check...Ok");
		uart_nextline
		
	}
	
	
	//только в целях отладки подождем UART. Кроме него у нас ничего не должно выполняться асинхронно
	//таймер0 остановлен
	//INT0 инициализирован
	_delay_ms(2000);
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_mode();
	/*
	
	slee_mode=
	    sleep_enable();  \
	    sleep_cpu();     \
	    sleep_disable();
	
	sleep_cpu =
	
	__asm__ __volatile__ ( "sleep" "\n\t" :: );
	
	
	*/
	
	
	//тут мы должны проснуться после сна
	
	
	
	sleep_disable();
	
	uart_puts("Waking up");
	uart_nextline

	
	
	
	
	while(true)
    {
		
	}
}
Вложения
WinRAR archive.rar
файл проекта протеуса и прошивка с проектом Atmel Studio
(76.34 КБ) 150 скачиваний
Последний раз редактировалось punxer Пт мар 13, 2015 17:45:28, всего редактировалось 1 раз.
Реклама
Аватара пользователя
eess9
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение eess9 »

Выложенный вами файл протеуса без hex-файла или проета студии бесполезен, т.к. все равно он не запустится.
А как вы засыпаете?

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

/*
   
   slee_mode=
       sleep_enable();  \
       sleep_cpu();     \
       sleep_disable();
   
   sleep_cpu =
   
   __asm__ __volatile__ ( "sleep" "\n\t" :: );
   
   
   */
единственное sleep_cpu() у вас в комментариях находится...
Реклама
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

за отсутствие прошивки прошу прощения. Прикладывал да недоприкладывал. Не тот архив.
UPD: добавил все

Посмотрите внитаельнее, там sleep_mode();, которая в свою очередь равна

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

sleep_enable();
sleep_cpu();
sleep_disable();
UPDATED:

proteus пишет
Entering power-down mode

если добавить слежение за внешними прерываниями то пишет что взведены оба, хотя

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

void enable_int0(void)
{
	//initialize interrupts
	GICR = (1<<INT0);					// Enable INT0
	MCUCR =( 1<<ISC01) | (0<<ISC00);	// Trigger INT0 on falling edge
}
ни о каком срабатывании не идет речи

если перед сном добавить delay_ms(1.. 2.. 3000), то в это время прерывание сработает

Изображение
Последний раз редактировалось punxer Пт мар 13, 2015 18:03:51, всего редактировалось 1 раз.
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение codenamehawk »

punxer писал(а): с подтяжкой ноги к питанию и соединением ее через разрывной тумблер с корпусом.
Был бы хоть переключающий тумблер. А так КЗ.

punxer писал(а):
Просто подтянул к земле в протеусе, убрал подтяжку в порте, настроил на ниспадающий фронт-_-)
А фронта то и нет, только низкий уровень.
Реклама
Эиком - электронные компоненты и радиодетали
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

1: нога подключена на землю через разрыв и не подтянута к питанию внутри. Когда замкнуто, там 1, при разрыве питания там 0. Нет там кз.
В состоянии не сна внешнее прерывание работает как надо
2:фронт есть и должен быть. Нога при разрыве проводника переходит с подтянутого к питанью состояние в 'подтянутое' к земле.

Если что-то конкретно не правильно во внешней реализации, милости просим

UPD: на счет противня нашел такое
http://forum.chipmk.ru/index.php/topic/ ... e__st__140
но пока единожды, говорят, не работает эмуляция спящего режима.
Тогда вопрос где отлаживать код? кроме реального железа, да и на реальном нет средств отладки, кроме как совать сообщения в UART.
Быть может у кого-то в протеусе работает код засыпания? другой код? Другой протеус..(версия)
Реклама
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение codenamehawk »

punxer писал(а):нога подключена на землю через разрыв
Шедевр номер один.
punxer писал(а):2:фронт есть и должен быть. Нога при разрыве проводника переходит с подтянутого к питанью состояние в 'подтянутое' к земле.
Я надеюсь мы говорим о INT0 ? Который всегда у вас подключен через резистор к земле и фронта там отродясь не найдешь.
Реклама
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение codenamehawk »

С такими номиналами у вас и ресет не сработает.
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

Изображение

вот тут делитель напряжения на 2х резисторах. Что такое фронт?(передний) фронт это начало импульса(говорю примитивно простите)будь то положительный или отрицательный импульс. Его отрезок изменения от одного состояния к другому.
думается мне там там будет такое изменение с уровня единицы до уровня ноля. задний фронт положительного импулься

я в чем-то не прав?

UPD: номиналы не выбирал особо, ибо думалось, в цифре proteus не придирчив к этому?
Какие номиналы взять тут
Последний раз редактировалось punxer Пт мар 13, 2015 18:46:46, всего редактировалось 1 раз.
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

Изображение

вот, например, по нарастающему фронту
ногу стоит настроить на отсутствие подтяжки или убрать резистор

но так в протеусе прерывание срабатывает сразу после старта
аналогичный код писал даже в arduino среде для atmega8 и все равно прерывание при старте
поэтому я перешел на ниспадающий фронт в proteus. с этим вариантом проблем не было при симуляции прерываний
Последний раз редактировалось punxer Пт мар 13, 2015 18:49:36, всего редактировалось 1 раз.
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение codenamehawk »

Про фронт понимаете правильно. А вот к резисторам протеус придирчив.
Есть у него деталь RES называется, так для нее возможно выставить тип DIGITAL, но это вам тоже не поможет, в вашей схеме будет КЗ.
Если не ошибаюсь, выход из SLEEP_MODE_POWER_DOWN, только по уровню (по фронту не сработает). По второй схеме Ресет должен рабатать .
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

как схематически правильно сделать внешнюю часть прерывания по кнопке на разрыв с прерыванием по низкому уровню? подскажите
reset у меня просто постоянно к питанию притянут. Котики, ну поучавствуйте, я из болгарии))))
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение codenamehawk »

Для протеуса так
shema.JPG
(124.39 КБ) 653 скачивания
Я из Литвы, вам от этого легче?
Последний раз редактировалось codenamehawk Пт мар 13, 2015 19:25:39, всего редактировалось 1 раз.
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

Изображение

прерывание настроено на низкий уровень, засыпает и не просыпается. В отсутствие сна прерывание имеется

я это к слову о соседнем топике говорил, в котором все сделали за человека из болгарии))

в первом сообщении есть файл протеуса в архив
вывод на терминал работает на ура
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение codenamehawk »

Помочь да, делать за кого то человека из болгарии нет.
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

я разве похож на человека просящего сделать за него?
у меня код, написанный мной.
Проект в протеусе, сделанный мной. Я разве спрашиваю очевидные вещи,как мне зажечь светодеод,?
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

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

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

	set_sleep_mode(SLEEP_MODE_IDLE);
	sleep_enable();
	sleep_cpu();
	//тут мы должны проснуться после сна
	sleep_disable();
	
	//checking system wires
	if (check_system())
	{
		set_check_led();
		uart_puts("System check...Ok");
		uart_nextline
			
	}
	
	
	uart_puts("Waking up");
	uart_nextline

	
	
	
	
	while(true)
    {
		sleep_enable();
		sleep_cpu();
	}
}
в цикле тоже есть переход в спящий режим, но цикл начинает выполняться только после выполнения прерывания int0, в котором стартует таймер, который в свою очередь будет будить мк. Так что, тут ничего не скажу
Знает кто, имеет смысл так использовать спячку?
я все еще хочу фатальный спящий режим)
Пробовал MCUCR писать, тоже спим на всю жизнь(
мб есть варианты обхода этого( косяка) в Proteus?
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение uk8amk »

Так я не понял, вы разобрались со своей ошибкой в коде или нет?
На всякий случай:

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

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
GICR|=0x40;
MCUCR=0x00;
GIFR=0x40;

// Global enable interrupts
#asm("sei")

sleep_enable();
powerdown();

while (1)
      {

      };
Протеус исправно засыпает и просыпается. В старой AVR studio 4 в режиме симулятора(AVR simulator) точки останова ставятся и код симулируется корректно(в т.ч. режим сна).
punxer
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт сен 04, 2008 21:15:02
Откуда: Rzhev (Moscow now)
Контактная информация:

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение punxer »

нет, не разобрался, что у вас powerdown()? какая версия протеус?
и о какой ошибке в коде вы говорите?

У меня не получается запустить симулятор в atmel studio c мегой8, как мне это сделать.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение uk8amk »

протеус 7.5
powerdown - встроенная в компилятор ф-ция. Вот её внутренности:

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

	.SET power_ctrl_reg=mcucr
void sleep_enable(void)
{
#asm
   in   r30,power_ctrl_reg
   sbr  r30,__se_bit
   out  power_ctrl_reg,r30
#endasm
}

void powerdown(void)
{
#asm
   in   r30,power_ctrl_reg
   cbr  r30,__sm_mask
   sbr  r30,__sm_powerdown
   out  power_ctrl_reg,r30
   sleep
#endasm
}
Как видите, всё по даташиту, кроме некоторой шелухи.
Касательно ошибки.

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

   MCUCR =( 1<<ISC01) | (0<<ISC00);   // Trigger INT0 on falling edge
Никогда не выведет МК из глубокого сна т.к. в этом режиме прерывание по фронту невозможно.
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: atmega8 proteus проблемы с sleep (SLEEP_MODE_POWER_DOWN)

Сообщение codenamehawk »

Про ошибку я уже писал. В протеусе работает, если заменить строку MCUCR &=~(( 1<<ISC01) | (1<<ISC00)); // Trigger INT0 LOW LEVEL
codenamehawk писал(а):Если не ошибаюсь, выход из SLEEP_MODE_POWER_DOWN, только по уровню (по фронту не сработает).
В 6 студии требуется установить заходы в прерывания.

Изображение

Структура программы не верна(хотя и может работать)
В прерывании устанавливайте переменную, а длительные операции выполняйте в майн.

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

volatile bool flag_int0; //Ustanavlivajetsa v TRUE jesli bylo preryvanije INT0

//Interrupt Service Routine for INT0
ISR(INT0_vect)
{
  flag_int0 = true;	
}

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

int main(void)
{
  flag_int0 = false;
....
....
   while(true)
    {
	if (flag_int0 == true)
		{
                       Vot tut kod, kotoryj neobhodimo vypolnit, jesli srabotalo preryvanije INT0, n.p. vyvod v UART
                       .....
                       .....
			flag_int0 = false;
		}
		
	}
}
Вложения
settings.JPG
(45.68 КБ) 2198 скачиваний
Ответить

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