Перейти к содержанию
    

Assembler uart

Здравствуйте.

Написал программу для передачи символа через UART на Ассемблере. Прошил МК, а символ получить не могу. Подскажите, пожалуйста, что не так?

Программа следующая (Atmega164P, кварц 7,3728МГц):

 

include <m164def.inc>

#include <iomacros.inc>

 

.def dummy=R19

.cseg

 

ldi R24, low(RAMEND) ; SP = RAMEND

ldi R25, high(RAMEND)

out SPL, R24

out SPH, R25

 

; ---------------------------------- init UART ------------------------------------------

 

ldi R24, 23 ; Baud rate = 19.2 bps

sts UBRR0L, R24

 

ldi R24,0

sts UBRR0H, R24

 

ldi R24,(1<<RXEN0)|(1<<TXEN0) ; Enable receiver & transmitter, 8-bit mode

sts UCSR0B,R24

 

rcall uartSend ; send the read character via the UART

 

uartSend:

SKBS UCSR0A,UDRE0,dummy ; wait for empty transmit buffer (until UDRE==1)

rjmp uartSend

ldi R16, 48

STORE UDR0,R16 ; UDR = R16, start transmission

 

Delay:

ldi R16,10

rjmp Delay

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

; ---------------------------------- init UART ------------------------------------------

ldi R24, 23; Baud rate = 19.2 bps
sts UBRR0L, R24

ldi R24,0
sts UBRR0H, R24

Команда sts выполняет непосредственную запись в ОЗУ. Вам же нужно переслать значение из регистра общего назначения в регистр ввода-вывода. Кроме того, сначала производится запись в старший байт, затем в младший. Этим обычно занимается команда out:

; ---------------------------------- init UART ------------------------------------------
ldi R24, 0
ldi R25, 0x17
...
out UBRR0H, R24; Baud rate = 19.2 bps
out UBRR0L, R25
...
ldi R24,(1<<RXEN0)|(1<<TXEN0); Enable receiver & transmitter, 8-bit mode
out UCSR0B,R24

Изменено пользователем Goodefine

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласно описания МК регистры имеют следующие адреса:

.equ UBRR0L = 0xc4 ; MEMORY MAPPED

.equ UBRR0H = 0xc5 ;

 

а команда OUT работает только с адресами от 0 до 63

 

На языке СИ задаю сначала младший регистр, а затем старший и все работает нормально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласно описания МК регистры имеют следующие адреса:

.equ UBRR0L = 0xc4 ; MEMORY MAPPED

.equ UBRR0H = 0xc5 ;

И правда, не глянул какая мега...

На языке СИ задаю сначала младший регистр, а затем старший и все работает нормально.

Если на Си у вас работает, загляните в листинг. Вот, например, как CAVR генерит начальный код инициализации USART0:

На Cи:

// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 19200
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x17;

На асме:

;0000 007F // USART0 initialization
;0000 0080 // Communication Parameters: 8 Data, 1 Stop, No Parity
;0000 0081 // USART0 Receiver: On
;0000 0082 // USART0 Transmitter: On
;0000 0083 // USART0 Mode: Asynchronous
;0000 0084 // USART0 Baud Rate: 19200
;0000 0085 UCSR0A=0x00;
    STS  192,R30
;0000 0086 UCSR0B=0x18;
    LDI  R30,LOW(24)
    STS  193,R30
;0000 0087 UCSR0C=0x06;
    LDI  R30,LOW(6)
    STS  194,R30
;0000 0088 UBRR0H=0x00;
    LDI  R30,LOW(0)
    STS  197,R30
;0000 0089 UBRR0L=0x17;
    LDI  R30,LOW(23)
    STS  196,R30

Изменено пользователем Goodefine

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрел в Disassembler текст программы на СИ и на Assembler. Отличие в том, что на СИ дополнительно происходить определение регистров X,Z,Y.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...определение регистров X,Z,Y.

Минималисткий рабочий вариант:

;Chip type			  : ATmega164P
;Clock frequency		: 7,372800 MHz

#pragma AVRPART ADMIN PART_NAME ATmega164P
#pragma AVRPART MEMORY PROG_FLASH 16384
#pragma AVRPART MEMORY EEPROM 512
#pragma AVRPART MEMORY INT_SRAM SIZE 1024
#pragma AVRPART MEMORY INT_SRAM START_ADDR 0x100

.EQU RAMEND=0x4FF
.EQU EECR=0x1F
.EQU UCSR0B=0xC1
.EQU UBRR0H=0xC5
.EQU UBRR0L=0xC4
.EQU SPL=0x3D
.EQU SPH=0x3E
;/////////////////////
;INTERRUPT VECTORS
JMP  __RESET

__RESET:
CLI
CLR  R30
OUT  EECR,R30

;STACK POINTER INITIALIZATION
LDI  R30,LOW(RAMEND)
OUT  SPL,R30
LDI  R30,HIGH(RAMEND)
OUT  SPH,R30

;DATA STACK POINTER INITIALIZATION
LDI  R28,LOW(0x200)
LDI  R29,HIGH(0x200)

JMP  _main

;/////////////////
_transmitRS232byte:
_fl_transmit:
LDS  R30,192
LDI  R31,0
ANDI R30,LOW(0x20)
BREQ _fl_transmit
;UDR0=byte;
LD   R30,Y
STS  198,R30
	ADIW R28,1
RET
;///////////////

_main:
;UASART0 init
;UCSR0B=0x18;
LDI  R30,LOW(24)
STS  UCSR0B,R30
;UBRR0H=0x00;
LDI  R30,LOW(0)
STS  UBRR0H,R30
;UBRR0L=0x17;
LDI  R30,LOW(23)
STS  UBRR0L,R30

;/////////////////////
;transmitRS232byte(48);
LDI  R30,LOW(48)
ST   -Y,R30
RCALL _transmitRS232byte 

_while_1_:

;/// Main Loop \\\

RJMP _while_1_

 

От модератора.

Для объемных исходников пользуйтесь тэгом codebox, вместо code .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, разобрался, отсутсвовало определение регистра UCSR0C. Он задает количество бит в сообщении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...