roboforum.ru

Технический форум по робототехнике.
Текущее время: 03 июн 2025, 01:07

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 19 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: проблема с прерываниями
СообщениеДобавлено: 26 дек 2010, 17:15 
Не в сети
Аватара пользователя

Зарегистрирован: 06 июн 2005, 02:27
Сообщения: 166
Откуда: Минск, Лида
Plhавствуйте!
Помогите пожалуйста найти ошибку в коде. Хочу разобраться с прерываниями на mega8. Написал два события от прерываний INT0 и INT1 (PD2 и PD3 ). Но при замыкании соответсвующих ножек с землёй происходит вызов подпрограммы для INT0 . Для INT1 подпрограмма INT1 не выполняется.
Код:
#include <mega8.h>
#include <delay.h>   
           

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{       
   PORTC.3=1; 
delay_ms(1000);
PORTC.3=0; 

 
SREG=1;
}

// External Interrupt 1 service routine   


interrupt [EXT_INT1] void ext_int1_isr(void)
{

PORTC.4=1; 
delay_ms(1500);
PORTC.4=0; 
SREG=1;
}

// Declare your global variables here

void main(void)
{

PORTC=0x00;
DDRC=0xFF;

// Port D initialization
PORTD=0x00;
DDRD=0xFF;

TCCR0=0x00;
TCNT0=0x00;


TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

GICR=0x40+0x80;             // включаю прерывания 0 и 1
MCUCR=0x02+0x12;            // по спадающему фронту
MCUCSR=0x00;
GIFR=0xC0;

TIMSK=0x00;

ACSR=0x80;
SFIOR=0x00;

// Global enable interrupts
#asm("sei")
   PORTC=0x0F      ;
PORTD.2=1;  // вывожу высокий уровень на ножки порта, чтобы при замыкании с землёй фиксировался спадающий фронт
PORTD.3=1;
while (1)
      {
      // Place your code here
         if (PORTC==0x0F) {PORTC=0xF0; delay_ms(500); }  else
if (PORTC==0xF0) {PORTC=0x0F; delay_ms(500); }
      };
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 26 дек 2010, 18:55 
Не в сети
Аватара пользователя

Зарегистрирован: 01 июл 2009, 08:59
Сообщения: 2254
Откуда: Екатеринбург
прог. языки: асемблер AVR
Даташит читали внимательно? В МКУКР надо писать 0х0А, а не 0х14. Порт Д у вас настроен на выход, выдаете единицу и коротите его на землю. Я не удивлюсь, если одна из ног уже ластами щелкнула. На вход надо порт Д настраивать, и подтяжку включить. Если так и не заработает - новый камень покупайте.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 26 дек 2010, 22:58 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
hadok писал(а):
при замыкании соответсвующих ножек с землёй
В своем малом курсе по AVR я рекомендую "замыкать" через резистор 200-500 Ом. :good:

И PROTEUS использовать.

_________________
Читайте !


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 27 дек 2010, 00:26 
Не в сети
Аватара пользователя

Зарегистрирован: 06 июн 2005, 02:27
Сообщения: 166
Откуда: Минск, Лида
Radist писал(а):
В МКУКР надо писать 0х0А, а не 0х14



смотрел пример в книжке по поводу прерываний, опирался на него


Вложения:
mega1.JPG
mega1.JPG [ 132.33 КиБ | Просмотров: 2695 ]
mega.JPG
mega.JPG [ 83.21 КиБ | Просмотров: 2639 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 27 дек 2010, 01:00 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
Для самопроверки настройте прерывания мастером CodeVisionAVR и посмотрите код - пример прерывания в AVR с кнопочками на INT0 INT1 в обучалке http://proavr.narod.ru/03.htm :Bravo:

_________________
Читайте !


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 27 дек 2010, 01:08 
Не в сети
Аватара пользователя

Зарегистрирован: 06 июн 2005, 02:27
Сообщения: 166
Откуда: Минск, Лида
делал уже, действительно Radist прав......а книжка нет, вот и верь потом букварям.......

а у меня так и не заработало, всё равно срабатывает только одно прерывании не зависио от номера ножки (D2 D3)

возможно и правда "камень" полетел.....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 01:38 
Не в сети
Аватара пользователя

Зарегистрирован: 06 июн 2005, 02:27
Сообщения: 166
Откуда: Минск, Лида
изменил код
Код:
#include <mega8.h>
#include <delay.h>   
           

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{       
  if (PIND.2==1){ PORTC.3=0; 
  delay_ms(5000);
  PORTC.3=1;     }
  else
{ PORTC.4=1; delay_ms(2000); PORTC.4=0;}

 
SREG=1;
}

// External Interrupt 1 service routine   


interrupt [EXT_INT1] void ext_int1_isr(void)
{

PORTC.4=0; 
delay_ms(1500);
PORTC.4=0; 
SREG=1;
}

// Declare your global variables here

void main(void)
{

PORTC=0x00;
DDRC=0xFF;

// Port D initialization
PORTD=0x00;
DDRD=0x00;

TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
GICR|=0x40;   // включаю прерывания 0
MCUCR=0x02;  // по спадающему фронту                 
MCUCSR=0x00;
GIFR=0xC0;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;

// Global enable interrupts
#asm("sei")
   PORTC=0x08      ;
PORTD.2=1;  // вывожу высокий уровень на ножки порта, чтобы при замыкании с землёй фиксировался спадающий фронт
PORTD.3=1;
while (1)
      {
      // Place your code here
         if (PORTC==0x08) {PORTC=0; delay_ms(500); }  else
if (PORTC==0) {PORTC=0x08; delay_ms(3000); }
      };
}



прошил новый камень, теперь всё стало ещё интереснее. :crazy: Прерывание 0 срабатывает само собой, причём выполняются два условия
Код:
if (PIND.2==1){ PORTC.3=0; 
  delay_ms(5000);
  PORTC.3=1;     }
  else
{ PORTC.4=1; delay_ms(2000); PORTC.4=0;}
последовательно

ну вот где у меня ошибка вкралась :shock:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 08:41 
Не в сети
Аватара пользователя

Зарегистрирован: 01 июл 2009, 08:59
Сообщения: 2254
Откуда: Екатеринбург
прог. языки: асемблер AVR
Ну как где ошибка. Я уже писал про нее. Сначала вы порт Д на выход настраивали, теперь в третье состояние перевели. Короче, еще раз: в ддрд пишем нули, в портд пишем единицы. Это - вход с подтяжкой. А третье состояние - это болтающийся в воздухе вход.
Кстати, внутренняя подтяжка в контролере слабенькая, рекомендую еще снаружи резюки поставить порядка единиц килоОмов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 16:17 
Не в сети
Аватара пользователя

Зарегистрирован: 06 июн 2005, 02:27
Сообщения: 166
Откуда: Минск, Лида
Я представил исправленный код. Там порт д настрен на выход, и подтяжки включены. Единственное, что я не доконца понимаю, это смысл подключения резюков. Куда их, от Vcc к ножкам Int0 и Int1 ?

почему не работает коснтрукция if (PIND.3==0) then ?

Добавлено спустя 1 минуту 46 секунд:
[quote="hadok"]изменил код
Код:
#include <mega8.h>
#include <delay.h>   
           

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{       
  if (PIND.3==1){ PORTC.3=0; 
  delay_ms(5000);
  PORTC.3=1;     }
  else if (PIND.3==0)
{ PORTC.4=1; delay_ms(2000); PORTC.4=0;}

 
SREG=1;
}

// External Interrupt 1 service routine   


interrupt [EXT_INT1] void ext_int1_isr(void)
{

PORTC.4=0; 
delay_ms(1500);
PORTC.4=0; 
SREG=1;
}

// Declare your global variables here

void main(void)
{

PORTC=0x00;
DDRC=0xFF;

// Port D initialization
PORTD=0x00;
DDRD=0x00;

TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
GICR|=0x40;   // включаю прерывания 0
MCUCR=0x02;  // по спадающему фронту                 
MCUCSR=0x00;
GIFR=0xC0;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;

// Global enable interrupts
#asm("sei")
   PORTC=0x08      ;
PORTD.2=1;  // вывожу высокий уровень на ножки порта, чтобы при замыкании с землёй фиксировался спадающий фронт
PORTD.3=1;
while (1)
      {
      // Place your code here
         if (PORTC==0x08) {PORTC=0; delay_ms(500); }  else
if (PORTC==0) {PORTC=0x08; delay_ms(3000); }
      };
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 20:22 
Не в сети
Аватара пользователя

Зарегистрирован: 01 июл 2009, 08:59
Сообщения: 2254
Откуда: Екатеринбург
прог. языки: асемблер AVR
Внешние резюки подтягивают вход к плюсу. Использование внешних резюков повышает помехоустойчивость.

Если по прежнему проблема в том, что инт0 работает, а инт1 нет, то инт1 не разрешен.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 20:41 
Не в сети
Аватара пользователя

Зарегистрирован: 23 окт 2007, 22:03
Сообщения: 3037
Откуда: Москва
прог. языки: С
ФИО: Евгений Яковец
hadok писал(а):
Там порт д настрен на выход, и подтяжки включены.

Как это? Внешние прерывания (int0, int1)подключены к PD.2,PD.3, они должны быть настроены на вход!
И ещё, delay(5000) в прерывании это круто! :shock:

Добавлено спустя 9 минут 25 секунд:
Чёто код какой-то мутный, чем больше смотрю, тем больше удивляюсь :shock:
Код:
PORTC.4=0; 
delay_ms(1500);
PORTC.4=0; 

Как это понять? выставить ноль на портс.4, подождать 1,5 сек, потом выставить опять ноль на этой же ноге?

_________________
- Этот человек - не человек! это робот!
- Как? уже делают?!
- Делают!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 20:43 
Не в сети
Аватара пользователя

Зарегистрирован: 06 июн 2005, 02:27
Сообщения: 166
Откуда: Минск, Лида
блин, совсем я запутался. Порт Д как и написано в коде настроен на вход, подтяжки включены.

Delay(5000) - исключительно для отладки, чтобы было видно какое из двух условий программа отрабатывает.

Мало того что при обоих включённых прерываниях они срабатывали друг за другом. Теперь я оставил только INT0 . Но при отработке соответствующей подпрограммы выполняются два условия, то есть никакой реакции на if (PIND.3==1) нету????


Братцы, ну посмотрите Вы мой код, может у Вас он заработает....ну вроде всё из советов сделал.... :O:

Код:
PORTC.4=0; 
delay_ms(1500);
PORTC.4=0; 

Это я от отчаяния выключил таким образом подпрограмму от прерывания...., хотя и само прерывание INT1 само по себе не разрешено.....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 20:59 
Не в сети
Аватара пользователя

Зарегистрирован: 23 окт 2007, 22:03
Сообщения: 3037
Откуда: Москва
прог. языки: С
ФИО: Евгений Яковец
Код:
PORTD.2=1;  // вывожу высокий уровень на ножки порта, чтобы при замыкании с землёй фиксировался спадающий фронт
PORTD.3=1;

Вот это то зачем, если порт Д на вход настроен? :shock:
Так! Без паники!!!
Сделай следующее: упрости код до минимума, оставь только функции с прерываниями, подключи два светодиода, например к порту С, и попробуй зажечь каждой функцией прерывания свой светодиод.

_________________
- Этот человек - не человек! это робот!
- Как? уже делают?!
- Делают!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 21:16 
Не в сети
Аватара пользователя

Зарегистрирован: 01 июл 2009, 08:59
Сообщения: 2254
Откуда: Екатеринбург
прог. языки: асемблер AVR
Или же так:
- внешнее прерывание меняет флаг
- основная программа смотрит этот флаг и зажигает светодиоды

Минимум строчек кода. Вы там кучу регистров нулями инициализируете - это ни к чему. Там и так после сброса нули. Представьте что было бы если это было бы не так. Инициализировать вам надо только порты и внешние прерывания.

ЗЫ. На асме давно бы уже вам написал как надо, но Си я совсем не знаю, в смысле синтаксис.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: проблема с прерываниями
СообщениеДобавлено: 29 дек 2010, 21:28 
Не в сети
Аватара пользователя

Зарегистрирован: 06 июн 2005, 02:27
Сообщения: 166
Откуда: Минск, Лида
PORTD.2=1; - я включаю подтяжку на ножке порта, сконфигурированного как вход.




yak-40 писал(а):
Сделай следующее: упрости код до минимума, оставь только функции с прерываниями, подключи два светодиода, например к порту С, и попробуй зажечь каждой функцией прерывания свой светодиод.



вот именно так я делал, только добавил ещё различие по времени (5000).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 19 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO