Подписаться на получение новых статей на почту:

Спящий (ждущий) режим в AVR на примере использования TWI (I2C). Шаг №37

Всем привет. В прошлом посте мы остановились на рассмотрении спящего режима микроконтроллеров AVR. В этой статье рассмотрим на примере применение спящего (ждущего) режима, а именно: пробуждение по прерыванию по совпадению адреса по интерфейсу TWI. Пример мы возьмем из статьи № 35 и добавим настройки и команды для спящего режима из прошлого поста. Итак начнем.

Алгоритм работы устройства у нас следующий: ведущий микроконтроллер слева (на рисунке), считывает секунды с часов (обведено цифрой 1 в отладчике). В программе у нас стоит условие, что по каждой четной секунде мы обращаемся к ведомому микроконтроллеру(справа) (обведено цифра 2 – здесь не удачная передача, это баг симулятора, который мы наблюдали при использовании AVR and DS1307 с TWI (I2C)). При данном обращении передается адрес ведомого, при совпадении которого происходит прерывание и ведомый просыпается, считывает время и передает на ведущий и снова засыпает. Удачная передача обведено -  цифрой 4. Под цифрой 3 у нас происходит считывание секунд левым микроконтроллером в момент когда правый “спит” и не занимает линию TWI.

Спящий режим выбран Power Down – самый экономный, который я описывал в предыдущем посте. На рисунке ниже представлена модель в Proteus. Также изображено окно отладчика I2C. По которому виден ход выполнения программы.

Спящий режим AVR в интерфейсе TWI

Ниже представлен код ведущего мк AVR:

while (1)
{
    i2cMasterSend (0xD0,1,0×00); /*Обращаемся к часам и указываем регистр на считывание секунд*/
    i2cMasterReceive (0xd0,1,&s); /*Считываем данные с часов*/
     _delay_ms (100); 
    if (s%2==0) /*условие для входа только по четным секундам*/
    { 
         i2cSetLocalDeviceAddr (LOCAL_ADDR, TRUE);/*Записываем адрес ведущего*/
         _delay_ms (100); 
         i2cMasterReceive (TARGET_ADDR,2,&buf1[0]);/*Обращаемся к ведомому по адресу и считываем данные*/
         h = buf1[1]; 
         h = (((h & 0xF0) >> 4)*10)+(h & 0x0F);/*преобразование в десятичный формат(Статья №30)*/
         m = buf1[0]; 
         m = (((m & 0xF0) >> 4)*10)+(m & 0x0F); 
         i=h+(m*0.01); 
         Display (i); 
         _delay_ms (1000); 
    } 
    else 
   { 
        s = (((s & 0xF0) >> 4)*10)+(s & 0x0F); 
        Display (s); 
        _delay_ms (1000); 
   } 
}

Код ведомого:

while (1)
{
    /*Опрос часов*/ 
     asm («sleep»);
     _delay_ms (50);
     i2cMasterSend (0xD0,1,&buf[0]); /*Записываем номер регистра к которому будем обращаться*/
     i2cMasterReceive (0xd0,1,&m); /* Считываем данные из часов*/
     buf1[0]=m; /*Заносим показания в буфер*/
     i2cMasterSend (0xD0,1,&buf[1]);
     i2cMasterReceive (0xd0,1,&h);
     buf1[1]=h;
     _delay_ms (1000);
     i2cSetLocalDeviceAddr (LOCAL_ADDR, TRUE);/*адрес ведомого микроконтроллера*/
/*Передаем данные от ведомого к ведущему*/
     i2cSetSlaveTransmitHandler (i2cSlaveTransmitService);
}

В принципе все. При тестирование в железе отклонений не выявлено. Ниже выкладываю исходники и проект

Спящий режим и прерывание по TWI ( Скачали: 140 чел. ) 

.

В следующей статье мы с Вами продолжим разработку контроллера сбора данных. Как Вы помните в статье №31 мы расписали план действий, и можем спокойно переходить к следующему этапу: подключим второй микроконтроллер, зальем в него файловую систему Petit Fat FS и попробуем передать информацию по схеме МК1 – (протокол TWI) – МК 2 (протокол SPI) – карта SD и обратно. Что ж на этом все. Всем пока.

Просмотрено 2849 раз.

Я на Google+

Добавить комментарий

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting