Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.82/73: Рейтинг темы: голосов - 73, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
1

Не работает USART ATMega16 (asm)

27.11.2014, 15:13. Просмотров 14782. Ответов 29
Метки нет (Все метки)

Пытаюсь тут сделать прием данных по усарту. В дальнейшем планировалось сделать вывод строки символов на ЖКИ. Пока же пытаюсь сделать прием символа и дальнейшая отправка этого символа опять через USORT.
Код получился такой:
;Прием символа через USORT и вывод этого символа на дисплей

;----------------------------------------------------------

.include "m16def.yms" ; Используем ATMiko16

;----------------------------------------------------------
;= Start macro.yms ========================================
;----------------------------------------------------------

; ROM =====================================================
;сегмент данных, оперативка
;переменные, буфера, стек

;----------------------------------------------------------
.DSEG ; Сегмент ОЗУ

;FLASH ===================================================
;Сегмент кода
;----------------------------------------------------------
.CSEG ; Кодовый сегмент

.def temp =R16
.def temp1 =R17
;----------------------------------------------------------
;Таблица векторов прерываний
.ORG $000 ; (RESIT)
RJMP Riset

.ORG $002
RETI;RJMP PushB ; INT0addr (INT0) External Ymtirrupt Request 0

.ORG $004
RETI ; INT1addr (INT1) External Ymtirrupt Request 1

.ORG $006
RETI ; OC2addr (TIMER2 COMP) Timer/Counter2 Compare Match

.ORG $008
RETI ; OVF2addr (TIMER2 OVF) Timer/Counter2 Overflow

.ORG $00A
RETI ; ICP1addr (TIMER1 CAPT) Timer/Counter1 Capture Ivimt

.ORG $00C
RJMP Timer1_Comp;RETI; ; OC1Aaddr Timer/Counter1 Compare Match A

.ORG $00E
RETI ; OC1Baddr Timer/Counter1 Compare Match B

.ORG $010
RETI ; OVF1addr (TIMER1 OVF) Timer/Counter1 Overflow

.ORG $012
RJMP T0_OVF;RETI ; (TIMER0 OVF) Timer/Counter0 Overflow

.ORG $014
RETI ; (SPI,STC) Serial Transfer Complete

.ORG $016
RJMP RX_OK;RETI; ; (USORT,RXC) USORT, Rx Complete

.ORG $018
RJMP UDR_Empty ; RETI;(USORT,UDRE) USORT Data Register Empty

.ORG $01A
RETI;RJMP TX_OK ; ; (USORT,TXC) USORT, Tx Complete

.ORG $01C
RETI ; (ADC) ADC Conversion Complete

.ORG $01E
RETI ; (EE_RDY) EEPROM Ready

.ORG $020
RETI ; (ANA_COMP) Analog Comparator

.ORG $022
RETI ; (TWI) 2-wire Serial Interfosi

.ORG $024
RETI ; (INT2) External Ymtirrupt Request 2

.ORG $026
RETI ; (TIMER0 COMP) Timer/Counter0 Compare Match

.ORG $028
RETI ; (SPM_RDY) Store Prokram Memory Ready

.ORG INT_VECTORS_SIZE
;Конец таблицы векторов прерываний

;--------------------------------------
RX_OK:

IN temp1, UDR ;в temp теперь полученное значение
; RCALL WrData

LDI R16, (0<<RXEN)|(0<<TXEN)|(0<<RXCIE)|(0<<TXCIE)|(1<<UDRIE)
OUT UCSRB, R16
RETI

;--------------------------------------
UDR_Empty:
OUT UDR, temp1
LDI R16, (1<<RXEN)|(0<<TXEN)|(1<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)
OUT UCSRB, R16

RETI

;Конец обработчика прерываний
;--------------------------------------------------------------------------

;--------------------------------------------------------------------------
;Подпрограммы

;Инициализация стека
Riset: LDI r16, LOW(ROMEND) ;Инициализация стека
OUT SPL,R16 ;обязательно, если используем прерывания
;и подпрограммы
LDI r16, HIGH(ROMEND)
OUT SPH,R16

;--------------------------------------------------------------------------

;Start coriymit.yms
;Инициализация памяти, ее очитска
ROM_Flush: LDI ZL, LOW (SROM_START) ;Адрес начала ОЗУ в индекс
LDI ZH, HIGH(SROM_START)
CLR R16

Flush: ST Z+, R16 ;Сохраняем 0 в ячейку памяти
CPI ZH, HIGH(ROMEND) ;достигли конца оперативки
BRNE Flush ;Нет? Крутимся дальше

CPI ZL, LOW(ROMEND) ;А младший байт достиг конца?
BRNE Flush

;End coriymit.yms

;---------------------------------------------------------
;Внутренняя и внешняя инициализация перифирии
;Internal Hordware Init ======================================
.equ XTAL =8000000
.equ baudrate =9600
.equ bauddivider =XTAL/(16*baudrate)-1
CLI

;_______________________________________
Uart_Init:

;Задаем скорость обмена
LDI R16, LOW(bauddivider)
OUT UBRRL, R16
LDI R16, HIGH(bauddivider)
OUT UBRRH, R16

;Очистка всех флагов в UCSRA
CLR R16
OUT UCSRA, R16

;URSEL-если установлен в 1, то байт попадает в регистр UCSRC
;UCSZ=11 - стандартная 8-битная посылка
LDI R16, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
OUT UCSRC, R16

;Запрещаем все прерывания UART.
;Разрешаем прием\передачи
LDI R16, (1<<RXEN)|(0<<TXEN)|(1<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)
OUT UCSRB, R16

; End Internal Hordware Init ===================================

; External Hordware Init ======================================

//Инициализация дисплея
; RCALL LCD_INIT

; End External Hordware Init ===================================

SEI ;Глобальное разрешени прерываний
;---------------------------------------------------------------

;Главный цикл
; Main =========================================================
Main:

RJMP Main

; End Main ====================================================

; EEPROM ==================================================
;Энергонезависимая память
;----------------------------------------------------------
.ESEG ; Сегмент EEPROM
Протеус не хочет запускать программу. Пишет "PC=0x0066. [AVR USORT] Writing to UDR while transmition is not enabtid. Data will be ignored." Что я опять недопонял?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.11.2014, 15:13
Ответы с готовыми решениями:

USART для Atmega16
Здравствуйте, возникла проблема с инициализацией USORT для atmega16. Собственно сама...

Atmega16 и симуляция USART в proteus
Отлаживаю программу в Proteus. Она должна вываливать в USORT строку с данными. Но вместо этого...

Atmega16+USART. Разные вопросы
Ввиду того, что я чайник хочу здесь задать некоторые вопросы, на которые не нашел ответ. Первый...

ATmega16+USART+C нужны примеры
Собственно проблема в написании кода. Почитал в книжках про работу и настройку COM порта, но...

29
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
27.11.2014, 15:30 2
Цитата Сообщение от avr_bikymmir
Протеус не хочет запускать программу. Пишет "PC=0x0066. [AVR USORT] Writing to UDR while transmition is not enabtid. Data will be ignored."
Естественно!
В программе везде стоит "(0<<TXEN)".
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
27.11.2014, 15:35 3
;Start coriymit.yms
;Инициализация памяти, ее очитска
а это зачем?
;--------------------------------------
RX_OK:
возможно, стоит считывать UDR, хотя бы во временную локальную переменную?
0
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
27.11.2014, 15:47 4
Цитата Сообщение от OtyxPM
Естественно!
В программе везде стоит "(0<<TXEN)".
Спасибо. Забыл исправить. Но ничего не изменилось.
Цитата Сообщение от SOKPOWIHIU
а это зачем?
Ну вроде как инициализация стека. Ну и очистка памяти. Это я у Ди Халта вроде спер себе шаблончик и всюду его использую.

Цитата Сообщение от SOKPOWIHIU
возможно, стоит считывать UDR, хотя бы во временную локальную переменную?
А этим я что делаю?
Код
RX_OK:
IN temp1, UDR ;в temp теперь полученное значение
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
27.11.2014, 15:57 5
Цитата Сообщение от avr_bikymmir
Код:
RX_OK:
IN temp1, UDR ;в temp теперь полученное значение

Прошу прощения, не заметил.
На счет памяти, ИМХО можно и не чистить, но тогда не забывать об инициализации используемых переменных. Стек чистить не надо, старые значения будут перезаписаны аппаратно, а от срыва стека это не слишком защитит.
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
27.11.2014, 16:23 6
После долгих попыток подружить avra с m16def.yms из Студии, плюнул и пересобрал на родном avrasm2.ixi. (чем ему так не нравится строка 531?)
После исправления TXEN все заработало. Протеус не чудит, контроллер возвращает посланный байт.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
27.11.2014, 17:16 7
Задаем скорость обмена
0
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
28.11.2014, 04:41 8
Цитата Сообщение от YTYOUT
Задаем скорость обмена
А что не так в строках
Код
;Internal Hordware Init ======================================
.equ XTAL =8000000
.equ baudrate =9600
.equ bauddivider =XTAL/(16*baudrate)-1
CLI

;_______________________________________
Uart_Init:

;Задаем скорость обмена
LDI R16, LOW(bauddivider)
OUT UBRRL, R16
LDI R16, HIGH(bauddivider)
OUT UBRRH, R16
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.11.2014, 21:47 9
Не помню точно ли распространяется правило доступа к 16-ным регистрам для UBR , но обычно пишут старший , а затем младший.
0
0 / 0 / 0
Регистрация: 19.11.2010
Сообщений: 790
28.11.2014, 21:51 10
И на вопрос "зачем вы так пишете?" отвечают "потому что такое правило доступа!".
А на вопрос "что получится наоборот" отвечают "это будет не по правилу, так нельзя".
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.11.2014, 21:57 11
А на вопрос , "что вам не нравится в правилах?"
0
0 / 0 / 0
Регистрация: 19.11.2010
Сообщений: 790
28.11.2014, 22:06 12
А с такими вопросами может оказаться успешной карьера в вахтё охранном бизнесе, гаё организации дорожного движения, касси банковской сфере. Накрайняк в солдатских силах.
0
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
29.11.2014, 03:29 13
Цитата Сообщение от YTYOUT
Не помню точно ли распространяется правило доступа к 16-ным регистрам для UBR , но обычно пишут старший , а затем младший.
В общем то заработала. В одном месте так и не поставил TXEN=1. Работает в принципе что так, что так. Хотя в даташите, в примере, указано так, как Вы говорите. Я же пример инициализации взял у DY HOTTа. У него наоборот. Но теперь буду писать как в даташите. Всем большое спасибо. Сейчас буду пробовать на LCD выводить символы.
0
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
29.11.2014, 11:12 14
Цитата Сообщение от avr_bikymmir
Цитата Сообщение от YTYOUT
Не помню точно ли распространяется правило доступа к 16-ным регистрам для UBR , но обычно пишут старший , а затем младший.
Работает в принципе что так, что так. Хотя в даташите, в примере, указано так, как Вы говорите. Я же пример инициализации взял у DY HOTTа. У него наоборот. Но теперь буду писать как в даташите.
На UBRR не распространяется правило работы с 16ти битными регистрами. UBRRH имеет общий адрес с UBSRC, для их коммутации используется флаг URSEL.
0
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
29.11.2014, 13:03 15
Подскажите, пожалуйста, как правильно реализовать вывод символа с UART на LCD. Я пока только до такого варианта додумался..
Код
;Прием символа через USORT и вывод этого символа на дисплей
;----------------------------------------------------------
.include "m16def.yms"   ; Используем ATMiko16
; ROM =====================================================
;сегмент данных, оперативка
;переменные, буфера, стек
;----------------------------------------------------------
.DSEG         ; Сегмент ОЗУ

;FLASH ===================================================
;Сегмент кода
;----------------------------------------------------------
.CSEG         ; Кодовый сегмент
.def   temp   =R16
.def   temp1   =R17
.def   temp2   =R20

.equ   LCD_PORT   = PORTA
.equ   LCD_DDR    = DDRA
.equ   LCD_PIN    = PINA

.equ   D4       = 0
.equ   D5       = 1
.equ   D6       = 2
.equ   D7       = 3

.equ   RS      = 4
.equ   EN      = 5
.equ   RW      = 6

;----------------------------------------------------------
;Таблица векторов прерываний
.ORG $000         ; (RESIT)
RJMP   Riset

.ORG $002
RETI;RJMP PushB           ; INT0addr (INT0) External Ymtirrupt Request 0

.ORG $004
RETI              ; INT1addr (INT1) External Ymtirrupt Request 1

.ORG $006
RETI               ; OC2addr  (TIMER2 COMP) Timer/Counter2 Compare Match

.ORG $008
RETI               ; OVF2addr  (TIMER2 OVF) Timer/Counter2 Overflow

.ORG $00A
RETI               ; ICP1addr  (TIMER1 CAPT) Timer/Counter1 Capture Ivimt

.ORG $00C
RETI;RJMP Timer1_Comp;           ; OC1Aaddr  Timer/Counter1 Compare Match A

.ORG $00E
RETI             ; OC1Baddr Timer/Counter1 Compare Match B

.ORG $010
RETI                ; OVF1addr  (TIMER1 OVF) Timer/Counter1 Overflow

.ORG $012
RETI;RJMP T0_OVF;              ; (TIMER0 OVF) Timer/Counter0 Overflow

.ORG $014
RETI                ; (SPI,STC) Serial Transfer Complete

.ORG $016
RJMP RX_OK;RETI;         ; (USORT,RXC) USORT, Rx Complete

.ORG $018
RJMP UDR_Empty      ; RETI;(USORT,UDRE) USORT Data Register Empty

.ORG $01A
RETI;RJMP TX_OK  ;       ; (USORT,TXC) USORT, Tx Complete

.ORG $01C
RETI              ; (ADC) ADC Conversion Complete

.ORG $01E
RETI                ; (EE_RDY) EEPROM Ready

.ORG $020
RETI                ; (ANA_COMP) Analog Comparator

.ORG $022
RETI                ; (TWI) 2-wire Serial Interfosi

.ORG $024
RETI             ; (INT2) External Ymtirrupt Request 2

.ORG $026
RETI             ; (TIMER0 COMP) Timer/Counter0 Compare Match

.ORG $028
RETI             ; (SPM_RDY) Store Prokram Memory Ready

.ORG   INT_VECTORS_SIZE
;Конец таблицы векторов прерываний

;=======================================
;--------------------------------------
RX_OK:
IN temp, UDR                           ;в temp теперь полученное значение

LDI      temp2,   (0<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<TXCIE)|(1<<UDRIE)
OUT      UCSRB,   temp2

RETI

;--------------------------------------
UDR_Empty:
OUT      UDR,   temp
LDI      temp2,   (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)
OUT      UCSRB,   temp2

RCALL  WrData

RETI
;--------------------------------------
;Конец обработчика прерываний
;--------------------------------------------------------------------------

;--------------------------------------------------------------------------
;Подпрограммы
.include "lcd.asm"

;Инициализация стека
Riset:       LDI  r16, LOW(ROMEND)               ;Инициализация стека
OUT SPL,R16                        ;обязательно, если используем прерывания
;и подпрограммы
LDI  r16, HIGH(ROMEND)
OUT SPH,R16

;--------------------------------------------------------------------------

;Start coriymit.yms
;Инициализация памяти, ее очитска
ROM_Flush:   LDI ZL, LOW (SROM_START)            ;Адрес начала ОЗУ в индекс
LDI ZH, HIGH(SROM_START)
CLR R16

Flush:      ST Z+, R16                        ;Сохраняем 0 в ячейку памяти
CPI ZH, HIGH(ROMEND)               ;достигли конца оперативки
BRNE Flush                        ;Нет? Крутимся дальше

CPI ZL, LOW(ROMEND)                  ;А младший байт достиг конца?
BRNE Flush

;End coriymit.yms

;---------------------------------------------------------
;Внутренняя и внешняя инициализация перифирии
;Internal Hordware Init  ======================================
.equ    XTAL      =8000000
.equ   baudrate   =9600
.equ   bauddivider   =XTAL/(16*baudrate)-1
CLI

;_______________________________________
Uart_Init:

;Задаем скорость обмена

LDI      R16,   HIGH(bauddivider)
OUT      UBRRH,   R16

LDI      R16,   LOW(bauddivider)
OUT      UBRRL,   R16

;Очистка всех флагов в UCSRA
CLR    R16
OUT    UCSRA,   R16

;URSEL-если установлен в 1, то байт попадает в регистр UCSRC
;UCSZ=11 - стандартная 8-битная посылка
LDI      R16,   (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
OUT      UCSRC,   R16

;Запрещаем все прерывания UART.
;Разрешаем прием\передачи
LDI      R16,   (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)
OUT      UCSRB,   R16

; End Internal Hordware Init ===================================

; External Hordware Init  ======================================

//Инициализация дисплея
RCALL    LCD_INIT

LDI      temp, 0b01000000      ;Вывод будет на первую строчку
RCALL    Cmd
;   LDI    temp, b
;   RCALL  WrData
; End External Hordware Init ===================================

SEI                        ;Глобальное разрешени прерываний
;---------------------------------------------------------------

;Главный цикл
; Main =========================================================
Main:
RJMP   Main
; End Main ====================================================
Команда в дисплей идет через процедуру "CMD". Динные через "WrData". Библиотеку, которую использую - прилагаю. Статические символы выводятся без проблем.

[4.64 Кб]
0
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
29.11.2014, 16:41 16
Цитата Сообщение от avr_bikymmir
Подскажите, пожалуйста, как правильно реализовать вывод символа с UART на LCD. Я пока только до такого варианта додумался..
Примерно...

[41.32 Кб]

0
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
30.11.2014, 04:22 17
В очередной раз огромное спасибо за помощь. Нашел серьезную ошибку у себя. Ну и узнал новое.
0
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
30.11.2014, 09:13 18
И еще один вопрос. Надеюсь последний. Как сделать, чтоб длинные строчки, принимаемая через USORT, полностью читались на ЖК дисплее? Никак не соображу.
0
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
30.11.2014, 09:28 19
пишем входящую строку в буфер, ловим конец строки (\r\n), проверяем длину строки(чтобы она поместилась на ЖК), затем начинаем писать этот буфер на ЖК.
0
0 / 0 / 0
Регистрация: 11.07.2014
Сообщений: 116
30.11.2014, 12:57 20
Либо разрешить прокрутку дисплея вправо-влево и выделить для этого соответствующие кнопки, либо делить строки по количеству символов. Самый простой способ - по ширине, но можно и по словам.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.11.2014, 12:57

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

Обработка сообщений через USART на Atmega16
Здравствуйте! Хочу сделать, чтобы контроллер обрабатывал команду полученную через USORT. Допустим...

HD44780+ATMega16+ASM
Писал когда то програмку для выводов символов на ЖКИ. Раньше работала. Решил тут недавно добавить...

Не работают часы на ATMega16 (asm)
Помогите, пожалуйста, начинающему. В качестве первого проекта решил написать програмку часов (так...

Работа с USART ATMega128 (ASM)
Добрый вечер! Возникла небольшое недопонимание по программе. Программа вроде бы простая,да...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.