Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы

Помогите с прерываниями в AVR

Непрочитано 29.06.2012, 02:57  
olegdemkiv111
Частый гость
 
Регистрация: 27.06.2012
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 20 раз(а) в 20 сообщении(ях)
olegdemkiv111 на пути к лучшему
По умолчанию Помогите с прерываниями в AVR

сейчас начал изучать мк AVR а именно ATmega16 ... помигаты светодиодами уже могу, подключать кнопки и управлять светодиодами тоже могу ... только я все задержки времени делаю - ‹delay.h›, это занимая мне процессор, и я не могу ничего делать микроконтроллером пока он считает задержку ... я знаю есть такая фигня как - прерывание по таймеру, только я незнаю как им пользоваться, как его запустить ... я составляю программы на Си в CVAVR ...
скиньте пожалуйста какие обучалки ... чтобы там доступно было объяснено ... с кодом написанной в CVAVR на Си ...
если есть какие-то собственные непростые программы с комментариями то закидывает сюда, или напишите пожалуйста программу здесь простую программу для миганием диода только с использованием прерываний по таймеру ... но прошу с комментах, чем побольше комментариев ..
заранее спасибо ..)
Реклама:
olegdemkiv111 вне форума  
Сказали "Спасибо" olegdemkiv111
warel (29.06.2019)
Непрочитано 29.06.2012, 09:11  
Flopix
Гражданин KAZUS.RUN
 
Регистрация: 31.12.2010
Сообщений: 837
Сказал спасибо: 371
Сказали Спасибо 153 раз(а) в 113 сообщении(ях)
Flopix на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

olegdemkiv111, В CodeVision есть такая замечательная утилита как CodeWizardAVR.

Заходим в Tools-›CodeWizardAVR вкладка Timers-›Timer1

Например для TImer1, его удобно использовать тем что он 16 битный и на нем можно организовать большие задержки без дополнительных программных счетчиков.

Выставляем в меню:
ClockSource: System Clock - источником импульсов для Timer1 будет системный генератор.

ClockValue: - это настройка предделителя, она задает во сколько раз будет делиться частота выбранная как СlockSource выше. Правда в СodeVision в этом поле задается не значение предделителя, а сразу же можно выбрать необходимую нам частоту из списка возможных значений, список разный в зависимости от выставленной частоты на которой будет работает микроконтроллер. При частоте кварца 16МГц доступны следующие значения:

16000кГц - предделитель = 1
2000кГц - предделитель = 8
250кГц - предделитель = 64
62,500кГц - предделитель = 256
15,625кГц - предделитель = 1024

Что из них выбирать определимся ниже, пока пропускаем.


Остальные поля не меняем. Кроме Interrupt on - это собственно и есть настройка которое задает при каких условиях по таймеру будет вызвана подпрограмма прерывания. Можно для начала выбрать значение - Timer1 overflow - прерывание по переполнению Timer1.

В соответствии с выполненными настройками периодически значение таймера будет увеличиваться от 0 до максимального значения FFFF шестнадцатеричное (65535 в десятичной системе). Когда счетчик таймера достигнет максимального значения FFFF и будет увеличен на 1, счетчик таймера сбросится на 0 и будет сгенерировано событие переполнение Timer1 и соответственно вызвана наша подпрограмма.

Расчета времени в течении которого таймер переполнится:

(1000000 мкСек / ClockValue) * 65536, значение будет в микросекундах.

Например если выбрать значение ClockValue 15,625кГц = 15625Гц, то

(1000000 / 15625) * 65536 = 4194304мкСек = 4,194304 Сек.

То есть подпрограмма прерывания будет вызвана примерно раз в 4 секунды.

Настраиваем остальные нужные настройки проекта в Wizard (параметры портов ввода вывода и т.п.) и генерируем текст программы. Wizard сам добавит в тело главной функции main() команду #asm("sei") - глобальное разрешение прерываний.



Также wizard добавил функцию которая будет вызываться по переполнению таймера

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here

}


В ее тело пишете свой код который например будет включать-выключать светодиод.


Попробуйте сначала сделать это, потом я расскажу как можно более тонко в самой программе настраивать задержку срабатывания таймера.

Сразу же предостережение. Код размешенный в подпрограмме прерывания принято делать максимально коротким и быстрым. Нужно избегать применения в нем сложных вычислений.

Последний раз редактировалось Flopix; 29.06.2012 в 09:21.
Flopix вне форума  
Эти 3 пользователя(ей) сказали Спасибо Flopix за это сообщение:
Ara41 (29.06.2012), olegdemkiv111 (29.06.2012), warel (29.06.2019)
Непрочитано 29.06.2012, 15:05  
olegdemkiv111
Частый гость
 
Регистрация: 27.06.2012
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 20 раз(а) в 20 сообщении(ях)
olegdemkiv111 на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Большое спасибо Flopix, Вы все очень понятно объяснили .)
я сегодня вечером буду пробовать писать программу так как Вы говорите,
результат, и свои вопросы представлю здесь ...
olegdemkiv111 вне форума  
Сказали "Спасибо" olegdemkiv111
warel (29.06.2019)
Непрочитано 29.06.2012, 19:35  
olegdemkiv111
Частый гость
 
Регистрация: 27.06.2012
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 20 раз(а) в 20 сообщении(ях)
olegdemkiv111 на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Flopix ,Это код программы ...
я его прокомментирую как понимаю ... Вы посмотрите и проверите чи я правильго его понимаю ..


/************************************************** ***
This program was produced by the
CodeWizardAVR V2.05.0 Evaluation
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 02.07.2012
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 1,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
************************************************** ***/

#include ‹mega16.h›
#include ‹delay.h›

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void) //эта программа считает примерно четыре секунды незавантажуючы процессор ... если прошло чуть больше четырех секунд программа позволяет делать код что ниже. (в моем случае это мигание светодиодом) в этой программе - delay_ms, это уже загружает процессор ... поэтому нужно делать эту программу мигания чем по короче, поскольку процессор может делать ничего другого пока он считает задержку ...
И так ... основная программа здесь ---

/ / Global enable interrupts
# asm ("sei")

while (1)
****** {
******
****** / / ******** ЗДЕСЬ ********* / /

****** }
}
Она себе выполняется чуть больше четырех секунд ... когда проходит то время она останавливается и начинает выполняться программа ----

interrupt [TIM1_OVF] void timer1_ovf_isr (void) / / [COLOR = "Lime"] [/ COLOR]
{
PORTA.0 = 1;
delay_ms (300);
PORTA.0 = 0;
delay_ms (300);

/ / Place your code here

}

После 300 +300 мс = 600 мс она завершается в программа начинает делать свою главную функцию ... ----

/ / Global enable interrupts
# asm ("sei")

while (1)
****** {
******
****** / / ******** ЗДЕСЬ ********* / /

****** }
}




{ // программа мигания
PORTA.0=1;
delay_ms(300);
PORTA.0=0;
delay_ms(300);

// Place your code here

}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=T State1=P State0=0
PORTA=0x02;
DDRA=0x01;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// Global enable interrupts
#asm("sei")

while (1)
{

// Головна програма...

}
}



// Прогрма работает вроде правельно, светодиод мигает приблизго раз в четыре секунды ...))

Последний раз редактировалось olegdemkiv111; 29.06.2012 в 20:20.
olegdemkiv111 вне форума  
Сказали "Спасибо" olegdemkiv111
warel (29.06.2019)
Непрочитано 29.06.2012, 20:54  
Flopix
Гражданин KAZUS.RUN
 
Регистрация: 31.12.2010
Сообщений: 837
Сказал спасибо: 371
Сказали Спасибо 153 раз(а) в 113 сообщении(ях)
Flopix на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Не не не, я об этом и писал никаких delay_ms (300); в теле прерывания, введите глобальную переменную которая будет помнить последнее состояние светодиода. В одно прерывания включаем светодиод, во второй вызов выключаем. Но никаких пауз в прерывании быть не должно.
Flopix вне форума  
Сказали "Спасибо" Flopix
warel (29.06.2019)
Непрочитано 29.06.2012, 21:00  
_Артём_
Гражданин KAZUS.RUN
 
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
_Артём_ на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Сообщение от Flopix Посмотреть сообщение
Не не не, я об этом и писал никаких delay_ms (300); в теле прерывания,
Это да - правильно.


Сообщение от Flopix Посмотреть сообщение
введите глобальную переменную которая будет помнить последнее состояние светодиода. В одно прерывания включаем светодиод, во второй вызов выключаем.
Что её вводить-то, она и так есть: PORTx называется.

Сообщение от Flopix Посмотреть сообщение
Но никаких пауз в прерывании быть не должно.
Ну иногда всё же можно, если очень хочется или программа учебная.
_Артём_ вне форума  
Эти 2 пользователя(ей) сказали Спасибо _Артём_ за это сообщение:
olegdemkiv111 (29.06.2012), warel (29.06.2019)
Непрочитано 29.06.2012, 21:22  
olegdemkiv111
Частый гость
 
Регистрация: 27.06.2012
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 20 раз(а) в 20 сообщении(ях)
olegdemkiv111 на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Flopix,сделал как Вы говорили...

/************************************************** ***
This program was produced by the
CodeWizardAVR V2.05.0 Evaluation
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 02.07.2012
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 1,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
************************************************** ***/

#include ‹mega16.h›
#include ‹delay.h›
bit x;

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
x=~x; // инвертирует бит который в главной программе вывожу на порт А
// Place your code here

}

// Declare your global variables here



void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=T State1=P State0=0
PORTA=0x02;
DDRA=0x01;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// Global enable interrupts
#asm("sei")

while (1)
{
PORTA.0=x; // тут я вывожу переменную х которое инвертирует в функции перересання


}
}
olegdemkiv111 вне форума  
Сказали "Спасибо" olegdemkiv111
warel (29.06.2019)
Непрочитано 29.06.2012, 22:11  
_Артём_
Гражданин KAZUS.RUN
 
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
_Артём_ на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Сообщение от olegdemkiv111 Посмотреть сообщение
while (1)
{
PORTA.0=x; // тут я вывожу переменную х которое инвертирует в функции перересання
}
}
Может сразу в прерывании и инвертировать?

Код:
// Timer1 overflow interrupt service routine
 interrupt [TIM1_OVF] void timer1_ovf_isr(void)
 {
PORTA^=0x01; // инверсия состояния выхода
 // Place your code here

 }
P.S. Возможны глюки при работе с переменными в прерывании и в основной программе, поэтому не нужно ли определить x как volatile (не знаю как с этим у CodeVision)?
_Артём_ вне форума  
Эти 2 пользователя(ей) сказали Спасибо _Артём_ за это сообщение:
olegdemkiv111 (29.06.2012), warel (29.06.2019)
Непрочитано 30.06.2012, 02:22  
olegdemkiv111
Частый гость
 
Регистрация: 27.06.2012
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 20 раз(а) в 20 сообщении(ях)
olegdemkiv111 на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Flopixчто дальше ...?
Вы говорили, что поможете мне дальше ...
olegdemkiv111 вне форума  
Сказали "Спасибо" olegdemkiv111
warel (29.06.2019)
Непрочитано 30.06.2012, 06:37  
Flopix
Гражданин KAZUS.RUN
 
Регистрация: 31.12.2010
Сообщений: 837
Сказал спасибо: 371
Сказали Спасибо 153 раз(а) в 113 сообщении(ях)
Flopix на пути к лучшему
По умолчанию Re: Помогите с прерываниями в AVR

Теперь научимся программно менять задержку срабатывания таймера.

Для этого в функции прерывания, желательно в самом конце присваиваем какое то начальное значение переменной счетчика таймера, для Timer1 это TCNT1.

И так для выбранной нами частоты 15625 время за которое значение счетчика увеличивается на 1 составляет 1000000 / 15625 = 64 мкСек.

Например если мы сразу зададим максимальное значение для счетчика таймера FFFF (65535 дес.) то уже через 64 микросекунды таймер переполнится и наше прерывание будет вызвано вновь. Так как так часто мигать светодиодом нам не нужно то рассчитываем нужное нам значение по формуле:

65536 - (t / (1000000 / f))

где
t - нужная нам задержка в мкс
f - частота генератора для таймера в нашем случае 15625Гц

Если нам нужно получить задержку равную 0,5 секунды (500000 мкс), то:

65536 - (500000/(1000000/15625)) = 65536 - (500000/64) = 65536 - 7812,5 = 57723,5, тут придется округлить, неточность в +-32 микросекунды в задержке 500000 микросекунд несущественна.

Теперь наш код примет вид:

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here

//тут ваш код

TCNT1 = 57723;
}
Flopix вне форума  
Сказали "Спасибо" Flopix
warel (29.06.2019)
 
Опции темы

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Mega48. Как работать с прерываниями PCintX ? aleksandr_zh Микроконтроллеры, АЦП, память и т.д 18 27.01.2012 15:07
Почему не работает код с прерываниями Archer07 Микроконтроллеры, АЦП, память и т.д 13 03.09.2011 20:17
Codevision AVR + AVR Studio помогите разобраться с отладкой Daget Микроконтроллеры, АЦП, память и т.д 24 07.03.2011 14:41
Проблема с прерываниями в AVR Zemlyanov Микроконтроллеры, АЦП, память и т.д 14 02.07.2008 15:23
Проблема с прерываниями. sniper-dv Proteus 7 02.02.2007 13:28


Часовой пояс GMT +4, время: 13:35.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.