Страница 1 из 2
Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 09:48:04
Дем
Добрый день.
Начинаю осваивать МК.
Но что то не пошло с прерываниями. С таймером разобрался, начал разбираться с внешними прерываниями, но идет затыкаю Вот код.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
unsigned int k,hour, set_hout, delta, i;
ISR(TIMER0_OVF_vect)
{
k=k+1;
if (k>=900)
{
hour=hour+delta;
k=0;
}
}
ISR(INT0_vect)
{
cli();
_delay_ms(100);
set_hour=set_hour+delta;
i=i+1;
if (i==5)
{
i=0;
set_hour=delta;
}
switch (i)
{
case 0 : PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));
case 1 : PORTB |= (1 << 0); break;
case 2 : PORTB |= (1 << 2); break;
case 3 : PORTB |= (1 << 3); break;
case 4 : PORTB |= (1 << 4); break;
default : PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));
}
sei();
}
int main(void)
{
k=0;
hour=0;
delta=30;
set_hour=delta;
i=0;
DDRB=0; // все ножки на вход
DDRB |= (1 << 0)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5); //1,2,3,4,5 на выход
PORTB |= (1 << 5); //5 =1
PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));//1,2,3,4 = 0
PORTB |= (1 << 1); //0 вывод вход по умолчани
GIMSK|=(1<<INT0);//Включаем внешние прерывание
MCUCR|=(0<<ISC00)|(1<<ISC01); //Настраиваем прерывание на срабатывание по спадающему фронт
TCCR0A=0; //счетчик счетает в режиме нормаль
TCCR0B|= (0<<CS02)|(0<<CS01)|(1<<CS00); //001 без деления 101 -1024, 100-256
TCNT0 = 0; //обнулние счетчика
TIMSK0 |= (1<<TOIE0); //разрешение прерывания по переполнению
sei(); // разрешаем глобальное прерывание
while (1)
{
if (set_hour==hour)
PORTB &= ~((1 << 5));
}
}
Работать должен так: нажимаем кнопку 5-вывод отключается через delta-время, еще раз нажимаем, delt+delta и т.д. до 4 раз. Так же при нажатии загораются светодиоды. Но при отладке вылетает из цикла и начинает работать с int main(void). Думаю какой то конфликт прерываний, хотя в отладке пока ничего не нажимаю.
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 10:55:45
metan
Ничего не понятно.
Дем писал(а):Но при отладке вылетает из цикла и начинает работать с int main(void)
Из какого цикла вылетает? У вас в программе я кроме бесконечного цикла в майн других циклов не нашел.
По коду.
1. cll sei в подпрограмме обработки прерывания не нужны, это сделает сам чип.
2. Задержки в обработчиках прерываний - зло, их следует избегать.
3. Все проверки и действия, критически не завязанные на быстродействие, желательно выносить из обработчика в главный цикл. А в самом обработчике оставлять только максимально необходимый код, такой как например, установка флагов, которые можно проверить и в главном цикле.
4. Что касается обработки нажатий кнопок, то на этом сайте есть специальная
тема, там есть примеры качественно разработанных программ для этой истории.
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 11:00:07
Дем
Спасибо за ответ.
Последую Вашим рекомендациям.
Но у меня при отладке программа курсор отладки самопроизвольно выходит из бесконечного цикла и начинает работать с начала программы
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 15:34:07
Z_h_e
Для кода есть специальные тэги и желательно тот же код заключить в тэги спойлера. А то нечитабельно и длинно. Исправте, если правка еще возможна.
Ватчдог выключен во фьюзах? Если включен, то это бы все объясняло.
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 19:23:55
Дем
Вачдок не включен. Мне кажется что то не то с avr studio так ка прога работает на тиньке 2313 . Бред какой то.
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 19:55:22
Alkul
Дем писал(а):Мне кажется что то не то с avr studio так ка прога работает на тиньке 2313 . Бред какой то.
Мне кажется, я знаю, что у Вас не так.
Вы не инициализировали указатель стека SPL.
В ассемблере это делается в самом начале программы командами
Да, я знаю, что регистр SPL у ATtiny2313 инициализируется значением RAMEND по умолчанию. Но AVR Studio об этом, похоже, не знает. Во-всяком случае в моих проектах на асм, если вышеуказаные строки не включить в код, программа при отладке рестартует при первом же возврате из подпрограммы, когда адрес возврата снимается из стека с неинициализированным указателем вершины (а обработчик прерывания это тоже подпрограмма).
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 20:37:58
ARV
Alkul писал(а):Вы не инициализировали указатель стека SPL.
это же Си! компилятор всегда делает необходимый пролог, где все и инициализирует!
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 20:48:13
Mishany
Как настроена опоимизация?
Re: Конфликт прерываний на тиньке 13
Добавлено: Чт июн 30, 2016 21:48:19
COKPOWEHEU
Дем писал(а):
TCNT0 = 0; //обнулние счетчика
TIMSK0 |= (1<<TOIE0); //разрешение прерывания по переполнению
Дем писал(а):Вачдок не включен. Мне кажется что то не то с avr studio так ка прога работает на тиньке 2313 . Бред какой то.
Поскольку у ATtiny2313 нет регистра TIMSK0, очевидно, вы собираете прошивку для другого камня. Но если так, при чем здесь ATtiny2313? Перепроверьте настройки компилятора и симулятора. Само поведение похоже на вызов неизвестного прерывания.
Re: Конфликт прерываний на тиньке 13
Добавлено: Пт июл 01, 2016 05:00:29
Дем
Поскольку заподозрил что дело не совсем в проге, то перевел ееи настройки с тиньки13 на тиньку 2313. Так то я думал что у них регистры одинаково называются.
Re: Конфликт прерываний на тиньке 13
Добавлено: Пт июл 01, 2016 06:08:04
Z_h_e
У Вас не определена тактовая частота процессора. Установите нечто такое вначале программы.
Переменная объявлена с ошибкой, как вообще проект запускался? Если быть точнее, объявлена одна, в коде другая.
set_hou
t
И самое главное, поставте правильный вектор прерывания
Смотреть надо не только на ошибки при компиляции, но и на предупреждения.
Re: Конфликт прерываний на тиньке 13
Добавлено: Пт июл 01, 2016 07:38:53
COKPOWEHEU
Z_h_e писал(а):У Вас не определена тактовая частота процессора. Установите нечто такое вначале программы.
Частоту лучше указывать в настройках проекта, а не в исходном коде. Если будете собирать прошивку из нескольких файлов, придется внимательно следить чтобы частоты во совпадали во всех. Неужели в последних версиях студии нельзя задать командную строку компилятора? Добавить надо всего лишь -DF_CPU=8000000
Z_h_e писал(а):
Смотреть надо не только на ошибки при компиляции, но и на предупреждения.
Вот предупреждения надо исправлять всегда, разве что 100% уверены что делаете правильно, а для удовлетворения компилятора пришлось бы уж слишком извращаться.
Re: Конфликт прерываний на тиньке 13
Добавлено: Пт июл 01, 2016 20:02:33
Дем
Ну что же в AVR заработало. Поставил TIME0. Но ни в железе ни в протеусе не работает. Други работают на тиньке 231тиньке. Но на тиньке 13 нехочет. Незнаю что делать
Re: Конфликт прерываний на тиньке 13
Добавлено: Пт июл 01, 2016 20:40:01
Z_h_e
Попробуйте добавить все-таки определение F_CPU и обязательно перед #include <util/delay.h>.
Re: Конфликт прерываний на тиньке 13
Добавлено: Пт июл 01, 2016 22:16:15
Дем
Z_h_e писал(а):Попробуйте добавить все-таки определение F_CPU и обязательно перед #include <util/delay.h>.
Добавил. Ничего. Везде проверил. Кстати почему то не работает делитель таймера, работает только cs00=1
Re: Конфликт прерываний на тиньке 13
Добавлено: Пт июл 01, 2016 22:55:58
COKPOWEHEU
Выложите оба проекта полностью - для ATtiny2313 и ATtiny13.
Re: Конфликт прерываний на тиньке 13
Добавлено: Вс июл 03, 2016 08:49:20
Дем
переделал код под Аттини13
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
unsigned int k,hour, set_hour, delta, i;
ISR(TIM0_OVF_vect)
{
k=k+1;
if (k>=900)
{
hour=hour+delta;
k=0;
}
}
int main(void)
{
k=0;
hour=0;
delta=30;
set_hour=delta;
i=0;
DDRB=0; // все ножки на вход
DDRB |= (1 << 0)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5); //1,2,3,4,5 на выход
PORTB |= (1 << 5); //5 =1
PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));//1,2,3,4 = 0
PORTB |= (1 << 1); //0 вывод вход по умолчанию 1
TCCR0A=0; //счетчик счетает в режиме нормаль
TCCR0B|= (0<<CS02)|(0<<CS01)|(1<<CS00); //001 без деления 101 -1024, 100-256
TCNT0 = 0; //обнулние счетчика
TIMSK0 |= (1<<TOIE0); //разрешение прерывания по переполнению
sei(); // разрешаем глобальное прерывание
while (1)
{
if (!(PORTB & (1<<PB1)))
{
_delay_ms(50);
if (!(PORTB & (1<<PB1)))
{
i++;
set_hour=set_hour+delta;
}
}
if (i==5)
{
i=0;
set_hour=delta;
}
if (i==0)
PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));
if (i==1)
PORTB |= (1 << 0);
if (i==2)
PORTB |= (1 << 2);
if (i==3)
PORTB |= (1 << 3);
if (i==4)
PORTB |= (1 << 4);
if (set_hour==hour)
PORTB &= ~((1 << 5));
}
}
но дело в том что просто даже это не работает:
Код: Выделить всё
#define F_CPU 4800000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB=0x00; // порт B на выход
PORTB=0xFF; // все входы на порте B=0
DDRD =0xFF;
PORTD=0xFF;
while(1)
{
if (PORTD & (1 << PD1))
{
PORTB |= (1 << PB1);
// _delay_ms(5000);
}
else
{
PORTB &=~ (1 << PB1);
}
if (!(PORTD & (1 << PD1)))
{
PORTB &=~ (1 << PB1);
// _delay_ms(5000);
}
}
}
Вернее в AVR6 работает а в протеусе нет.
Может какие настойки нужны
Re: Конфликт прерываний на тиньке 13
Добавлено: Вс июл 03, 2016 08:52:50
Дем
последний код для 2313 (что-то пердыдущее сообщение не корректируется)
Re: Конфликт прерываний на тиньке 13
Добавлено: Вс июл 03, 2016 09:30:03
Z_h_e
Протеус много сообщений выдает при симуляции. Поглядите там. Например могут быть сообщений типа "рестарт из-за.."
Re: Конфликт прерываний на тиньке 13
Добавлено: Вс июл 03, 2016 09:35:35
Z_h_e
Кстати. А как код для 2313 должен работать? Вы же значения порта D нигде не меняете. А если имелось ввиду внешнии кнопки, то проверяйте регистр PIND, а не PORTD.