ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
22 ноября
441230 Топик полностью
Adept (12.09.2013 17:35 - 18:03, просмотров: 271) ответил Apтём на Если использовать два прерывания(RS485), то в TXC ничего посылать не надо, там только направление переключается. Для RS232 не нужно два прерывания использовать.
+ в общем-то прерывание нужно использовать только на приём, чтобы вовремя забирать то, что туда прилетело. При передаче, как правило, это не нужно. Достаточно отслеживать то, что передача ещё не закончена, и затем пихать туда новый байт. У меня примерно так и сделано, есть типовая подпрограммка отсылки байта через UART, с ожиданием опустошения буфера. Я обычно активно использую прерывания (как правило, - структура программы - главный цикл, с контролем системных флагов, и системный таймер, который заправляет отсчётами всяких таймаутов, и установкой флагов для периодичности выполнения задач), для всей периферии, которая мне нужна, я безбоязненно включаю прерывания, и в общем и целом программа глубоко нелинейна. Как правило, при такой структуре, "зависон" в цикле отправки одного байта (помним, что прерывания разрешены, и задачи по прерываниям выполняются) никого не напрягает. Итог: по прерыванию UART у меня только "распарсивание" пакетов в софтовом приёмном буфере (в соответствии с моим протоколом), а передача небуферизирована - просто цикл с ожиданием окончания передачи предыдущего байта. Там, где нужна буферизированная передача - организую частный специальный буфер именно для этой операции, а саму операцию, выделяю в отдельную задачу, которая выполняется, когда до неё дойдёт очередь, и освободятся ресурсы (у меня сделана эдакая "мультизадачная" среда на 16 задач с пиоритетом и очередью" очень удобная штука, как шаблон для проектов :)) Надеюсь, что как-то паонятно (хотя чувствую - о"объяснил" очень туманно :(( Ну во п/п передачи выглядит примерно так: ;П/П передачи байта через USART C0 ;TMP - передаваемые данные, никакие регистры (в т.ч. и TMP) не портятся ;10/VII.13 TxD_USART_C0: push TMP ;Сохраним данные, пока проверяем статус USART wait_if_USART_C0_busy: ;Ждём, если USART занят sei ;Разрешим все прерывания на время ожидания освобождения регистра данных UART lds TMP,USARTC0_STATUS ;Проверяем, не занят ли USART передачей? sbrs TMP,USART_DREIF_bp ;Если USART занят, rjmp wait_if_USART_C0_busy ; то ждём, иначе ; начинаем передачу. ;-- Передача байта pop TMP ;вспомним, что хотели передавать :) sts USARTC0_DATA,TMP ;передаём ret А кусок кода, с передачей данных по UART, примерно вот так: ;-- стандартный канал обмена для приложения .macro SendBYTE_byUSART_C0 ;макрос передачи байта через USART_C0 ldi TMP,@0 call TxD_USART_C0 ;Используемая п/п "TxD_USART_C0" умеет ; ждать, когда буфер ещё занят отправляемыми данными. .endmacro #define TxD_USART_exchange TxD_USART_C0 ;определение П/П порта обмена данными #define SendBYTE_byUART_exchange SendBYTE_byUSART_C0 ;Имя макроса передачи байта по каналу обмена . . . mov TMP,STAT call TxD_USART_exchange ; mov TMP,STAT_plus call TxD_USART_exchange lds TMP,S_Parameter_Waveforms call TxD_USART_exchange lds TMP,S_Parameter_MTime0 call TxD_USART_exchange lds TMP,S_Parameter_MTime1 call TxD_USART_exchange lds TMP,S_Parameter_Frequency0 call TxD_USART_exchange . . . Ну или с использованием макроса, примерно вот так: . . . Set_STAT_DATAtype DT_About ;Установим в регистре STAT подходящий тип передаваемых данных mov TMP,STAT call TxD_USART_stuff ; SendBYTE_byUART_exchange Hardware_VERSION SendBYTE_byUART_exchange Hardware_REVISION SendBYTE_byUART_exchange Software_VERSION SendBYTE_byUART_exchange Software_REVISION SendBYTE_byUART_exchange dateDay SendBYTE_byUART_exchange dateMonth SendBYTE_byUART_exchange dateYear . . . Чёт-то посмотрел сейчас и ужаснулся, сколько я вложенных макросов использую :( надо с этим что-то делать :))
...делать нужно так, как нужно. А как ненужно - делать не нужно (С) Винни-Пух :)