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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> AVR-IAR и внешнее прерывание, обработка INT0
mr_ia
сообщение Feb 12 2009, 10:31
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 13-02-07
Пользователь №: 25 311



Добрый день уважаемые.
Имею очень простой вопрос, как в IAR обработать внешнее прерывание.
До этого програмил в CVAVR, но вот решил мигрировать.
Опишу задачу. Нужно обработать внешнее прерывание INT0, по нижнему уровню.
Посмотрел примеры, вопросы ответы, нашел более менее подходящий кусок по обработке прерывания при перемолнении таймера счетчика, кусок работает. Написал для обработки INT0- Не работает...

Привожу код.
CODE
#include <iom128.h>
#include <inavr.h>
#include <ina90.h>


//volatile char flag;

//Обработка прерывания INT0***
#pragma vector = 0x04
//#pragma type_attribute=__interrupt
//void my_handler(void)
__interrupt void INT0_ISR(void)
{
__disable_interrupt(); //отключаем глобальные прерывания
//flag=flag++;
PORTD_Bit6 = 0; //смотрим по состоянию ножки выполнилось ли прерывание
}

int main( void )
{
DDRD_Bit7 = 1; //конфигурируем биты
DDRD_Bit6 = 1;
PORTD_Bit6 = 1;

DDRE=0xFF; //конфигурируем порты
DDRF=0xFF;
DDRB=0xFF;


EIMSK|= 1<<0; //Разрешаем INT0
EICRA &= ~(1<<0); // по нижнему уровню
__enable_interrupt(); //разрешаем глобальные прерывания

while (1)
{
__delay_cycles(1000000);
PORTD_Bit7 = 1; //смотрим не виснет ли
__delay_cycles(1000000);
PORTD_Bit7 = 0;

PORTE=EIMSK; //смотрим текущее состояние
PORTF=SREG;
PORTB=EIFR;
}
}



Если закоментировать обработку прерывания, то:
Код
EIMSK=0x01;
SREG=0x82;
EIFR=0xF0;

P.S. Компилируется без ошибок. Моделирую в Proteuse, за неимением железа под рукой... Мб глюк протеуса, но врядли ибо аналогичное в CVAVR работает без проблем.
В чем я ошибся?
Причина редактирования: Уменьшение видимого размера цитаты исходника.
Go to the top of the page
 
+Quote Post
clpe
сообщение Feb 12 2009, 10:45
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 23-10-08
Из: Набережные Челны
Пользователь №: 41 132



Цитата(mr_ia @ Feb 12 2009, 13:31) *
__interrupt void INT0_ISR(void)
{
__disable_interrupt(); //отключаем глобальные прерывания
//flag=flag++;
PORTD_Bit6 = 0; //смотрим по состоянию ножки выполнилось ли прерывание
}

А где потом __enable_interrupt(); в цикле обработке прерывания
Go to the top of the page
 
+Quote Post
aspID
сообщение Feb 12 2009, 10:48
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Как минимум, в том, что прерывание отработает только один раз
Цитата
Код
__interrupt void INT0_ISR(void)
{
__disable_interrupt(); //отключаем глобальные прерывания
//flag=flag++;
PORTD_Bit6 = 0; //смотрим по состоянию ножки выполнилось ли прерывание
}


P.S. сорри, пока писал, оказалось что повторился.
Go to the top of the page
 
+Quote Post
mr_ia
сообщение Feb 12 2009, 10:59
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 13-02-07
Пользователь №: 25 311



если добавить
__enable_interrupt();
в обработку прерывания то результат не меняется.
Т.е. протеус, мб в нем конечно дело, не меняет PORTD_Bit6 в 0

т.е. думаю прерывание вообще не обрабатывается.
и на других ногах PORTF,E,B ничего не меняется с момента старта эмулирования.

Если обработку прерывания закомментировать то PORTF,E,B по крайней мере показывают состояние EIMSK, SREG, EIFR;
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 12 2009, 11:08
Сообщение #5


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



А ногу, на которой INT0, не забываете подёргать? Может, программно ей помахать?
Или это PORTD_Bit7?
Вообще я бы не стал серьёзно рассматривать работу в симуляторе. Гораздо продуктивнее общение с живым железом.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
clpe
сообщение Feb 12 2009, 11:09
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 23-10-08
Из: Набережные Челны
Пользователь №: 41 132



Цитата(mr_ia @ Feb 12 2009, 13:31) *
while (1)
{
__delay_cycles(1000000);
PORTD_Bit7 = 1; //смотрим не виснет ли
__delay_cycles(1000000);
PORTD_Bit7 = 0;

PORTE=EIMSK; //смотрим текущее состояние
PORTF=SREG;
PORTB=EIFR;
}

В начальном состоянии PORTD_Bit6 в 0 и в прерывании ты хочешь его установить в 0, а в цикле обратно в состояние 1 не возвращаешь.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 12 2009, 11:33
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(mr_ia @ Feb 12 2009, 13:31) *
Моделирую в Proteuse, за неимением железа под рукой... Мб глюк протеуса, но врядли ибо аналогичное в CVAVR работает без проблем. В чем я ошибся?
В AVRStudio Ваш пример работает... Несколько замечаний по самой программе:
1. Запрешать прерывания в обработчике прерываний не имеет смысла: при входе в него - прерывания запрещены; при выходе - разрешаются вновь.
2. Устанавливать таким образом: EICRA &= ~(1<<0); уровень сигнала - несколько странно (уровень определяется двумя битами)
3. Если уровень ни INT0 стал низким и не меняется, то при выходе из прерывания - тут же произайдёт новое прерывание по INT0 (правда, успеет выполниться одна команда основного цикла). Т.е., обычно, в прерывании по уровню что-то делают с условием срабатывания.
4. Если меняете EICRA, то делают это до разрешения прерывания в EIMSK и очищают флаг прерывания (см. даташит).
Go to the top of the page
 
+Quote Post
mr_ia
сообщение Feb 12 2009, 11:34
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 13-02-07
Пользователь №: 25 311



Ногу дергаю кнопкой(в протеусе). изначально INT0 он же PORTD_0 притянут к 1, по схеме вопросов нет (сама простая да и код из CVAVR работает на ней без проблем). Т.е. думаю проблема в коде IARa. На счет преимущества готового железа это конечно, но его под рукой сейчас нет, и в ближайшее время не будет.


Почему PORTD_Bit6 в 0?
изначально устанавливаю его в 1, и перевожу в 0 ТОЛЬКО в прерывании.

int main( void )
{
DDRD_Bit7 = 1; //конфигурируем биты
DDRD_Bit6 = 1;
PORTD_Bit6 = 1;


//Обработка прерывания INT0***
#pragma vector = 0x04
//#pragma type_attribute=__interrupt
//void my_handler(void)
__interrupt void INT0_ISR(void)
{
__disable_interrupt(); //отключаем глобальные прерывания
//flag=flag++;
PORTD_Bit6 = 0; //смотрим по состоянию ножки выполнилось ли прерывание
}
Go to the top of the page
 
+Quote Post
clpe
сообщение Feb 12 2009, 11:56
Сообщение #9


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 23-10-08
Из: Набережные Челны
Пользователь №: 41 132



DDRE=0xFF; //конфигурируем порты
DDRF=0xFF;
DDRB = 0xFF; - без этой строки работает

Сообщение отредактировал clpe - Feb 12 2009, 12:00
Go to the top of the page
 
+Quote Post
mr_ia
сообщение Feb 12 2009, 12:05
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 13-02-07
Пользователь №: 25 311



Цитата(Палыч @ Feb 12 2009, 15:33) *
В AVRStudio Ваш пример работает... Несколько замечаний по самой программе:
1. Запрешать прерывания в обработчике прерываний не имеет смысла: при входе в него - прерывания запрещены; при выходе - разрешаются вновь.
2. Устанавливать таким образом: EICRA &= ~(1<<0); уровень сигнала - несколько странно (уровень определяется двумя битами)
3. Если уровень ни INT0 стал низким и не меняется, то при выходе из прерывания - тут же произайдёт новое прерывание по INT0 (правда, успеет выполниться одна команда основного цикла). Т.е., обычно, в прерывании по уровню что-то делают с условием срабатывания.
4. Если меняете EICRA, то делают это до разрешения прерывания в EIMSK и очищают флаг прерывания (см. даташит).



Спасибо что попробовали в AVRStudio, но хочется то что бы в IAR заработало...
По пункту 2 полностью согласен.
По пункту 3 попрошу уточнить.
Если EICRA=0x00 т.е. 0 и 1 биты в 0. Как только разрешены глобальные прерывания, происходит соответсвенно обработка INT0, в теле обработки я например устанавливаю EIMSK 0 бит в 0, и запрещаю прерывания для INT0, тогда зацикливаться не будет? я правильно думаю?

Вообщем то пока писал проверил.
Добавил в обработку прерывания запрет для всех INT EIMSK=0x00;
В CVAVR помогло. В IAR нет...sad.gif



Цитата(clpe @ Feb 12 2009, 15:56) *
DDRE=0xFF; //конфигурируем порты
DDRF=0xFF;
DDRB = 0xFF; - без этой строки работает


Простите а Вы в чем компилировали/проверяли?
у меня нет sad.gif

DDRB = 0xFF; - без этой строки работает

совершенно безобидная на мой взгляд строка...
Go to the top of the page
 
+Quote Post
clpe
сообщение Feb 12 2009, 12:17
Сообщение #11


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 23-10-08
Из: Набережные Челны
Пользователь №: 41 132



Нет всетаки виноват протеус... У меня работает: Proteus 7.4 sp3 iar5.11b. ваш код
CODE
#include <ioavr.h>
#include <inavr.h>
#include <ina90.h>

//Обработка прерывания INT0***
#pragma vector = 0x04

__interrupt void INT0_ISR(void)
{
PORTD_Bit6 = 0; //смотрим по состоянию ножки выполнилось ли прерывание
}

int main( void )
{
DDRD_Bit7 = 1; //конфигурируем биты
DDRD_Bit6 = 1;
PORTD_Bit6 = 1;

DDRE=0xFF; //конфигурируем порты
DDRF=0xFF;
DDRB = 0xFF;

EIMSK|= 1<<0; //Разрешаем INT0
EICRA &= ~(1<<0); // по нижнему уровню
__enable_interrupt(); //разрешаем глобальные прерывания

while (1)
{
__delay_cycles(1000000);
PORTD_Bit7 = 1; //смотрим не виснет ли
__delay_cycles(1000000);
PORTD_Bit7 = 0;

PORTE=EIMSK; //смотрим текущее состояние
PORTF=SREG;
PORTB=EIFR;
}
}
А на счет DDRB = 0xFF просто я запутался rolleyes.gif
Причина редактирования: Уменьшение видимого размера цитаты исходника.

Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 12 2009, 12:53
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(mr_ia @ Feb 12 2009, 15:05) *
Спасибо что попробовали в AVRStudio, но хочется то что бы в IAR заработало...
Выше я говорил о том, что Ваша программа, оттранслированная IAR, нормально симулируется AVRStudio. Поскольку, аналогичная программа из CVAVR нормально симулируется в протеусе и Ваша программа, оттранслированная IAR у "чужих" тоже нормально симулируется, то, имхо, в настройках проекта IAR у Вас какая-то бяка...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 12 2009, 13:29
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(mr_ia @ Feb 12 2009, 13:31) *
нашел более менее подходящий кусок по обработке прерывания при перемолнении таймера счетчика, кусок работает. Написал для обработки INT0- Не работает...


А кто будет делать:

EXTINT = EXTINT_EINT0; // Clear the EXT interrupt flag
VICVectAddr = 0; // Dummy write to signal end of interrupt

А вообще исходник бредовый, и разговоры об эмуляции периферийного железа всякими приблудами - тоже sad.gif  Вместо многочасового тыка в "эмуляторе" надежнее и проще уделить 15 минут чтению документации и со знанием дела, уверенно написать эти несколько строк. 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 12 2009, 13:53
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(zltigo @ Feb 12 2009, 16:29) *
А кто будет делать:
EXTINT = EXTINT_EINT0; // Clear the EXT interrupt flag
VICVectAddr = 0; // Dummy write to signal end of interrupt
Имхо, это - "с другой оперы"... А, что работу перифирии проверять в симуляторе - плохо, тут я полностью согласен.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 12 2009, 14:02
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Палыч @ Feb 12 2009, 16:53) *
Имхо, это - "с другой оперы"... А, что работу перифирии проверять в симуляторе - плохо, тут я полностью согласен.

А!!! Чего-то привиделось, что LPC sad.gif. Тему перенес.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 24th June 2025 - 17:12
Рейтинг@Mail.ru


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