Страница 1 из 1

Не работают прерывания в UART

Добавлено: Чт окт 30, 2008 13:30:36
Nash
Помогите пожалуйста, не могу понять, почему не вызывается прерывание по окончанию передачи UART

rjmp main ; External Reset, Power-on Reset and Watchdog Reset
nop ; External Interrupt Request 0
nop ; External Interrupt Request 1
nop ; Timer/Counter 1 Capture Event
nop ; Timer/Counter 1 Compare Match
nop ; Timer/Counter 1 Overflow
nop ; Timer/Counter 0 Overflow
nop ; UART, Rx complete
nop ; UART Data Register Empty
rjmp trans ; UART, TX complete
nop ; Analog Comparator

main:
ldi r16, ramend
out spl, r16
ldi r16, 0b11011000
out ucr, r16
ldi r16, 25
out ubrr,r16
sei
loop:
sbis USR,5
rjmp loop
; Передача байта (число 9)
ldi r16, 9
out udr, r16
rjmp loop

trans:
; прерывание почему-то не выполняется ?????
reti

Добавлено: Чт окт 30, 2008 13:51:25
Foks
Или мне кажется, или на каждое прерывание нужно два NOP'а. А еще лучше использовать .org с константами адресов прерываний. Они определены в инклюдах асма, по крайней мере в AVR Studio.

Для включения глобального флага разрешения прерываний после main: нужно написать:
bset 7

И еще: скажите, какой у Вас микроконтроллер, чтоб мы не гадали.

Добавлено: Чт окт 30, 2008 14:03:24
Pooher
Не плохо было бы указать какой контроллер :)
Попробуй так:
(для Tiny2313)
reset:
rjmp main
reti ; Addr $01
reti ; Addr $02
reti ; Addr $03
reti ; Addr $04
reti ; Addr $05
reti ; Addr $06 Use 'rjmp myVector'
reti ; Addr $07 to define a interrupt vector
reti ; Addr $08
rjmp trans ; Addr $09
reti ; Addr $0A
reti ; Addr $0B This is just an example
reti ; Addr $0C Not all MCUs have the same
reti ; Addr $0D number of interrupt vectors
reti ; Addr $0E
reti ; Addr $0F
reti ; Addr $10

; Program starts here after Reset
;
main:
ldi r16, ramend
out spl, r16

ldi r16, 25
out ubrr,r16
ldi r16, 0b11011000
out ucr, r16
sei
loop:
sbis USR,5
rjmp loop

rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay


ldi r16, 9
out udr, r16

rjmp loop

trans:
;
reti

delay:
ldi temp,0xff
d1:
dec temp
cpi temp, 0
brne d1
ret

То, что регистр данных UDR пуст, ещё совсем не значит, что передача закончена.

Добавлено: Чт окт 30, 2008 14:05:02
tych
Foks писал(а):Для включения глобального флага разрешения прерываний после main: нужно написать:
bset 7
А написаного не достаточно ?

Добавлено: Чт окт 30, 2008 14:40:39
Nash
Микроконтроллер AT90S2313

Добавлено: Чт окт 30, 2008 14:45:40
BerZerK-ku
Настройки не смотрел. Достаточно вот этого куска кода :

Код: Выделить всё

rjmp loop
; Передача байта (число 9)
ldi r16, 9
out udr, r16
rjmp loop 
Он не даст выставить флаг завершения передачи TXC, соответственно не будет вызвано и прерывание по завершению передачи. Данный флаг устанавливается в "1" после передачи всех разрядов посылки из сдвигового регистра передатчика, при условии, что в регистр данных UDR не было загружено нового значения.
Кидайте первый байт в udr из основной программы. А последующие байты посылки - по прерыванию "Опустошение регистра данных".

Добавлено: Чт окт 30, 2008 15:27:47
Pooher
что значит:
Он не даст выставить флаг завершения передачи TXC
?
Проблема здесь только в том, что новое значение в UDR загружается сразу после установки флага опустошения,
loop:
sbis USR,5
rjmp loop
а он в свою очередь устанавливается раньше(что в полне закономерно), чем флаг завершения передачи, т.к. для завершения передачи опустошения UDR явно недостаточно.
[/code]

Добавлено: Чт окт 30, 2008 18:35:47
Nash
Подправьте пожалуйста код как правильно... а то запутался совсем :shock:

Re: Не работают прерывания в UART

Добавлено: Пт окт 31, 2008 06:33:19
Старый Бабай
Nash писал(а):Помогите пожалуйста, не могу понять, почему не вызывается прерывание по окончанию передачи UART

rjmp main ; External Reset, Power-on Reset and Watchdog Reset
nop ; External Interrupt Request 0
nop ; External Interrupt Request 1
nop ; Timer/Counter 1 Capture Event
nop ; Timer/Counter 1 Compare Match
nop ; Timer/Counter 1 Overflow
nop ; Timer/Counter 0 Overflow
nop ; UART, Rx complete
nop ; UART Data Register Empty
rjmp trans ; UART, TX complete
nop ; Analog Comparator

main:
ldi r16, ramend
out spl, r16
ldi r16, 0b11011000
out ucr, r16
ldi r16, 25
out ubrr,r16
sei
loop:
sbis USR,5
rjmp loop
; Передача байта (число 9)
ldi r16, 9
out udr, r16
rjmp loop

trans:
; прерывание почему-то не выполняется ?????
reti
Давайте смотреть инициализацию UARTa

Код: Выделить всё

ldi r16, 0b11011000
out ucr, r16
ldi r16, 25
out ubrr,r16
Идет установка битов
RXCIE - разрешение прерывания по ЗАВЕРШЕНИЮ ПРИЕМА
TXCIE - разрешение прерывания по ЗАВЕРШЕНИЮ ПЕРЕДАЧИ
RXEN - разрешение приема
TXEN - разрешение передачи

Вроде все понятно...
Но где тогда обработчик прерывания ПО ПРИЕМУ СИМВОЛА?
И самое важное ФЛАГ TXC будет выставлен тогда когда данные переданы и в UDR ничего больше не пишется...
А у вас запись в UDR идет постояно в цикле

Данный код вызовет срабатывание прерывания один раз

Код: Выделить всё


       sei 
;loop: 
;sbis USR,5 
;rjmp loop 
; Передача байта (число 9) 
      ldi r16, 9 
      out udr, r16 
;rjmp loop 
main:
      nop
      rjmp main


Добавлено: Пт окт 31, 2008 11:46:15
Pooher
Код рабочий я уже писал выше.
После установки флага опустошения UDR

Код: Выделить всё

loop:
sbis USR,5
rjmp loop 
надо выдержать паузу
(1 MHz - порядка 14 ms)

Код: Выделить всё

rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay
rcall delay 
и всё будет работать!

Добавлено: Пт окт 31, 2008 12:30:04
Jotto
Pooher, я прошу прощенья, за ваш код (совет) с паузами надо отстреливать все пальцы... это я как программист-программисту, ничего личного.

Добавлено: Пт окт 31, 2008 12:44:32
Pooher
за ваш код (совет) с паузами надо отстреливать все пальцы
Ну, как программист программиста я ,конечно, вас понимаю.:)
Но на мой взгляд, при объяснении человеку принципа работы чего-либо,
совсем не стоит лезть в какие то дебри, гораздо лучше и понятнее показать всё "на пальцах", которые Вы так яростно стремитесь мне ОТСТРЕЛИТЬ. Да ещё и все.
И вообще, не нравится, предложите свой вариант.
Объяснять нужно людям, а не мозги засе..ть.

Добавлено: Пт окт 31, 2008 13:05:17
Старый Бабай
Слушайте какие "ПАЛЪЦЫ".
На At90S2113 даташит давным давно переведен на русский.
Единствено в тхт файле , а непэдэфка..
Так что надо читать внимательно...
Не понятно прочитать еще раз...
Лпять не понятно - опять читаем

И если вы разрешаете прерывание по ОКОНЧАНИЕ ПЕРЕДАЧИ БАЙТА, то не надо слать байты в цикле постояно. Тогда и задержки не понадобятся :))

Добавлено: Пт окт 31, 2008 13:19:06
Pooher
И если вы разрешаете прерывание по ОКОНЧАНИЕ ПЕРЕДАЧИ БАЙТА, то не надо слать байты в цикле постояно. Тогда и задержки не понадобятся
Ну как поспорить :))

Добавлено: Пт окт 31, 2008 13:36:25
Старый Бабай
Мож прежде чем спорить тогда выдержду из даташита приведем здесь.
Тогда и спорить не придется :)) :)

Добавлено: Пт окт 31, 2008 15:15:18
Jotto
Pooher писал(а):Ну, как программист программиста я ,конечно, вас понимаю.:)
Но на мой взгляд, при объяснении человеку принципа работы чего-либо,
совсем не стоит лезть в какие то дебри, гораздо лучше и понятнее показать всё "на пальцах", которые Вы так яростно стремитесь мне ОТСТРЕЛИТЬ. Да ещё и все.
И вообще, не нравится, предложите свой вариант.
Объяснять нужно людям, а не мозги засе..ть.
Ну я не стремлюсь... отстрелить... но!
Если вы, как программист, понимаете, то зачем предлагать КОНЦЕПТУАЛЬНО НЕВЕРНОЕ решение (даже представим, что оно будет работать) Потому что: при применении механизма прерываний нужно использовать именно этот механизм, при применении механизма флагов нужно ожидать флаги. Всевозможные примочки типа задержек уместны лишь в определенных ситуациях и никак, в данном случае с асинхронным портом, они неприменимы. Поэтому, что-бы на пальцах объяснить и не лезть в дебри, нужно написать правильно. Или не писать. Поэтому я не пишу тут кода, потому что ASM не мой профиль. Но не предостеречь от "индо-пакистанского" кода не могу.

Добавлено: Пт окт 31, 2008 17:05:36
Pooher
Jotto писал(а):
Pooher писал(а):Ну, как программист программиста я ,конечно, вас понимаю.:)
Но на мой взгляд, при объяснении человеку принципа работы чего-либо,
совсем не стоит лезть в какие то дебри, гораздо лучше и понятнее показать всё "на пальцах", которые Вы так яростно стремитесь мне ОТСТРЕЛИТЬ. Да ещё и все.
И вообще, не нравится, предложите свой вариант.
Объяснять нужно людям, а не мозги засе..ть.
Ну я не стремлюсь... отстрелить... но!
Если вы, как программист, понимаете, то зачем предлагать КОНЦЕПТУАЛЬНО НЕВЕРНОЕ решение (даже представим, что оно будет работать) Потому что: при применении механизма прерываний нужно использовать именно этот механизм, при применении механизма флагов нужно ожидать флаги. Всевозможные примочки типа задержек уместны лишь в определенных ситуациях и никак, в данном случае с асинхронным портом, они неприменимы. Поэтому, что-бы на пальцах объяснить и не лезть в дебри, нужно написать правильно. Или не писать. Поэтому я не пишу тут кода, потому что ASM не мой профиль. Но не предостеречь от "индо-пакистанского" кода не могу.
Не могу с этим не согласиться, но я считаю, что лучше в качестве примера показать в каком-то смысле "неверный" код, который визуально и интуитивно понятно иллюстрирует ПРОЦЕССЫ, которые происходят, а не выкладывать сложный для понимания "правильный" код, который в конечном счёте может окончательно закипятить человеку мозги. Ведь если он возьмёт кусок кода и начнёт его впихивать в приложение, то есть 2 варианта: или он окончательно запутается, или у него всё получится, но и в том и в другом случае мы ему совсем даже не поможем, как может показаться, а как раз наоборот.
Ведь для полноценного понимания того, что ты делаешь, надо самому искать пути решения проблемы, а не пользоваться готовыми , тем более, что в данной ситуации ВЫХОД обозначен жирной стрелкой.

Добавлено: Пт окт 31, 2008 18:11:07
Jotto
Pooher писал(а):... но я считаю, что лучше в качестве примера показать в каком-то смысле "неверный" код, который визуально и интуитивно понятно иллюстрирует ПРОЦЕССЫ, которые происходят, а не выкладывать сложный для понимания "правильный" код...
А вот я тут не соглашусь. Иллюстрировать процессы можно (и нужно) вербально. Сграфиками, диаграммами, с чем угодно, даже с верным кодом, который вдумчивый ученик проанализирует. А "неверный" код приведет вот к чему: человек схватит идею (а багажа других знаний по теме нет) поэтому отпечатается некая "аксиома" или "шаблон", который, весьма возможно, скопируется в другие места, потом разработчик поднимает частоту кристалла, скорость порта... и... вуаля, такой "прекрасный" код, который работал - перестал. Кстати, rcall delay позволяет внутри себя прерывания?

Добавлено: Сб ноя 01, 2008 10:04:44
Pooher
Jotto писал(а):Кстати, rcall delay позволяет внутри себя прерывания?
Ну чтот я там в циклях CLI не наблюдаю :))