Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Гарантия того, что по USART все данные ушли
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
Александр Куличок
Речь шла о флаге TXC. И о возможности отслеживания разрывов:
Цитата
Если же флаг сбрасывать при загрузке UDR, то вы не сможете отследить те самые разрывы между байтами, которые могут быть критичны.

Если паузы недопустимы, то считывание его перед записью в UDR как раз позволяет проанализировать, была ли пауза при передаче. И принимать дальнейшее решение о том, что писать (или не писать) в UDR.
Одно только использование UDRE еще не дает гарантию, что пауз не будет. Особенно при большИх скоростях.
sitafern
Пользуюсь простым алгоритмом при реализации Modbus RTU (потолок скорости 115200).
Назначения:
1. Буфер приёмника/передатчика (первый байт - счётчик).
2. 1 РОН для счётчика "долгих" циклов.
3. 2 РОНа для хранения CRC16.
4. Функция подсчёта CRC "на лету".
5. Функция записи в буфер записывает последними в буфер 2 байта CRC16.
6. Функция передачи данных подсчитывает CRC16 "на лету".
Собственно проверка:
1. "Длинный" счётчик =0? Да.
2. РОНы контрольной суммы =0? Да.
Резюме: данные "уехали" без проблем.
CODE
;======================================================================
=============
; ЗАДАЧА 7 - Передача фрейма данных в хост-компьютер по USART0 по протоколу ModBusRTU
;===============================================================================
====
PLC_7:
sbrs rFlagPLC, flPLC_7
rjmp Exit_PLC_7

cbr rFlagPLC, (1<<flPLC_0) ; Запретить приём по USART0 на время передачи
sbrc rFlagUSART, flReady0 ; Начальная инициализация была?
rjmp lbLoadTxD0 ; Да
;-------------------------------------------------------------------
; Инициализация функции передачи данных
ldi rFuncL, N115200 ;1. Делитель частоты UBRR0H:UBRR0L = 0x0007
out UBRR0L, rFuncL ;2. Асинхронный режим UMSEL = 0
out UBRR0H, rZero ;3. Контроль чётности UPM1 = 1, UPM0 = 0
ldi rFuncL, 0xA6 ;4. Один стоп-бит USBS = 0
out UCSR0C, rFuncL ;5. Формат кадра 8бит UCSZ1 = 1, UCSZ0 = 1

lds rCounter0, pCountUSART0 ; Количество передаваемых байт данных
ldi XL, low(pAdressUSART0) ; Буфер передатчика начинается с адре-
ldi XH, high(pAdressUSART0) ; са УСО

sbi UCSR0B, TXEN0 ; Включить передатчик USART0!
sbr rFlagUSART, (1<<flReady0) ; PLC инициализирована
;---------------------------------------------------------------------------
; Загрузка байта данных для передачи
lbLoadTxD0:
cpse rCounter0, rZero ; Все байты фрейма загружены?
rjmp lbFrame0 ; Нет
rjmp lbEndTxD0 ; Да
lbFrame0:
sbis UCSR0A, UDRE0 ; Надо загрузить байт для передачи?
rjmp Exit_PLC_7 ; Нет.

ld rdUSART0, X+ ; Загрузить передаваемый байт
out UDR0, rdUSART0 ; Собственно загрузить байт данных для передачи
dec rCounter0 ; Уменьшаем счётчик передаваемых байт фрейма
cbi UCSR0A, UDRE0 ; Сбросить флаг требования загрузки
sbr rFlagUSART, (1<<flCRC160) ; Установить флаг требования подсчёта CRC16
;---------------------------------------------------------------------------
; Окончание функции передачи данных
lbEndTxD0:
sbis UCSR0A, TXC0 ; Ожидание передачи последнего байта
rjmp Exit_PLC_7
;-------------------------------------------------------------------
; Сброс передатчика USART0
clr rFuncL
out UCSR0B, rFuncL
;-------------------------------------------------------------------
; Проверка регистров CRC16 на ошибку
cpse rCRC160L, rZero
rjmp lbTxDError0
cpse rCRC160H, rZero
rjmp lbTxDError0
rjmp lbExitTxD0
;-------------------------------------------------------------------
lbTxDError0: ; Обработка ошибки подсчёта CRC16 "на лету"
sbr rErrInter, (1<<flCRC16T0xD)
lbExitTxD0:
sbi UCSR0A, TXC0
cbr rFlagUSART, (1<<flEmpty0)+(1<<flReady0)+(1<<flCRC160)+(1<<flFrame0)
cbr rFlagPLC, (1<<flPLC_7); Выключить функцию передачи данных по USART0
sbr rFlagPLC, (1<<flPLC_0); Включить функцию приёма данных по USART0
Exit_PLC_7:
nop
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.