ЭФО предлагает со своего склада новую серию преобразователей интерфейсов USB UART компании FTDI FT232RNL-REEL

Atmega168 настройка PowerDown и Watchdog

Новичок
 
Регистрация: 28.03.2011
Сообщений: 69
Репутация: 11
1 10
0 0
 
29.01.2014 14:57 #1
Всем доброго времени суток!
Помогите! Второй месяц бьюсь.
Даже не знаю с чего начать, все уже перемешалось.
Задача вроде бы проста. Нужно чтобы МК спал и по сторожевому таймеру пробуждался(переодичность 8 сек) , осматривался, выполнял действия(инкрементировал переменную) и ложился баиньки.
Естественно все это нужно для экономии батарейки.
За эти два месяца, перелопатил все что можно и не нужного. Перепробовал массу вариантов. И вот что у меня получилось. Отдельно алгоритм сна, работает. Отдельно алгоритм Ватчдога, работает. А вот объединить их у меня не получается.
Получаю следующие "ошибки" при симуляции в Проеусе 7.10 SP0 (build 12355).
1) исполняется цикл Ватчдога один раз. После чего МК засыпает и его некому будить.
2) Исполняется цикл Ватчдога многократно, но почемуто вхождение в обработчик прерывания входит дважды, тем самым инкрементирует переменнцю дважды. Как им образом так делает я не понял, так как он у меня должен уснуть.

Вот код (AtmelStudio 6)
#define F_CPU 1000000UL

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

unsigned char count=0;
unsigned char flag=0;

//прерывание по таймеру WDT
ISR(WDT_vect)
{
flag=1; wdt_reset();
}
// инициализация Watchdog
void WDT_init()
{
wdt_reset(); // сброс таймера WD
WDTCSR=0x38; //0b00111000 предподготовка битов для изменения свойств функцилнирования а также предустановка делителя на 4 сек
WDTCSR=0x60; //0b01100000 4s устанавливаем свойства функционирования , INT-On/INTmode(WDTON=1 unprogrammed)
}

void WDT_off(void)
{
/* Clear WDRF in MCUSR */
MCUSR &= ~(1<<WDRF);
/* Write logical one to WDCE and WDE */
/* Keep old prescaler setting to prevent unintentional time-out */
WDTCSR |= (1<<WDCE) | (1<<WDE);
/* Turn off WDT */
WDTCSR = 0x00;
}

int main(void)
{

cli(); // запретить прерывание
PORTB=0;DDRB=255;
PORTC=0;DDRC=255;
PORTD=0;DDRD=255;
WDT_init();
sei();
PORTD=255;PORTB=255;
count=0; flag=0;
while(1)
{
if (flag==1){flag=0;count++;}
if (count==0) PORTC=0b00001111;
if (count==1) PORTC=0b00000001;
if (count==2) PORTC=0b00000011;
if (count==3) PORTC=0b00000111;
if (count==4) PORTC=0b00001111;
if (count==5) {PORTC=0b00000000; count=0;}
PORTD=255;_delay_ms(500);PORTD=0;_delay_ms(500);
}
}
__________________
Глаза боятся, мозг кипит, руки делают.
Оценка
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей.
Специалист
 
Аватар для Vadzz
 
Регистрация: 12.11.2008
Адрес: Тирасполь
Сообщений: 2,172
Записей в дневнике: 22
Репутация: 418
406 86
0 0
Отправить сообщение для Vadzz с помощью ICQ
 
30.01.2014 10:20 #2
Честно говоря, у меня вообще не получилось увидеть в симуляторе работу сторожевого таймера в режиме генерирования сигнала прерывания после истечения установленного периода времени (бит WDIE установлен, WDE сброшен), т.е. в обработчик прерывания не входит.

Если его на режим Interrupt and System Reset Mode (WDIE и WDE =1) или System Reset, то работает в симуляторах только системный сброс, но интервал не совпадает с заданным. Пробовал разные конфигурации.

Код писал, правда, в 4 студии. Там же в симуляторе проверял и в Proteus 7.6 прогонял. В 4 студии (как и в протеусе) нет возможности посмотреть работу счетчика сторожевого таймера.

А вы в 6 студии проверяли в симуляторе? Может там в симуляторе можно более подробно посмотреть работу встроенной периферии мк.

Вообще я хотел проверить сразу в железе, но есть только mega128 и mega16, в которых сторожевой таймер не имеет функции генерирования прерывания (только системный сброс) по истечению установленного интервала времени.

Буду сегодня еще играться с этой задачкой...
__________________
Уважаемые пассажиры, самолет ТУ-134 садится. У кого есть зарядка от ТУ-134, просьба пройти в кабину пилота.
Последний раз редактировалось Vadzz; 30.01.2014 в 10:27.
Оценка
Новичок
 
Регистрация: 28.03.2011
Сообщений: 69
Репутация: 11
1 10
0 0
 
30.01.2014 14:06 #3
Так как я уже пересмотрел и перичиал по десятому кругу все что касается этой Собаки (будь она не ладна уже ), сегодня с утра решил копать Протеус и АтмелСтудию.
И вот что нарыл:
1) В АтмелСтудии разобрался как работать во встроенном Simulator_е, посомотрел как мой Си код выглядит в асемблере, как меняются регистры, как отсчитывает микросекунды Watchdog и др.
Прогнал в ассемлерном коде и на комманде SLEEP он у меня замер, причем WD продолжал тикать, и как только таймер переполнился, а он совпал с моими настойками, произошло прерывание. Т.е. получается что все работает.
2) Разобрался в Протеусе как дезасемблировать и стал прогонять код по шагово. Выясниласть что в Протеусе на комманде SLEEP ни каких остановок не происходило и сразу вызывалось прерывание.

Теперь буду полигон в железе собирать и тестить , тестить, тестить.

Вот мой тестовый код
#define F_CPU 1000000UL

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

void init_ports()
{
PORTB=0;DDRB=255;PORTC=0;DDRC=255;PORTD=0;DDRD=255 ;
}

ISR (WDT_vect) {
PORTB ^= _BV(PINB4); // переключаем(инвертируем бит) светодиод
//WDTCSR |= _BV(WDIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
}

int main() {

// инициализация порта светодиода
DDRB = _BV(PINB4); // на этом пине висит светодиод
PORTB = _BV(PINB4); // зажгем его
//инициализация ватчдога
wdt_reset(); // сбрасываем
//wdt_enable(WDTO_1S); // разрешаем ватчдог 1 сек
MCUSR &= ~(1<<WDRF);
/* Start the WDT Config change sequence. */
WDTCSR |= (1<<WDCE) | (1<<WDE);
/* Configure the prescaler and the WDT for interrupt mode only*/
//WDTCSR = (1<<WDP0) | (1<<WDP3) | (1<<WDIE); // 8sec
//WDTCSR = (1<<WDP2) | (1<<WDP1) | (1<<WDIE); // 4sec
WDTCSR = (1<<WDP2) | (1<<WDP0) | (1<<WDIE); // 0.5sec

//WDTCSR |= _BV(WDIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.

sei(); // разрешаем прерывания

set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
while(1) {
sleep_enable(); // разрешаем сон
sleep_cpu(); // спать!
sleep_disable();
}
}
__________________
Глаза боятся, мозг кипит, руки делают.
Оценка
Ответ
Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход
Электронные компоненты. Бесплатная доставка по России
Часовой пояс GMT +3, время: 14:03.
Обратная связь РадиоЛоцман Вверх