Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.74/74: Рейтинг темы: голосов - 74, средняя оценка - 4.74
VtTykht
0 / 0 / 0
Регистрация: 17.09.2012
Сообщений: 19
1

AtTiny 2313, прерывания

20.09.2012, 20:04. Просмотров 13464. Ответов 24
Метки нет (Все метки)

Доброго времени суток. Решил освоить программирование МК и сразу же столкнулся с проблемой, которую не могу разрешить.
Имеется плата с МК Attiny 2313, к которой подключены 15 светодиодов.
Есть элементарная программа (компилирую в WINAVR), мигающая диодами (в данном случае порта B) с интервалом в 5 секунд.
Код
   #define F_CPU 4000000UL  // 4 MHz
#include <avr/io.h>
#include <util/delay.h>

int main(void)              // начало основой программы
{
PORTA=0x07;
DDRA=0x07;

PORTB=0xFF;
DDRB=0xFF;

PORTD=0x7F;
DDRD=0x7F;

while (1)
{              // Бесконечный цикл
_delay_ms(5000);
PORTB = ~PORTB;

}       // закрывающая скобка бесконечного цикла

}      // закрывающая скобка основной программы
Она работает.
Двигаясь дальше, я решил освоить моргание с помощью прерывания по совпадению
Код
   #define F_CPU 4000000UL  // 4 MHz
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) //обработчик прерывания по совпадению А
{
PORTB = ~PORTB;
}

int main(void)              // начало основой программы
{
DDRA=0x07;
PORTA=0x07;

DDRB=0xFF;
PORTB=0xFF;

DDRD=0x7F;
PORTD=0x7F;

//Режим СТС
TCCR1A = 0x00;
TCCR1B = 0x0D; // Clock / 1024, CTC включен

TIMSK  = 0x40;

// 5 секунд
OCR1AH  = 0x4C;
OCR1AL  = 0x4B;

sei();

while (1)
{              // Бесконечный цикл

}       // закрывающая скобка бесконечного цикла

}      // закрывающая скобка основной программы
А вот эта программа заработала совсем не так, как я предполагал - диоды потушены,
затем коротко вспыхивают (не успев даже загореться в "полный накал"), опять гаснут на несколько секунд - и т.д.
Ради проверки я заменил
Код
   ISR(TIMER1_COMPA_vect) //обработчик прерывания по совпадению А
{
PORTB = ~PORTB;
}
на
Код
   ISR(TIMER1_COMPA_vect) //обработчик прерывания по совпадению А
{
PORTB = 0x00;
}
ожидая, что все диоды просто зажгутся и останутся гореть, но получил примерно ту же картину, что и в предыдущем случае - коротко моргающие диоды.

Вероятно, я что-то делаю неправильно, но не могу понять, что. :( Объясните, пожалуйста, как решить эту задачу, используя прерывание?

UPD: Добавил скриншот с конфигурацией фьюзов (это 4 MHz, я правильно понял?) и видео, чтобы было понятнее, как это выглядит (для видео уменьшил задержку до 2 сек.).
Фьюзы:

<Изображение удалено>

<Изображение удалено>

Задержка в основном цикле с помощью _delay_ms(): Тыц
Вызов из прерывания: Тыц
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.09.2012, 20:04
Ответы с готовыми решениями:

ATtiny 2313. Бегущие огни через прерывания
Помогите пожалуйста отредактировать/исправить код на авр студио. Задание было...

ATtiny 2313
Добрый день, возникли трудности с работой с МК. Это мой первый практический...

Термостат на ATTiny 2313
Собираю термостат в Протеусе на Attiny 2313. Имеется код на ассемблере...

Attiny 2313 не прошивается
Attiny 2313 пытаюсь прошить через arduino nano но ни как не могу подключил тут...

Использование таймера в ATTiny 2313
#include &lt;avr/io.h&gt; #include &lt;avr/interrupt.h&gt; unsigned char rab;...

24
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
20.09.2012, 21:05 2
1.
//Режим СТС
TCCR1A = 0x00;
TCCR1B = 0x0D; // Clock / 1024, CTC включен

TIMSK = 0x40;
Что за нигические цифры???
Молодой человек (читай "пионер" ;-), потрудитесь перевести эти числа в удобочитаемые ЧЕЛОВЕКОМ символы. Я, например, в машинных кодах не умею программировать, и не собираюсь в них разбираться.

Записывать нужно так:
Код
TCCR1A = (0<<WGM11)|(0<<WGM10);
TCCR1B = (0<<WGM13)|(1<<WGM12) | (1<<CS12)|(0<<CS11)|(1<<SC10);

TIMSK = (1<<OCIE1A);
2. Нужно проверить - как настроен МК - на какую частоту.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
20.09.2012, 22:27 3
1 - какое устройство вы хотите получить в данный момент?
2 - Мигающие светодиоды - для человека, а человеко-интерфейсы медленные. И нет нужды загромождать прерывание.
3 - Уясните, что прерывание должно быть максимально минимальным. При написании программ с использованием прерываний нужно стараться, чтобы в прерывании делались короткие действия. Например выставить флаг, который будет обрабатываться в основном цикле.
0
VtTykht
0 / 0 / 0
Регистрация: 17.09.2012
Сообщений: 19
20.09.2012, 23:12 4
Цитата Сообщение от kytikot
Что за нигические цифры???
Молодой человек (читай "пионер" ;-), потрудитесь перевести эти числа в удобочитаемые ЧЕЛОВЕКОМ символы. Я, например, в машинных кодах не умею программировать, и не собираюсь в них разбираться.
2. Нужно проверить - как настроен МК - на какую частоту.
Спасибо, дедушка ;) В будущем буду стараться следовать Вашим рекомендациям.
Сейчас нет возможности сделать скриншот конфигурации фьюзов, но насколько я понимаю, именно 4 MHz, делитель частоты выключен (ну и _delay_ms(5000) отрабатывал по времени примерно 5 сек.)

Цитата Сообщение от dymyurk1978
1 - какое устройство вы хотите получить в данный момент?
2 - Мигающие светодиоды - для человека, а человеко-интерфейсы медленные. И нет нужды загромождать прерывание.
3 - Уясните, что прерывание должно быть максимально минимальным. При написании программ с использованием прерываний нужно стараться, чтобы в прерывании делались короткие действия. Например выставить флаг, который будет обрабатываться в основном цикле.
1. В данный момент я хочу получить возможность зажигать / гасить светодиоды по прерыванию. Понятно, что это не конечная задача; в целом мне в итоге хочется получить эти 15 светодиодов, светящихся несколько секунд на 30%, затем с эффектом: 1 диод 50% яркости (250 мс пауза) -> 1 диод 50% яркости, 2 диод 60% яркости (250мс пауза) -> 1 диод 50% яркости, 2 диод 60% яркости, 3 диод 70% яркости (250мс пауза) - и т.д.
2,3 Спасибо, я буду иметь это в виду.. конкретно эта задача - гашение и зажигание диодов - просто упражнение для новичка, чтобы уяснить возможности МК
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
20.09.2012, 23:21 5
Я проверил на пинборде, все работает. http://youtu.be/1AV4KoVartA
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
20.09.2012, 23:24 6
<Изображение удалено>

фьюзы на 4МГц
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
20.09.2012, 23:31 7
Кстати, рекомендую сразу же набрать себе набор "дефайнов". И потом, таскайть их из проекта в проект.
Например, такой:

Код
//----- настройка таймера 1 CTC ------------------------------------------

#define   TIMER1_INIT      do{TIMSK|=(1<<OCIE1A);TCCR1A=0x00;TCCR1B=(0<<WGM13)|(1<<WGM12);}while(0)
#define   TIMER1_DISABLE   (TIMSK&=~(1<<OCIE1A))

#define   TIMER1_ZERO      (TCNT1=0)
#define   TIMER1_START_1024   (TCCR1B|=(1<<CS12)|(0<<CS11)|(1<<CS10))
// pressotir 1024
#define   TIMER1_STOP      (TCCR1B&=~((1<<CS12)|(1<<CS11)|(1<<CS10)))
//----------------------------------
И в дальнейшем писать в программе так:

Код
....
TIMER1_INIT;
TIMER1_ZERO;
....
TIMER1_START_1024;
while(1)
{
}
....
0
VtTykht
0 / 0 / 0
Регистрация: 17.09.2012
Сообщений: 19
20.09.2012, 23:33 8
Цитата Сообщение от dsodir
Я проверил на пинборде, все работает. http://youtu.be/1AV4KoVartA
Это здорово :)
Моя проблема может быть следствием какой-то проблемы в железе (с учётом того, что без использования прерываний всё работает), или такой вариант исключён?
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
20.09.2012, 23:38 9
Вот я тоже сначала подумал на железо. Но потом понял, что странно это и неправильно. Можно попробовать мигать другим пином каким-нибудь.

Еще попробуйте поменять МК, если можно. Это конечно не поможет, но зато мы исключим маловероятный сценарий (баг в МК)
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
20.09.2012, 23:38 10
Кстати, а можете скинуть весь проект для авр студии?
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
20.09.2012, 23:39 11
Цитата Сообщение от kytikot
Кстати, рекомендую сразу же набрать себе набор "дефайнов". И потом, таскайть их из проекта в проект.
Например, такой:

Код:
//----- настройка таймера 1 CTC ------------------------------------------

#define TIMER1_INIT do{TIMSK|=(1<<OCIE1A);TCCR1A=0x00;TCCR1B=(0<<WGM13)|(1<<WGM12);}while(0)
#define TIMER1_DISABLE (TIMSK&=~(1<<OCIE1A))

#define TIMER1_ZERO (TCNT1=0)
#define TIMER1_START_1024 (TCCR1B|=(1<<CS12)|(0<<CS11)|(1<<CS10))
// pressotir 1024
#define TIMER1_STOP (TCCR1B&=~((1<<CS12)|(1<<CS11)|(1<<CS10)))
//----------------------------------

И в дальнейшем писать в программе так:

Код
....
TIMER1_INIT;
TIMER1_ZERO;
....
TIMER1_START_1024;
while(1)
{
}
....
А потом люди будут читать и долго думать. Я думаю это лишнее, разве что для себя так писать
0
VtTykht
0 / 0 / 0
Регистрация: 17.09.2012
Сообщений: 19
20.09.2012, 23:56 12
Цитата Сообщение от dsodir
Кстати, а можете скинуть весь проект для авр студии?
Да там не проект, там программа на C, набранная в блокноте (которую я запостил) и makefile :)
AVR Studyo я не ставил пока, начал просто с компилятора WINAVR.
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
20.09.2012, 23:58 13
Я просто думаю, может оно случайно (в авр студии такого можно добиться :) скомпилировалось для другого МК. Тогда обычные мигалки могут работать, а вот с прерываниями будет затык. Дайте тогда .hex, я его попробую прошить себе
0
VtTykht
0 / 0 / 0
Регистрация: 17.09.2012
Сообщений: 19
21.09.2012, 00:18 14
Буду Вам признателен.
Тыц
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
21.09.2012, 00:28 15
К сожалению :) все работает
0
VtTykht
0 / 0 / 0
Регистрация: 17.09.2012
Сообщений: 19
21.09.2012, 00:43 16
Цитата Сообщение от dsodir
К сожалению :) все работает
Значит одну возможную причину можно вычеркнуть :) Спасибо
0
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
21.09.2012, 00:46 17
Судя по всему с платой у вас тоже все ОК (раз обычная мигалка работает)
0
DOOMSDOY
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
21.09.2012, 01:12 18
После экспериментов с прерываниями пробовал обратно зашить в контроллер код, мигающий в основном цикле?
Фузы точно не трогал, может WDTON случайно включил?
0
VtTykht
0 / 0 / 0
Регистрация: 17.09.2012
Сообщений: 19
21.09.2012, 13:39 19
Цитата Сообщение от DOOMSDOY
После экспериментов с прерываниями пробовал обратно зашить в контроллер код, мигающий в основном цикле?
Фузы точно не трогал, может WDTON случайно включил?
Да, прошивал и то, и то по очереди - код с задержкой в основном цикле нормально работает. WDTON выключен (в первый пост добавил картинку своих фузов и видео).

Ещё вот что: код в main() начинает работать сразу после прошивки. Чтобы заработал код в ISR(TIMER1_COMPA_vect) (ну, как заработал - чтобы началось короткое мигание) - нужно выключить и включить устройство. Именно выключить и включить, по RESIT исполняется только то, что в main(), то, что в ISR(TIMER1_COMPA_vect) не исполняется.
0
botu_dork
0 / 0 / 0
Регистрация: 09.02.2011
Сообщений: 544
21.09.2012, 15:12 20
А разве таймер в прерывании не нужно сбросить? или вы ждете пока он полный круг сам пройдет?
Более распространенным вариантом явлается инициализация таймера как (0хFFFF - необходимое вам значение )
и внутри обработчика прерывания при равенстве таймера нулю - заново иним это значение.
0
21.09.2012, 15:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.09.2012, 15:12

Работа с UART (Си, ATtiny 2313)
Дорогие формчане и знатаки по микроконтролёрам я Новичок в этом деле. У меня...

ATtiny 2313. Контроль освещения
Требуется написать программу на Assembler или на С++ Программа не для рабочего...

Attiny 2313 простая задачка с индикацией
Задача состоит вот в чем: На основе микроконтроллера Atmel Atiny2313...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru