Страница 1 из 1
СТАТЬЯ: По курсу освоения AVR(глава Прерывания)
Добавлено: Вт окт 11, 2005 17:27:43
Владимир
Разъясните чуть подробней,почему после ссылок на все прерывания
закоментированы именно те прерывания,которые используются в программе(Reset и Timer1_comp1),а не наоборот?Логичнее исключить прерывания,которые не используются.Или здесь что-то особенное?
И ещё - при компиляции последней версии проги(с прерываниями)
компилер ругается:
code asm:27 Error:Label'INT0' already defined at line 87 in 'c:\avr\
avrasv\appnotes\2313DEF.inc'
Аналогично и о "INT1".

:
Re: По курсу освоения AVR(глава Прерывания)
Добавлено: Вт окт 11, 2005 17:34:08
Владимир
В подпрограмме Delay наверное надо:
out DDRB,Temp
----------
И не сомневайся даже
отдых - кайф,работа - лажа
Добавлено: Вт окт 11, 2005 17:45:19
Serega
Я ж уже давно это исправил...
Переобзови метки, например INT_0, INT_1.
По прерываниям: смари, в самом начале проги, по каждому вектору прерывания мы даем ссылку на обработчик этого прерывания. Если это прерывание используется и обработчик для него написан - замечательно. Но если прерывания нет, мы все равно обязаны написать метку на обработчик. Иначе компилер, увидев ссылку на несуществующую метку страшно выругается и обидится

Поэтому мы прописываем пачкой все метки и выполняем по ним команду reti.
Можно было бы просто поставить по векторам ссылки только на обработчики используемых прерываний, а остальные адреса забить nop'ами:
rjmp Reset
nop
nop
nop
rjmp Timer1_comp1
nop
nop
nop
nop
nop
nop
Но это не очень удобно: если мы захотим использовать в программе еще какое-то прерывание - надо будет лезть в даташит, смотреть его адрес и прописывать.
А данная структура универсальна. Всего-то надо - закомментировать используемые прерывания и все...

По курсу освоения AVR(глава Прерывания)
Добавлено: Ср окт 12, 2005 16:13:34
Владимир
Хотя и попозже,но дошло.Слава Коту!
Спасибо!
_____
И не сомневайся даже...отдых - кайф, работа - лажа!
Добавлено: Вт апр 21, 2009 21:06:13
Razor
Не нашел нужной темы, поэтому решил написать в эту. Есть проблема:
программирую под Мега16 на асме в авр студио 4. вот код
Код: Выделить всё
.include "m16def.inc"
.def Temp=R16
.def Temp1=R17
.def Temp2=R18
.def Temp3=R19
.cseg
.org 0
;вектора прерываний
rjmp RESET ; Reset Handler
rjmp EXT_INT0 ; IRQ0 Handler
rjmp EXT_INT1 ; IRQ1 Handler
rjmp TIM2_COMP ; Timer2 Compare Handler
rjmp TIM2_OVF ; Timer2 Overflow Handler
rjmp TIM1_CAPT ; Timer1 Capture Handler
rjmp TIM1_COMPA ; Timer1 CompareA Handler
rjmp TIM1_COMPB ; Timer1 CompareB Handler
rjmp TIM1_OVF ; Timer1 Overflow Handler
rjmp TIM0_OVF ; Timer0 Overflow Handler
rjmp SPI_STC ; SPI Transfer Complete Handler
rjmp USART_RXC ; USART RX Complete Handler
rjmp USART_UDRE ; UDR Empty Handler
rjmp USART_TXC ; USART TX Complete Handler
rjmp _ADC ; ADC Conversion Complete Handler
rjmp EE_RDY ; EEPROM Ready Handler
rjmp ANA_COMP ; Analog Comparator Handler
rjmp TWSI ; Two-wire Serial Interface Handler
rjmp EXT_INT2 ; IRQ2 Handler
rjmp TIM0_COMP ; Timer0 Compare Handler
rjmp SPM_RDY ; Store Program Memory Ready Handler
;RESET: ; Reset Handler
EXT_INT0: ; IRQ0 Handler
EXT_INT1: ; IRQ1 Handler
TIM2_COMP: ; Timer2 Compare Handler
TIM2_OVF: ; Timer2 Overflow Handler
TIM1_CAPT: ; Timer1 Capture Handler
TIM1_COMPA: ; Timer1 CompareA Handler
TIM1_COMPB: ; Timer1 CompareB Handler
TIM1_OVF: ; Timer1 Overflow Handler
TIM0_OVF: ; Timer0 Overflow Handler
SPI_STC: ; SPI Transfer Complete Handler
USART_RXC: ; USART RX Complete Handler
USART_UDRE: ; UDR Empty Handler
USART_TXC: ; USART TX Complete Handler
_ADC: ; ADC Conversion Complete Handler
EE_RDY: ; EEPROM Ready Handler
ANA_COMP: ; Analog Comparator Handler
TWSI: ; Two-wire Serial Interface Handler
EXT_INT2: ; IRQ2 Handler
TIM0_COMP: ; Timer0 Compare Handler
SPM_RDY: ; Store Program Memory Ready Handler
reti
;****************************************************
; ИНИЦИАЛИЗАЦИЯ
;****************************************************
Reset: ldi Temp,0b11111111 ;настройка портов
out DDRA,Temp
ldi Temp,0 ;инициализация компаратора
out OCR1AH,Temp
ldi Temp,0x4B
out OCR1AL,Temp
ldi Temp,0b00010000 ;разрешить прерывание компаратора
out TIMSK,Temp
ldi Temp,0b00000001 ;тактовый сигнал = CK/1
out TCCR1B,Temp
ldi Temp,low(RAMEND) ;установка указателя стека
out SPL,Temp
ldi Temp,high(RAMEND)
out SPH, Temp
ldi Temp1,0b00000001 ;инициализация индикатора
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
sei ;разрешить прерывания
;****************************************************
; ОСНОВНОЙ ЦИКЛ
;****************************************************
Inf: rjmp Inf ;бесконечный цикл
;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************
Timer1_comp1:
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
Shift: cpi Temp1,0b10000000 ;сравнить с крайним знач.
breq Init ;если равно - загрузка нач. знач.
lsl Temp1 ;иначе - сдвиг влево
rjmp Output ;перейти на вывод в порт
Init: ldi Temp1,0b00000001 ;загрузить нач. значение
Output: out PortA,Temp1 ;вывод в порт
reti ;выход из обработчика
Адреса прерываний нахально слиты из даташита на Мегу16, но вместо прерывания по таймеру на строке
rjmp TIM1_COMPA ; Timer1 CompareA Handler программа переходит на строчку
rjmp USART_UDRE ; UDR Empty Handler
Не могу понять почему. Поясните плиз если знаете ответ.
Добавлено: Вт апр 21, 2009 21:46:09
GP1
В меге16 адреса прерываний 2-х байтовые, поэтому инструкция
rjmp
будет приводить к непредсказуемым результатам
необходимо использовать
jmp
Обработчики прерываний лучше размещать после тела основной программы, меньше вероятность ошибочных переходов.
для обнуления регистра лучше использовать clr Rn, а для установки всех разрядов в "1" ser Rn
это то, что бросилось в глаза, остальное не проверял.
Добавлено: Вт апр 21, 2009 22:05:09
GP1
Еще, стек необходимо инициализировать до его использования, лучше всего если это будут первые строки.
команды относящиеся к инициализации одной и той же перефирии лучше писать подряд, иначе уже через месяц вы убьете кучу времени и сил пытаясь разобраться в вами же написаном.
если начинаете программировать то лучше сразу приучить себя к единому порядку оформления текста программ, и заставьте себя перед метками переходов на обработчики прерываний ставить директиву .org <addr> ;Описание вектора, очень помогает при переброске программы с одного МК на другой, (к примеру с меги16 на мегу32 если вдруг памяти не хватит)
Поверьте, в будушем это съэкономит вам такую уйму времени...
Добавлено: Вт апр 21, 2009 22:34:58
edm2007
Обучалка великолепная, за что отдельная благодарность. Только при работе с прерыванием по таймеру огни стартуют начиная со второго. Оно и правильно, ведь сначала сдвигаем а потом уже выводим на индикацию. Вроде мелочь, а как-то того...
З.Ы. А вот за что учетку мою удалили (второй раз уже) непонятно. Я так понимаю, под тяжелую руку санитара попал. Пришлось заново регистрироваться.

Добавлено: Вт апр 21, 2009 22:47:21
asteroid7
Razor писал(а):...
Не могу понять почему.
...
Всё просто. В таблице векторов на каждый вектор отводится 2 слова или 4 байта. Команда RJMP занимает 2 байта, а JPM все 4.
В вашем примере таблица стала в 2 раза короче.
Как вариант для проверки, добавьте после каждого RJMP команду NOP. Будет работать. Но не делайте так в программах

Добавлено: Ср апр 22, 2009 05:08:23
Razor
GP1 и asteroid7 спасибо! Сравнил даташиты - точно в тиньке адреса различаются на байт а в меге на слово. Ну и ну ... может на Сях начать писать пока не поздно. Таких подводных камней я не ожидал ... это что мне теперь размер всех команд учить что ли? И где их взять? В смысле размеры команд.
Добавлено: Ср апр 22, 2009 07:46:28
GP1
Говорят на Си программировать проще (сам не пробовал

), но если хочешь знать процик до "последнего винтика" без асм-а не обойтись.
АСМ рулит!
Добавлено: Ср апр 22, 2009 08:03:28
asteroid7
Razor писал(а):... это что мне теперь размер всех команд учить что ли? И где их взять? В смысле размеры команд.
Да нет. Достаточно учитывать если память контроллера до или равно 4кБ - RJMP, больше JMP.
Хороший хелп по командам есть в AVR Studio. Постоянно им пользуюсь.
Добавлено: Ср апр 22, 2009 08:14:16
GP1
RJMP можно использовать, если адрес перехода отстоит не далее чем 2К
Добавлено: Ср апр 22, 2009 09:22:39
edm2007
Razor писал(а):...Ну и ну ... может на Сях начать писать пока не поздно. Таких подводных камней я не ожидал ...
Ну да, на Си проще, а на Бейсике так вообще элементарно. Дело-то в другом. Знать язык, и писать на нем - две разные вещи. Писать можно на чем угодно, а вот для того что бы "увидеть" что происходит внутри контроллера при выполнении программы - без АСМ не обойтись.
P.S. Да и вообще, этот язык интересен и логичен. Сам сейчас занимаюсь его изучением.
Добавлено: Ср апр 22, 2009 11:19:17
Yellow Tiger
А разве ассемблер студии (кто там - ГНУ?) не выдает диагностику типа:
Код: Выделить всё
rjmp.asm(4): error: Relative branch out of reach
???
Добавлено: Ср апр 22, 2009 11:26:08
GP1
если нет директивы
.device -------
то не выдает
Добавлено: Ср апр 22, 2009 11:46:48
edm2007
А все же как грамотнее изменить код, дабы светодиоды стартовали с первого? Вариантов-то несколько...
Добавлено: Ср апр 22, 2009 12:08:28
Yellow Tiger
GP1 писал(а):если нет директивы .device то не выдает
Вероятно потому, что он не только под AVR - в avrasm'е это происходит и без указания целевого кристалла.