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

 
 
 
Reply to this topicStart new topic
> Atmega1281 вектора прерывания, Некорректное поведение при отладке
alexxack
сообщение Apr 14 2014, 02:00
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 26-06-13
Пользователь №: 77 280



Уважаемые форумчане помогите в решении данного вопроса. При отладке в AVR Studio проекта на контроллере Atmega1281 переход по прерыванию происходит не по тому адресу по которому расположен вектор. Читал даташит на данный камушек и обнаружил в нем наличия в памяти сектора загрузки и есть подозрения что вектора прерывания распологаются не на своем месте а в секторе загрузки из за чего вектора прерываний смещаются. Помогите пожалуйста разобраться в данном вопросе.
CODE
.include "m1281def.inc"

jmp RESET ; Reset Handler
reti ;jmp INT0 ; IRQ0 Handler
reti ;jmp INT1 ; IRQ1 Handler
reti ;jmp INT2 ; IRQ2 Handler
reti ;jmp INT3 ; IRQ3 Handler
reti ;jmp INT4 ; IRQ4 Handler
reti ;jmp INT5 ; IRQ5 Handler
reti ;jmp INT6 ; IRQ6 Handler
reti ;jmp INT7 ; IRQ7 Handler
reti ;jmp PCINT0 ; PCINT0 Handler
reti ;jmp PCINT1 ; PCINT1 Handler
reti ;jmp PCINT2 ; PCINT2 Handler
reti ;jmp WDT ; Watchdog Timeout Handler
reti ;jmp TIM2_COMPA ; Timer2 CompareA Handler
reti ;jmp TIM2_COMPB ; Timer2 CompareB Handler
reti ;jmp TIM2_OVF ; Timer2 Overflow Handler
reti ;jmp TIM1_CAPT ; Timer1 Capture Handler
reti ;jmp TIM1_COMPA ; Timer1 CompareA Handler
reti ;jmp TIM1_COMPB ; Timer1 CompareB Handler
reti ;jmp TIM1_COMPC ; Timer1 CompareC Handler
reti ;jmp TIM1_OVF ; Timer1 Overflow Handler
reti ;jmp TIM0_COMPA ; Timer0 CompareA Handler
reti ;jmp TIM0_COMPB ; Timer0 CompareB Handler
reti ;jmp TIM0_OVF ; Timer0 Overflow Handler
reti ;jmp SPI_STC ; SPI Transfer Complete Handler
jmp USART0_RXC ; USART0 RX Complete Handler
jmp USART0_UDRE ; USART0,UDR Empty Handler
jmp USART0_TXC ; USART0 TX Complete Handler
reti ;jmp ANA_COMP ; Analog Comparator Handler
reti ;jmp ADC ; ADC Conversion Complete Handler
reti ;jmp EE_RDY ; EEPROM Ready Handler
reti ;jmp TIM3_CAPT ; Timer3 Capture Handler
reti ;jmp TIM3_COMPA ; Timer3 CompareA Handler
reti ;jmp TIM3_COMPB ; Timer3 CompareB Handler
reti ;jmp TIM3_COMPC ; Timer3 CompareC Handler
reti ;jmp TIM3_OVF ; Timer3 Overflow Handler
jmp USART1_RXC ; USART1 RX Complete Handler
jmp USART1_UDRE ; USART1,UDR Empty Handler
jmp USART1_TXC ; USART1 TX Complete Handler
reti ;jmp TWI ; 2-wire Serial Handler
reti ;jmp SPM_RDY ; SPM Ready Handler
reti;jmp TIM4_CAPT ; Timer4 Capture Handler
reti;jmp TIM4_COMPA ; Timer4 CompareA Handler
reti;jmp TIM4_COMPB ; Timer4 CompareB Handler
reti;jmp TIM4_COMPC ; Timer4 CompareC Handler
reti;jmp TIM4_OVF ; Timer4 Overflow Handler
reti;jmp TIM5_CAPT ; Timer5 Capture Handler
reti;jmp TIM5_COMPA ; Timer5 CompareA Handler
reti;jmp TIM5_COMPB ; Timer5 CompareB Handler
reti;jmp TIM5_COMPC ; Timer5 CompareC Handler
reti;jmp TIM5_OVF ; Timer5 Overflow Handler
reti;jmp USART2_RXC ; USART2 RX Complete Handler
reti;jmp USART2_UDRE ; USART2,UDR Empty Handler
reti;jmp USART2_TXC ; USART2 TX Complete Handler
reti;jmp USART3_RXC ; USART3 RX Complete Handler
reti;jmp USART3_UDRE ; USART3,UDR Empty Handler
reti;jmp USART3_TXC ; USART3 TX Complete Handler

RESET:
ldi R16, low(RAMEND) ; ??????? ????? ?????? RAMEND
out SPL, R16 ; ????????????? SPL
ldi R16, high(RAMEND) ; ??????? ????? ?????? RAMEND
out SPH, R16 ; ????????????? SPH

uart_init:


.equ XTAL = 8000000
.equ baudrate = 9600
.equ bauddivider = XTAL/(16*baudrate)-1
.equ addr= 11
.equ Command = 0x03


LDI R16, low(bauddivider)
STS UBRR0L,R16
LDI R16, high(bauddivider)
STS UBRR0H,R16
LDI R16,0
STS UCSR0A, R16
LDI R16, (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(1<<TXCIE0)|(0<<UDRIE0)
STS UCSR0B, R16
LDI R16, (1<<UCSZ00)|(1<<UCSZ01)|(0<<UCSZ02)
STS UCSR0C, R16

LDI R16, low(bauddivider)
STS UBRR1L,R16
LDI R16, high(bauddivider)
STS UBRR1H,R16
LDI R16,0
STS UCSR1A, R16
LDI R16, (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(1<<TXCIE1)|(0<<UDRIE1)
STS UCSR1B, R16
LDI R16, (1<<UCSZ10)|(1<<UCSZ11)|(0<<UCSZ12)
STS UCSR1C, R16
main1:












ldi R16,1
sts UDR0,R16
sei
main:
sei
sbi DDRB,7
sbi PORTB,7
nop
rjmp main

USART1_RXC: ; USART RX Complete Handler
nop
cli
sbi DDRB,0
sbi PORTB,0
ldi R16,1
sts UDR0,R16
ret
USART1_UDRE: ; UDR Empty Handler
cli
sbi DDRB,1
sbi PORTB,1
ldi R16,1
sts UDR0,R16
nop
ret
USART1_TXC:
cli
sbi DDRB,2
sbi PORTB,2
ldi R16,1
sts UDR0,R16
ret
nop



USART0_RXC:
cli
sbi DDRB,0
sbi PORTB,0
ldi R16,2
sts UDR0,R16
ret
USART0_UDRE: ; USART0,UDR Empty Handler
cli
sbi DDRB,1
sbi PORTB,1
ldi R16,2
sts UDR0,R16
nop
ret
USART0_TXC:
cli
sbi DDRB,2
sbi PORTB,2
ldi R16,2
sts UDR0,R16
ret
nop



USART2_RXC:
cli
sbi DDRB,0
sbi PORTB,0
ldi R16,3
sts UDR0,R16
ret
USART2_UDRE: ; USART0,UDR Empty Handler
cli
sbi DDRB,1
sbi PORTB,1
ldi R16,3
sts UDR0,R16
nop
ret
USART2_TXC:
cli
sbi DDRB,2
sbi PORTB,2
ldi R16,3
sts UDR0,R16
ret
nop

Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 14 2014, 02:25
Сообщение #2


Гуру
******

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



Процедуры обработки прерываний, обычно, заканчивают своё выполнение командой RETI, а не RET
Go to the top of the page
 
+Quote Post
alexxack
сообщение Apr 14 2014, 02:45
Сообщение #3





Группа: Участник
Сообщений: 12
Регистрация: 26-06-13
Пользователь №: 77 280



Цитата(Палыч @ Apr 14 2014, 06:25) *
Процедуры обработки прерываний, обычно, заканчивают своё выполнение командой RETI, а не RET

Это несомненно так но как видно из текста выше обработчик переходит черт знает куда но только не по прерыванию т.е. порядка 5 векторов ниже нужного прерывания. Честно говоря я в замешательстве не когда не сталкивался с таким "глюком"

т.е. прерывание вызывается jmp USART0_RXC ; USART0 RX Complete Handler а обработчик переходит на вектор reti;jmp TIM4_COMPB ; Timer4 CompareB Handler.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 14 2014, 02:54
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(alexxack @ Apr 14 2014, 05:45) *
обработчик переходит черт знает куда но только не по прерыванию т.е. порядка 5 векторов ниже нужного прерывания.
Никаких чудес. Чтобы понять такое поведение ответьте на пару вопросов:
1) Сколько слов программной памяти занимает команда reti?
2) Сколько слов программной памяти отводится под один вектор в вашем контроллере?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alexxack
сообщение Apr 14 2014, 04:17
Сообщение #5





Группа: Участник
Сообщений: 12
Регистрация: 26-06-13
Пользователь №: 77 280



Цитата(Сергей Борщ @ Apr 14 2014, 06:54) *
Никаких чудес. Чтобы понять такое поведение ответьте на пару вопросов:
1) Сколько слов программной памяти занимает команда reti?
2) Сколько слов программной памяти отводится под один вектор в вашем контроллере?

Честно говоря некогда не задавался данным вопросом из имеющихся источников команда reti занимает 2 байта т.е 1 слово из даташита на Atmega1281 адресация векторов имеет вид $0000,$0002,$0004 т.е по всей видимости адресация занимает 2 слова т.е 4 байта ситуация начинает прояснятся но не до конца! Если не трудно разъясните пожалуйста пути решения.
Go to the top of the page
 
+Quote Post
__Alexander
сообщение Apr 14 2014, 04:50
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 76
Регистрация: 18-07-07
Из: Киев
Пользователь №: 29 202



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

.org 0x0048
rjmp USART1_RXC ; USART1 RX Complete Handler
Go to the top of the page
 
+Quote Post
alexxack
сообщение Apr 14 2014, 05:01
Сообщение #7





Группа: Участник
Сообщений: 12
Регистрация: 26-06-13
Пользователь №: 77 280



Цитата(__Alexander @ Apr 14 2014, 08:50) *
если быстро и тупо в лоб то расставьте адресе вручную. типа так

.org 0x0048
rjmp USART1_RXC ; USART1 RX Complete Handler


Большое спасибо только что попробовал помогло. Если не трудно разъясните суть (От привычки копать глубоко не могу избавиться)
запись вида
Код
reti;jmp TIM0_OVF; Timer0 Overflow Handler
reti;jmp SPI_STC; SPI Transfer Complete Handler
.ORG $0032
jmp USART0_RXC; USART0 RX Complete Handler
.ORG $0034
jmp USART0_UDRE; USART0,UDR Empty Handler
.ORG $0036
jmp USART0_TXC; USART0 TX Complete Handler
reti;jmp ANA_COMP; Analog Comparator Handler

помогла решить проблему. Хотелось бы разобраться дабы в дальнейшем не устраивать "танцы с бубном на граблях" или пните пожалуйста в сторону какой либо статейки дабы ознакомится. P.S. если не трудно.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 14 2014, 05:02
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(alexxack @ Apr 14 2014, 07:17) *
Если не трудно разъясните пожалуйста пути решения.

Вектора прибиты гвоздями к своим адресам. Как вы правильно поняли, каждый вектор занимает 2 слова. И пока вы на место вектора вставляете двухсловную команду jmp все красиво - следующая команда jmp попадает на свое правильное место. Как только вы вместо jmp поставили однословную reti - все следующие команды "поджались" и съехали на одно слово. То есть в вашем коде
Код
jmp RESET; Reset Handler
reti;jmp INT0; IRQ0 Handler
reti;jmp INT1; IRQ1 Handler
комментарий про IRQ1 Handler уже перестал соответствовать действительности. Вам надо принудительно указать, что вторая команда reti должна располагаться по адресу IRQ1 Handler. Я не использую ассемблер Студии и саму студию, поэтому не могу точно сказать, какая именно директива ее ассемблера отвечает за принудительное размещение по определенному адресу. Возможно это будет что-то вроде ".org адрес". Также во избежание путаницы адреса не нужно указывать цифрами - в заголовочном файле студии m1281def.inc этим адресам должны быть присвоены мнемонические (текстовые) имена. И ваш исходник должен выгладеть примерно так:
Код
    .org 0; имя для вектора сброса авторы m1281def.inc забыли
    jmp RESET
    .org INT0addr
    reti;jmp INT0
    .org INT1addr
    reti;jmp INT1
Как видите, комментарии в этом коде уже не нужны и замена любого jmp на reti или rjmp не повлияет на размещение следующих команд


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
__Alexander
сообщение Apr 14 2014, 05:06
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 76
Регистрация: 18-07-07
Из: Киев
Пользователь №: 29 202



Цитата(alexxack @ Apr 14 2014, 08:01) *
. Хотелось бы разобраться дабы в дальнейшем не устраивать "танцы с бубном на граблях" или пните пожалуйста в сторону какой либо статейки дабы ознакомится. P.S. если не трудно.


так тут разбираться особо в не в чем. никто не создает в файле эту таблицу. добавляют эти вектора по мере увеличения нужных прерываний. если у вас их три, то так и запишите только три (адрес+rjpm). Зачем вам та простыня?
Go to the top of the page
 
+Quote Post
alexxack
сообщение Apr 14 2014, 05:22
Сообщение #10





Группа: Участник
Сообщений: 12
Регистрация: 26-06-13
Пользователь №: 77 280



Большое спасибо всем за помощь 3 дня бился с данным вопросом не догадался копнуть в сторону адресации. Надеюсь данный топик окажется полезным начинающим.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 14 2014, 05:41
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(__Alexander @ Apr 14 2014, 08:06) *
Зачем вам та простыня?
Довольно распространенное заблуждение, что на неиспользуемый вектор надо поставить заглушку в виде reti. Типа если случайно это прерывание будет разрешено, то попав в него сразу вывалимся обратно и программа будет работать как ни в чем не бывало. Ну, во-первых лучше уж ставить загрушки в виде бесконечных циклов, чтобы программа зависла попав в этот цикл и автор начал разбираться, а почему она туда вообще попала и устранил ошибку. А во-вторых далеко не у всех прерываний флаг сбрасывается просто от перехода по вектору прерывания, часто для его сброса надо прочитать какой-то регистр, а без этого чтения выполнив reti программа на следующей команде снова влетит в этот же обработчик. И отловить такие внезапно наступающие тормоза уже сложнее.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


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


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