Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.67/52: Рейтинг темы: голосов - 52, средняя оценка - 4.67
1000s
0 / 0 / 0
Регистрация: 18.03.2017
1

Сон в Atmega8a

26.01.2014, 11:17. Просмотров 9595. Ответов 20
Метки нет (Все метки)

Решил на днях попробовать спяцие режимы авр. В качестве подопытного использую Atmega8a. С точки зрения потребления, самый интересный режим - power save его и будем использовать.
Ну подключил внешний часовой кварц, помигал светодиодиком по прерыванию, прогнал это в IDLE режиме. Но в power save ни в какую не хочет просыпаться, помогите пожалуйста.
В гугле был.
Код
Код
   #define XTAL 4000000L    // 4 MHz
#define baudrate 19200L
#define bauddivider (XTAL/(16*baudrate)-1)
#define HI(x) ((x)>>8)
#define LO(x) ((x)& 0xFF)

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

#define LED1 0
#define LED2 1
#define LED_PORT PORTC
#define LED_PIN PINC
#define LED_DDR DDRC

volatile uint8_t count;

volatile uint8_t sec;
volatile uint8_t min;
volatile uint8_t hour;

void USORT_init(void)
{
UBRRH=HI(bauddivider);
UBRRL=LO(bauddivider);//9600 бод
UCSRB = (1<<RXEN)|(1<<TXEN);//прерывания отключены, разрешение передачи
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//размер слова 8 бит
}

void TIMER_ASS_init(void)
{
ASSR  = 1<<AS2;                // Включаем асинхронный режим
TCNT2 = 0;
TCCR2 = 5<<CS20;                 // Предделитель на 128 на 32768 даст 256 тиков в секунду
}

//отправка символа по usart`у
void uart_write(unsykned char sym)
{
while(!(UCSRA & (1<<UDRE)));
UDR = sym;
}

ISR( TIMER0_OVF_vect ) //прерывание по переполнению таймера 0
{
TCNT0 = 0; //выставляем начальное значение TCNT0
count++;
if (count == 30) //примерно 1 секунда
{
LED_PORT ^= (1<<LED2);
count = 0;
}
}

ISR( TIMER2_OVF_vect ) //прерывание по переполнению таймера 2
{
LED_PORT ^= (1<<LED1);
_delay_ms(10);
sec++;
if (sec == 60)
{
sec = 0;
min++;
uart_write(min);
if (min == 60)
{
min = 0;
hour++;
}
if (hour == 24)
{
hour = 0;
}
}
}

int main()
{

USORT_init();
TIMER_ASS_init();

LED_DDR = (1<<LED1)|(1<<LED2);   // настраиваем PB0, PB1 на выход

//настройка таймера 0
TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00); // настраиваем делитель (000 выкл)(001 без делителя)(010 8)(011 64)(100 256)(101 1024)
TIMSK |= (1<<TOIE0)|(1<<TOIE2); // разрешение прерываний по переполнению таймеров
TCNT0 = 0;        // выставляем начальное значение TCNT1

set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_enable(); // разрешаем сон

sei();                // выставляем бит общего разрешения прерываний

while(1)// вечный цикл
{
sleep_cpu();
_delay_ms(100);
LED_PORT ^=(1<<LED2);
}

}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.01.2014, 11:17
Ответы с готовыми решениями:

ATmega8a, ATmega32a и т.д.
Доброго времени суток! Компания атмель вместо родных нам мег восьмых, шестнадцатых и т.д. стала...

atmega8a ADC
Читаю доку на atmega8 не могу понять что значит цифровое питание и аналоговое при использовании...

БПФ на Atmega8A
Здравствуйте, подскажите пожалуйста, вот в голову пришло сделать гитарный тюнер. Сдуру сразу развел...

Atmega8A-AU + ESP8266
Уважаемые воротилы AVR, у меня к Вам вопрос. Заварганил я значит платку на Atmega8a, законнектил...

Atmega8a ISP 5V
Здравствуйте Можно ли прошивать Atmega8a у которого питание 3.3v, программатором c 5v, если на...

20
яверт
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
26.01.2014, 12:16 2
Регистры асинхронного таймера обновляются довольно медленно, перед сном надо ждать пока Update Busy флаги в ASSR не станут нулями.
0
OtixPM
0 / 0 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
26.01.2014, 14:11 3
ТС, в даташите этой Меги (и любых других AVR, имеющих Timer2/RTC) есть целая глава на 1.5-2 страницы "Как Надо Использовать Асинхронный Таймер". Прочитайте внимательно. Насчёт непробуждения из power-save в той главе тоже есть специальный абзац.

Кстати, зачем в прерывании по переполнению Вы записываете в счётчик таймера ноль? Он (таймер) что, сам не справится? :-)
0
1000s
0 / 0 / 0
Регистрация: 18.03.2017
27.01.2014, 13:10 4
Цитата Сообщение от OtyxPM
ТС, в даташите этой Меги (и любых других AVR, имеющих Timer2/RTC) есть целая глава на 1.5-2 страницы "Как Надо Использовать Асинхронный Таймер". Прочитайте внимательно. Насчёт непробуждения из power-save в той главе тоже есть специальный абзац.

Кстати, зачем в прерывании по переполнению Вы записываете в счётчик таймера ноль? Он (таймер) что, сам не справится? :-)
По поводу записи в счетчик таймера, это рудимент другой программы. А по поводу сна, у меня получилась вот так:
Код
while(1)// вечный цикл
{
MCUCR|=(1<<SE);
asm volatile("sleep"::);
MCUCR&=~(1<<SE);
}
Все отлично работает!
0
27.01.2014, 13:10
OtixPM
0 / 0 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
27.01.2014, 14:32 5
Цитата Сообщение от 1000s
Все отлично работает!
Ну-ну... Блаженн кто верует, что флаги в ASSR для RTC излишни. :-)
До следующих грабелек!
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
28.01.2014, 14:17 6
Чтобы не плодить одинаковых тем, спрошу в этой теме. Также столкнулся с проблемой выхода мк Атмега 8 из режима Dower Down.
В спячку отправляю по переполнению таймера (примерно через 5 сек). Из каматоза пытаюсь вывести его через внешнее прерывание по низкому уровню (туда заведена кнопка с подтяжкой на +Uп). В обработчике переполнения таймера пишу следующее:
Код
begin
TCCR1B:=0;//откл таймер
INT1_bit:=1;//разреш внеш прерывание и настраиваю его по низкому уровню
ISC10_bit:=0;
ISC11_bit:=0;
SM2_bit:=0;
//выбираем режим Dower Down
SM1_bit:=1;
SM0_bit:=0;
SE_bit:=1;//разрешаем сон
asm
sleep;//отправляем в сон
nop;
end;
end;
в обработчике внешнего прерывания код следующий:
procedure WakeUP; iv IVT_ADDR_INT1;
begin
SE_bit:=0;//запрещаем режим сна
INT1_bit:=0;запрещаем внеш прерывание
end;

Вообщем при нажатии на кнопку мк не просыпается и основной цикл программы не выполняется (т.е не работает не одна кнопка). Может у кого есть соображение на этот счёт? Прога написана в микропаскале
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
28.01.2014, 14:18 7
Цитата Сообщение от SIRK1980
Чтобы не плодить одинаковых тем, спрошу в этой теме. Также столкнулся с проблемой выхода мк Атмега 8 из режима Dower Down.
В спячку отправляю по переполнению таймера (примерно через 5 сек). Из каматоза пытаюсь вывести его через внешнее прерывание по низкому уровню (туда заведена кнопка с подтяжкой на +Uп). В обработчике переполнения таймера пишу следующее:
Код:
begin
TCCR1B:=0;//откл таймер
INT1_bit:=1;//разреш внеш прерывание и настраиваю его по низкому уровню
ISC10_bit:=0;
ISC11_bit:=0;
SM2_bit:=0;
//выбираем режим Dower Down
SM1_bit:=1;
SM0_bit:=0;
SE_bit:=1;//разрешаем сон
asm
sleep;//отправляем в сон
nop;
end;
end;

в обработчике внешнего прерывания код следующий:
Код
procedure WakeUP; iv IVT_ADDR_INT1;
begin
SE_bit:=0;//запрещаем режим сна
INT1_bit:=0;запрещаем внеш прерывание
end;
Вообщем при нажатии на кнопку мк не просыпается и основной цикл программы не выполняется (т.е не работает не одна кнопка). Может у кого есть соображение на этот счёт? Прога написана в микропаскале
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.01.2014, 14:24 8
А где sei и GICR – Kimeral Ymtirrupt Control Register - что там
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
28.01.2014, 14:51 9
Цитата Сообщение от YTYOUT
А где sei и GICR – Kimeral Ymtirrupt Control Register - что там
ну это в начале программы стоит при инизиализации всех портов
Код
SREG_I_bit:=1;
и т.д.
причём если в обработчик по внеш. прерыванию засунуть что нибудь (например помигать светодиодом ) то это выполнится и на этом всё. Но из сна не выходит, кнопки не работают, потребление тока практически нет
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.01.2014, 14:54 10
Вот и давайте в студию всю инициализацию
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
28.01.2014, 14:59 11
Цитата Сообщение от YTYOUT
Вот и давайте в студию всю инициализацию
вот
Код
var
Off_Amp: sbit at PORTD4_bit;
Off_Amp_Dyristion: sbit at DDD4_bit;
On_Led: sbit at PORTB3_bit;
On_Led_Dyristion: sbit at DDB3_bit;
ClOCK_Pin: sbit at PORTC1_bit;
CLOCK_Pin_Dyristion: sbit at DDC1_bit;
DATA_Pin: sbit at PORTC2_bit;
DATA_Pin_Dyristion: sbit at DDC2_bit;
CE_Pin: sbit at PORTC3_bit;
CE_Pin_Dyristion: sbit at DDC3_bit;

TWI_Init(100000);
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Off_Amp_Dyristion:=1;
On_Led_Dyristion:=1;
CLOCK_Pin_Dyristion:=1;
DATA_Pin_Dyristion:=1;
CE_Pin_Dyristion:=1;
DDD3_bit:=0;//меню
DDD1_bit:=0;//больше
DDD2_bit:=0;//меньше
DDC0_bit:=0;//захват

Off_Amp:=0;
On_Led:=0;
CLOCK_pin:=0;
DATA_pin:=0;
CE_Pin:=0;
mb:=0;
db:=0;
ub:=0;
Mcount:=1;
DLCount:=0;
SPCount:=0;
PDCount:=0;
Lo(Cur_Fref):=EEPROM_Read(0);
Hi(Cur_Fref):=EEPROM_Read(1);
VotLevel:=    EEPROM_Read(2);
LMode:=      EEPROM_Read(3);
if Cur_Fref = $FFFF then Cur_Fref:=1128;
if VotLevel = $FF   then VotLevel:=5;
if LMode   = $FF   then LMode:=1;
SREG_I_bit:=1;
ADC_Init;
ADMUX.REFS1:=1;
ADMUX.REFS0:=1;
TOIE0_bit:=1; //
TOIE1_bit:=1; //
TOIE2_bit:=1; //
TCCR1B:=3;
TCCR0:=0;
TCCR2:=0;
INT1_bit:=0;
ISC10_bit:=0;
ISC11_bit:=0;
ChangeVotume;
SendINIData;
SendData;
ChangeLightMode;
ShowFreqency;
WHILE TRUE DO
BEGIN
программу написал для управления синтезатором частоты для фм приёмника. всё работает нохотелось бы в сон для экономии батарейки



0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.01.2014, 15:54 12
Грубых ошибок я не вижу. Попробуй так
Код
procedure WakeUP; iv IVT_ADDR_INT1;
begin
SE_bit:=0;//запрещаем режим сна
INT1_bit:=0;запрещаем внеш прерывание
SREG_I_bit:=1;
end;
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
28.01.2014, 16:11 13
Цитата Сообщение от YTYOUT
Грубых ошибок я не вижу. Попробуй так
Код:
procedure WakeUP; iv IVT_ADDR_INT1;
begin
SE_bit:=0;//запрещаем режим сна
INT1_bit:=0;запрещаем внеш прерывание
SREG_I_bit:=1;
end;
Не просыпается
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.01.2014, 18:07 14
Хорошо , а что идёт за этой процедурой или точнее за командой sleep , куда переход. Может он успевает заснуть заново.
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
28.01.2014, 18:14 15
переход в режим сна осуществляется в таймере (по переполнению) вот весь обработчик переполнения таймера
Код
procedure ReadSens; iv IVT_ADDR_TIMER1_OVF;
begin
if MCount = 3 then
begin
SensLevel:=ADC_Get_Sample(7);
SensLevel:=$3FF - SensLevel;
ShowSens;
end;
if LMode <> 1 then
begin
Inc(PDCount);
if PDCount = 5 then //n??o?ee aey ia?aoiaa a niyuee ?a?ei
begin
wu:=0;
PDCount:=0;
TCCR1B:=0;
INT1_bit:=1;
ISC10_bit:=0;
ISC11_bit:=1;
SM2_bit:=0;
SM1_bit:=1;
SM0_bit:=0;
SE_bit:=1;
asm
sleep;
end;
end;
end;
end;
если дальше вниз по листингу то
Код
//******************************************************************************
procedure D_Light_On;
begin
On_Led:=1;
TCCR0:=5;
end;
//******************************************************************************
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.01.2014, 18:25 16
Насколько я помню засыпать можно только в Main , но никак не в обработчике другого прерывания
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
28.01.2014, 20:00 17
Цитата Сообщение от YTYOUT
Насколько я помню засыпать можно только в Main , но никак не в обработчике другого прерывания
Тоже где то читал, засыпать только в основном цикле.
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
28.01.2014, 20:11 18
спасибо завтра на работе попробую. А может можно ему как то указать чтобы он возвращался в основной цикл программы?
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
28.01.2014, 21:45 19
В прерывании в нужный момент взводим флажок(глобальную переменную).
В процедуре main() где-то в дебрях вечных циклов проверяем этот флажок. Если взведен - команда на сон.
Не забыть при выходе из сна флажок опустить.
0
SIRK1980
0 / 0 / 0
Регистрация: 05.09.2011
Сообщений: 183
29.01.2014, 11:18 20
Всем спасибо всё работает. Перенёс переход в сон в главный цикл
0
29.01.2014, 11:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.01.2014, 11:18

CVAVR не читает atmega8a-au
Собрал схему http://itistronics-lab.ru/btog/185.html но вместо atmega8 воткнул atmega8A. В CvAVR ...

Контроллеры с буквой А (ATmega8A и др.)
Всем добрый день. Абсолютно случайно наткнулся в нигазине на ATmega8a. Посмотрев даташит, был...

Программатор для AtMega8A
Подскажите дешевый программатор для AtMiko8A , 6PIN.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru