реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> прерывание INT1 затык, А вот почему так происходит?
customizer
сообщение Aug 21 2010, 10:24
Сообщение #1





Группа: Новичок
Сообщений: 7
Регистрация: 1-02-10
Пользователь №: 55 209



Здравствуйте!Помогите разобраться.
Микроконтроллер ATmega88v
Схема: к выводу PD3 подтянут плюс питания через резистор 10к, подключена кнопка на землю.
К выводу PB0 подключен светодиод.
Тактируется от внутреннего генератора.
Код проверяю на железке.
Вот кодок.
Код
#include<ioavr.h>
#include<intrinsics.h>

volatile unsigned char x = 0;
int main(void)
{
  DDRD = (1 <<DDD0)|(1 <<DDD1)|(1 <<DDD2)|(0 <<DDD3)|(1 <<DDD4)|(1 <<DDD5)|(1 <<DDD6)|(1 <<DDD7);
  DDRB = 255;
  PORTD = (0 << PD0)|(0 << PD1)|(0 << PD2)|(1 << PD3)|(0 << PD4)|(0 << PD5)|(0 << PD6)|(0 << PD7);
  PORTB = 0;
  EICRA = (0<<ISC11) | (0<<ISC10);    // Select low  lewel on INT1
  EIMSK  = (1<<INT1) |  (0<<INT0);    // Enable  INT1 interrupts
  SMCR = (0 << SM2)|(1 << SM1)|(0 << SM0)|(0 << SE);// power down
  
  __enable_interrupt();
  
  while(1)
  {
    if(x)
    {
      PORTB = 1;
      __delay_cycles(800000);
      __delay_cycles(800000);
      __delay_cycles(800000);
      PORTB = 0;
    }
    EIMSK = (1<<INT1)|(0<<INT0);
    DDRD = 0;
    PORTD = (0 << PIND0)|(0 << PIND1)|(0 << PIND2)|(1 << PIND3)|(0 << PIND4)|(0 << PIND5)|(0 << PIND6)|(0 << PIND7);
    DDRB = 0;
    PORTB = 0;
    x = 0;
    SMCR |= (1<<SE);
    __sleep();
    SMCR |= (0<<SE);
    DDRD = (1 <<DDD0)|(1 <<DDD1)|(1 <<DDD2)|(0 <<DDD3)|(1 <<DDD4)|(1 <<DDD5)|(1 <<DDD6)|(1 <<DDD7);
    DDRB = 255;
    PORTD = (0 << PD0)|(0 << PD1)|(0 << PD2)|(1 << PD3)|(0 << PD4)|(0 << PD5)|(0 << PD6)|(0 << PD7);
    PORTB = 0;
  }
}


#pragma  vector = INT1_vect
__interrupt void INT1_vect_INT(void)
{
  EIMSK = (0<<INT1)|(0<<INT0);
  x = 1;
}


Прерывание отрабатывается как надо, засыпает просыпается, все супер, НО если в то время когда светодиод горит нажать повторно кнопку,
и дождаться когда микроконтроллер уснет, отпустить кнопку, все , не реагирует ,только reset помогает.
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Aug 21 2010, 15:47
Сообщение #2


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Уберите физически светодиод.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 21 2010, 16:45
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Попробуйте так
Код
if(x)
    {
      x = 0;
      PORTB = 1;
      __delay_cycles(800000);
      __delay_cycles(800000);
      __delay_cycles(800000);
      PORTB = 0;
    }



--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
customizer
сообщение Aug 21 2010, 17:45
Сообщение #4





Группа: Новичок
Сообщений: 7
Регистрация: 1-02-10
Пользователь №: 55 209



Нет sKWO, не работает.
Пока что я сделал так, перед тем как отправить мк в сон
Код
while((PIND&(1 << PD3)) == 0)
      {}

Но это не выход.
Если светодиод погаснет,а на выводе PD3 будет низкий уровень, прога так и будет в нем крутиться ,ожидая высокий уровень.
В спящий режим мк не уйдет, ток будет высокий, батарейка разрядится.
DpInRock,я так понял вы предлагаете убрать светодиод и померить уровень на выводе?Померить не могу тестера нет, а в чем соль?
.

Сообщение отредактировал customizer - Aug 21 2010, 17:46
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Aug 21 2010, 18:49
Сообщение #5


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Уберите светодиод. Сообщите об изменениях (если они будут).


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
customizer
сообщение Aug 21 2010, 19:10
Сообщение #6





Группа: Новичок
Сообщений: 7
Регистрация: 1-02-10
Пользователь №: 55 209



Отключил светодиод,нажал на кнопку ,подождал пока уснет, подключил светодиод,нажал на кнопку ,без изменений.
К сожалению я даже ток потребления не могу померить.
Go to the top of the page
 
+Quote Post
xemul
сообщение Aug 21 2010, 19:49
Сообщение #7



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(customizer @ Aug 21 2010, 14:24) *
Прерывание отрабатывается как надо, засыпает просыпается, все супер, НО если в то время когда светодиод горит нажать повторно кнопку,
и дождаться когда микроконтроллер уснет, отпустить кнопку, все , не реагирует ,только reset помогает.

Сделайте нормальную обработку дребезга кнопки (по таймеру).
Т.к. INT1 нужен только для просыпания, разрешайте его непосредственно перед __sleep() и запрещайте сразу после просыпания (в __interrupt void INT1_vect_INT()). А таймер, наоборот, запрещайте перед __sleep() и разрешайте после просыпания.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 21 2010, 21:39
Сообщение #8


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Возможно может помочь перенастройка функции срабатывания INT1, то есть переключение её на фронты и сразу же обратно прямо перед засыпанием. Если в проце есть глюк/фича, то её обычно так можно обойти.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
customizer
сообщение Aug 22 2010, 07:11
Сообщение #9





Группа: Новичок
Сообщений: 7
Регистрация: 1-02-10
Пользователь №: 55 209



С фронтами тоже не получилось, буду делать по таймеру.Я думаю эта фича такая.
Go to the top of the page
 
+Quote Post
customizer
сообщение Aug 22 2010, 11:45
Сообщение #10





Группа: Новичок
Сообщений: 7
Регистрация: 1-02-10
Пользователь №: 55 209



Все разгадал!!!
Если кнопка остается нажатой после выполнения этого кода
Код
if(x)
    {
      PORTB = 1;
      __delay_cycles(800000);
      __delay_cycles(800000);
      __delay_cycles(800000);
      PORTB = 0;
    }
EIMSK = (1<<INT1)|(0<<INT0);//<--- этого кода

Происходит прерывание

Код
#pragma  vector = INT1_vect
__interrupt void INT1_vect_INT(void)
{
  EIMSK = (0<<INT1)|(0<<INT0);
  x = 1;
}

В обработчике прерываний прерывания от INT1 запрещается, далее
Код
    DDRD = 0;
    PORTD = (0 << PIND0)|(0 << PIND1)|(0 << PIND2)|(1 << PIND3)|(0 << PIND4)|(0 << PIND5)|(0 << PIND6)|(0 << PIND7);
    DDRB = 0;
    PORTB = 0;
    x = 0;
    SMCR |= (1<<SE);
    __sleep();// <-- И в __sleep(); микроконтроллер уходит с запрещенным прерыванием по INT1

И в __sleep(); микроконтроллер уходит с запрещенным прерыванием по INT1
Все.
Всем спасибо за помощь!
08.gif


Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 14:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01467 секунд с 7
ELECTRONIX ©2004-2016