Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
USART.docx
Скачиваний:
6
Добавлен:
01.03.2025
Размер:
171.66 Кб
Скачать

Init_usart:

ldi temp,(1<<TXEN | 1<<RXEN)

out UCSRB,temp ;разрешение передачи по каналу USART (в ;разряды TXEN и RXEN записываем 1)

sbi UCSRB, RXCIE ;устанавливаем флаг разрешения прерывания по

;завершении приема, прерывание происходит,

;когда RXC устанавливается в 1

clr temp

out UBRRH,temp

ldi temp,0x05

out UBRRL,temp ;задается скорость передачи 38400 бод

ldi temp, ((1<<URSEL)|(3<<UCSZ0))

out UCSRC,temp ; 1 стоп бит - 0 в USBS,

;контроль четности отсутсвует UPM1,UPM0 = 0

;USZ=3(USZ0-0,USZ1-1,USZ2-1) - посылается 8 бит за 1 раз

ret

;**********************************************************************

;передача байта по USART

USART_TRANSMIT:

clr flag

sbi UCSRB,UDRIE ;устанавливаем флаг разрешения ;прерывания регистр данных пуст ;прерывание происходит когда передача ;предыдущего байта завершена; ;и устанавливается флаг UDRE

rjmp loop ;переход на цикл ожидания прерывания

;**********************************************************************

;обработчик прерывания регистр данных UDR пуст, UDRE=1

TRANSMIT:

ldi flag,0x01 ;устанвливаем флаг в 1

ldi temp, 0x65 ;передаем "A", 0x65- ASCII код этого символа

out UDR,temp ;передача данных по USART

reti

;**********************************************************************;обработчик прерывания «прием данных завершен», регистр RXC=1

RECEIVE:

In temp, udr ; считываем данные, переданные по usart ;микроконтроллеру(байт содержаться в ;регистре udr)

out PORTB,temp ; выводим полученное значение на ;светодиоды

reti

.eseg

В двух следующих примерах по нажатию кнопки 0 осуществляется вывод последовательности байт I love this wonderful world, по нажатию кнопки 1 – Hello, World. При этом для того, чтобы определить конец последовательности в первом случае вводиться счетчик, который увеличивается на 1при выводе каждого символа ,после чего его значение сравнивается с количеством символов в последовательности. Если значение счетчика меньше количества символов, то выводим следующий байт, иначе завершаем передачу данных. Также символ введенный с клавиатуры компьютера выводится на светодиоды.

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

В примере 1 используется для организации обмена данными прерывания USART, в примере 2 – проверяется значение флагов вручную.

Последовательность символов с помощью директивы .db вносится в память программы.

text: .db 'I',' ','L','O','V','E',' ','T','H','I','S',' ','W','O','N','D','E','F','U','L','L',' ','W','O','R','L','D',0x0A,0x0D

Где text – это метка, по которой мы сможем обращаться к нашей последовательности в программе.

Два последних байта 0x0A и 0x0D – это коды соответствующие переносу строки и возврату каретки. Введены в последовательность, чтобы в окне Hyper Terminal фрза выводилась с начала новой строки.

Для чтения символов из памяти используется команда lpm(Load Program Memory). При ее выполнении байт, записанный в память программы, копируется в регистр r0. Адрес этого байта определяется шестнадцатиразрядным регистром z.

Для чиения символов нашей последовательности одного за другим следует сначала в регистр z записать адрес начала последовательности.

ldi zl,low(text*2)

ldi zh,high(text*2)

Умножение на 2необходимо, так как память программ имеет 2х байтовую структуру, а в zl значения вноситься побайтно.

Теперь чтобы передать байт по USART:

  1. считываем символ из памяти командой

lpm

  1. передаем по USART

out UDR,r0,

  1. увеличиваем адрес в z на 1

inc zl

Пример 1.

Ожидание прерывания происходит в бесконечном цикле loop. Для выхода из него используется регистр flag. После завершения передачи всех байт в обработчике прерывания этот флаг устанавливается в 1. В цикле loop происходит сравнение flag с 1, если flag=1, то осуществляется выход из цикла loop и возвращение в main.

В цикле main проверяется нажаты ли кнопки. Переход на функции обработки нажатия кнопки происходит только после того, как кнопка была отпущена.

Так как в функции передачи последовательности байт USART_TRANSMIT мы должны знать какая кнопка нажата, чтобы для каждой из них реализовать свой принцип завершения последовательности, вводиться регистр button, который хранит номер нажатой кнопки.

В обработчике события каждой кнопки в регистр button записываем ее номер, в регистр z вносим начальный адрес соответствующей данной кнопке последовательности символов и переходим на метку USART_TRANSMIT

BUTTON1_ON:

ldi button,BUTTON_1_ON

ldi zl,low(text*2) ;загрузка начального адреса передаваемого текста

ldi zh,high(text*2)

rjmp USART_TRANSMIT

В USART_TRANSMIT разрешаем прерывание «регистр данных пуст» sbi UCSRB,UDRIE, запрещаем прерывание «прием завершен cbi UCSRB,RXCIE. В регистр count записываем число символов первой последовательности ldi count,29 и переходим на цикл ожидания прерывания rjmp loop.

Когда происходит прерывание, передаем байт данных. Переданный байт записываем в регистр temp. Увеличиваем адрес, по которому считывается байт из памяти программы, на 1. В зависимости от того какая кнопка нажата переходим на разные метки.

TRANSMIT:

lpm

out UDR,r0 ;передача данных по USART

mov temp,r0

inc zl

cpi button,BUTTON_2_ON

breq BUTTON2_END

Если нажата кнопка 0, то переходим на метку BUTTON1_END, уменьшаем на 1 значение счетчика переданных символов count. Если его значение не равно0, то переходим на метку END_TR и по команде reti возвращаемся в цикл ожидания прерывания «регистр данных пуст» loop. Если равно, то завершаем передачу, перейдя на метку END_POSL, где устанавливаем в 1 flag.

Теперь, когда по команде reti мы вернемся в цикл loop, из него произойдет переход в основной цикл main, так как flag = 1.

Если нажата кнопка 1 макета, то из USART_TRANSMIT осуществляется переход на метку BUTTON2_END. Сравниваем содержимое регистра temp с последним символом последовательности. Если равенство не выполняется, то возвращаемся в loop по reti, иначе переходим на метку END_POSL, устанавливаем в 1 flag. И теперь, когда по команде reti мы вернемся в цикл loop, из него произойдет переход в основной цикл main, так как flag = 1.

BUTTON1_END:

dec count

breq END_POSL

rjmp END_TR

BUTTON2_END:

cpi temp,0x0D

breq END_POSL

END_TR:

reti

END_POSL:

ldi flag,0x01

rjmp END_TR

Во время цикла main может произойти прерывание «прием завершен». Тогда мы перейдем на обработчик прерывания RECEIVE, считаем полученный символ и выведем его ASCII код на светодиоды.

вывод последовательности символов по прерываниям от USART для Степана

.include "m8515def.inc"

.dseg

.def temp = r16

.def flag = r17

.def count = r18

.def button = r19 ;хранит номер нажатой кнопки

.equ BUTTON1 = 0x00

.equ BUTTON2 = 0x01

.equ BUTTON_1_ON = 0x01

.equ BUTTON_2_ON = 0x02

.cseg

.org 0x0000

rjmp INIT

.org 0x0009

rjmp RECEIVE

.org 0x000a

rjmp TRANSMIT

INIT:

ldi temp,low(RAMEND) ;инициализация стека

out SPL,temp

ldi temp,high(RAMEND)

out SPH,temp

sei

ser temp

out DDRB,temp ;портВ - светодиоды, в DDRB 1111111 - порт на вывод

clr temp

out DDRA,temp ;портА - на ввод, кнопки

ser temp

out PINA,temp

out PORTA,temp

rcall INIT_USART ;инициализация USART

MAIN:

sbis PINA,BUTTON1 ;если нулевой разряд установлен (кнопка не ;нажата), то пропускаем следующую команду

rcall BUTTON1_UP

sbis PINA,BUTTON2

rcall BUTTON2_UP

rjmp MAIN

BUTTON1_UP:

sbic PINA,BUTTON1

rjmp BUTTON1_ON

rjmp BUTTON1_UP

BUTTON2_UP:

sbic PINA,BUTTON2

rjmp BUTTON2_ON

rjmp BUTTON2_UP

LOOP:

cpi flag,0x01 ;если flag=1, то выходим из цикла, вся ;последовательность символов уже передана

breq END_LOOP

sbis PINA,BUTTON1 ;если нулевой разряд установлен (кнопка не ;нажата), то пропускаем следующую команду

rjmp END_LOOP ;если установлен, то выходим из цикла

sbis PINA,BUTTON2

rjmp END_LOOP

rjmp LOOP

END_LOOP:

cbi UCSRB,UDRIE ;запрещаем прерывание «регистр данных пуст»

sbi UCSRB,RXCIE ;разрешаем прерывание «прием завершен», тперь ;снова можем принимать байты

ret ;возврат в цикл main

;*******************************************************************

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]