Полная версия этой страницы:
UART не запскается
Slavast
Nov 2 2010, 11:08
Доброе время суток.
Прописываю работу USART на Atmega2561 и не работает команда SBIS во вседавно известном цикле отправке байта.
; Процедура отправки байта
uart_snt: SBIS UCSRA,UDRE ; Пропуск если нет флага готовности
RJMP uart_snt ; ждем готовности - флага UDRE
OUT UDR, R16 ; шлем байт
RET ; Возврат
Выдает ошибку:
D:\Slava\Atmel\Projects\UART1\UART1.asm(67): error: Operand 1 out of range: 0xc0
Подскажите что делать?
Цитата(Slavast @ Nov 2 2010, 14:08)

Выдает ошибку:
D:\Slava\Atmel\Projects\UART1\UART1.asm(67): error: Operand 1 out of range: 0xc0
Подскажите что делать?
Ну сколько уже раз говорено (и в даташите, кстати, есть, хоть и невнятно, в сносках к примерам с sbis/sbic) - раз регистры UART недоступны по in/out/sbi/cbi/sbis/sbic, используйте lds/sts. Ну да, рабочий регистр потребуется...
Цитата(Slavast @ Nov 2 2010, 14:08)

Доброе время суток.
Подскажите что делать?
Uart_snt:
lds temp, UCSRA
sbis temp,UDRE
rjmp Uart_snt
Slavast
Nov 2 2010, 11:18
Аа!
Век учись - на свои же грабли наступай!
Спасибо огромное!
Цитата(Slavast @ Nov 2 2010, 14:18)

Аа!
Век учись - на свои же грабли наступай!
Спасибо огромное!
И учитывайте , что первый байт , проскакивает сразу в сдвиговый регистр и только 2-ой "задерживается" в буфере. Это к тому, что если после отсылки первго , Вам надо что-то принять.
Slavast
Nov 2 2010, 11:30
Цитата(ILYAUL @ Nov 2 2010, 15:27)

И учитывайте , что первый байт , проскакивает сразу в сдвиговый регистр и только 2-ой "задерживается" в буфере. Это к тому, что если после отсылки первго , Вам надо что-то принять.
В смысле - если я после отсылки первого байта ничего не приму, то я не увижу свой изначально отправленный байт?
Цитата(Slavast @ Nov 2 2010, 14:30)

В смысле - если я после отсылки первого байта ничего не приму, то я не увижу свой изначально отправленный байт?
Всё зависит от Вашей скорости пердачи и приёма информации и Вашей программы . Т.е успеваете Вы переключатся между приёмом и передачей
Slavast
Nov 3 2010, 08:42
Подскажите: в UBRR0H и UBRR0H надозаписать Baudrate для UARTa. А в какой из них записывать конкретно не написано. Что делать?
• Bit 11:0 – UBRR11:0: USART Baud Rate Register
This is a 12-bit register which contains the USART baud rate. The UBRRH contains the four
most significant bits, and the UBRRL contains the eight least significant bits of the USART baud
rate. Ongoing transmissions by the Transmitter and Receiver will be corrupted if the baud rate is
changed. Writing UBRRL will trigger an immediate update of the baud rate prescaler.
Цитата(Slavast @ Nov 3 2010, 11:42)

Подскажите: в UBRR0H и UBRR0H надозаписать Baudrate для UARTa. А в какой из них записывать конкретно не написано. Что делать?
Там же все черным по белому сказано - 12-разрядный, в UBRR0H старшие четыре (остальные незначащие, нули), в UBRR0L - младшие восемь. Первым должен записываться старший, после записи младшего будут обновлены оба регистра.
Slavast
Nov 3 2010, 09:43
Т.е чтоб настроить UART на Baudrate = 115200
мне надо записать
ldi R16, 0x08 ; Baudrate = 115200
sts UBRR0H,R16 ;
ldi R16, 0x00 ;
sts UBRR0L,R16 ;
Т.е. мое число попадет получается только в UBBR0H? а в UBRR0L - попадет 0x00?
Так что ли?
Цитата(Slavast @ Nov 3 2010, 11:42)

Что делать?
Обратите внимание, что важен порядок записи в эти регистры: сначала старшую часть - в UBRR0H; затем младшую - в UBRR0L. Если программируете на С, то можно со всем этим не заморачиваться: оба этих регистра (старшая часть делителя и младший байт) объединены в один, который имеет идентификатор UBRR0. При этом запись делителя DIVISOR в регистры UBRR0H и UBRR0L с нужным порядком сделает за Вас транслятор:
Код
UBRR0= DIVISOR;
Цитата(Slavast @ Nov 3 2010, 12:43)

Т.е. мое число попадет получается только в UBBR0H? а в UBRR0L - попадет 0x00?
Так что ли?
Нет, конечно. Делитель для 115200 (при тактовой 7.3728 MHz и U2X) равен 7 (а не 8 !). Соответственно, в UBRR0L должно быть записано 7, а в UBRR0H - 0 (в старший байт обычно ноль, за исключением совсем низких скоростей).
Slavast
Nov 3 2010, 10:01
Я работаю на ATmega 2561 с 16 Мгц частотой и U2X=0.
Высчитал вроде Baudrate=8.
А что вначале записывать - UBRR0H или UBRR0L? Есть принципиальное отдичие?
Сергей Борщ
Nov 3 2010, 10:12
Цитата(Slavast @ Nov 3 2010, 13:01)

А что вначале записывать - UBRR0H или UBRR0L? Есть принципиальное отдичие?
Вот интересно, вы ответы принципиально не читаете?
Цитата(rx3apf @ Nov 3 2010, 12:01)

Первым должен записываться старший, после записи младшего будут обновлены оба регистра.
Цитата(Палыч @ Nov 3 2010, 12:46)

Обратите внимание, что важен порядок записи в эти регистры: сначала старшую часть - в UBRR0H; затем младшую - в UBRR0L.
demiurg_spb
Nov 3 2010, 10:37
Чукча не читатель, Чукча - писатель:-)
Цитата(Slavast @ Nov 3 2010, 13:01)

Я работаю на ATmega 2561 с 16 Мгц частотой и U2X=0.
Высчитал вроде Baudrate=8.
А, Вы высчитали: какая при этом ошибка скорости передачи получается? Это может быть важным. При Ваших данных ошибка -3,5%. Чтобы скорость USART получалась без ошибок используют тактовую 14.7456МГц или 11.0592МГц.
Slavast
Nov 3 2010, 12:08
Да, спасибо!
Цитата(Палыч @ Nov 3 2010, 13:44)

А, Вы высчитали: какая при этом ошибка скорости передачи получается? Это может быть важным. При Ваших данных ошибка -3,5%. Чтобы скорость USART получалась без ошибок используют тактовую 14.7456МГц или 11.0592МГц.
Как же я могу поменять частоту процессора микроконтроллера Atmega 2561 16Мгц ?
Выбирая не 16 Мгц, а 14.7456МГц или 11.0592МГц не будет работать, т.к. тактовая часота процессора МК Atmega 2561 16 МГц.?
Цитата(Slavast @ Nov 3 2010, 15:08)

Выбирая не 16 Мгц, а 14.7456МГц или 11.0592МГц не будет работать, т.к. тактовая часота процессора МК Atmega 2561 16 МГц.?
При 5В питания тактовая частота не должна превышать 16МГц. Конкретное значение выбирается из всяких-разных условий: напряжение питания, потребляемый ток, необходимое быстродействие и др.
Slavast
Nov 5 2010, 09:02
UART заработал!!
Но теперь вместо одного символа контроллер Atmega 2561 выводит мне в терминал бесконечный цикл этих символов. Без главного цикла все равно выводит миллион повторений того, что я нажму.
Вопрос - нужно ли здесь прерывания и какой их тогда будет смысл?
Заранее, низкий поклон!!
Главная программа у меня вот:
;-------Посылка байта----------
uart_rcv: lds r19, UCSR0A
SBRS r19,UDRE0 ; Пропуск если нет флага готовности,
RJMP uart_rcv ; вращаясь в цикле
lds R16,UDR0 ; байт пришел - забираем.
RET ; Выходим. Результат в R16
;-------Процедура отправки байта-------
uart_snt: lds r17, UCSR0A
SBRS r17,UDRE0 ; Пропуск если нет флага готовности,
; если 1 - то готов отправлять данные
RJMP uart_snt ; ждем готовности - флага UDRE
sts UDR0, R16 ; шлем байт 01010101 в UDR
RET ; Возврат
;------ Главный цикл --------
Main:
RCALL uart_rcv ; Ждем байта
INC R16 ; Делаем с ним что-то
RCALL uart_snt ; Отправляем обратно.
out PORTB, r18
JMP Main
На приём надо проверять бит RXC0, а вы проверяете UDRE0 и на приём, и на передачу.
Slavast
Nov 5 2010, 09:51
Цитата(=GM= @ Nov 5 2010, 12:41)

На приём надо проверять бит RXC0, а вы проверяете UDRE0 и на приём, и на передачу.
АААА!!!!
РАБОТАААААЕТТТТ!)!)!)!)!))!)!
Урааааааа!))))))
Огромный респект =GM=!!!!
На здоровье.
Ну и r18 у вас в main не определён. Повнимательнее будьте.
Slavast
Nov 5 2010, 11:54
А кто-нибудь знает, как в Ассемблере через UART вывести целую строку символов? Например фразу "Привет". Как определить символьный тип данных на переменную?
Спасибо.
Код
ldi xl, low (2*message1)
ldi xh, high (2*message1)
next1:
ld R16, x+
tst R16
breq end_sent1
rcall uart_snt
rjmp next1
message1:
.db "Привет!", 0
end_sent1:
nop
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.