У меня есть PIC16 , для которого (асинхронная) передача UART работает нормально, но прием UART дает неверные результаты.
Например, a
интерпретируется как O
, b
интерпретируется как '
, и c
получает как N
.
Вот моя функция приема:
char UART_read(void) {
while(!PIR1bits.RCIF) {}
return RCREG;
}
Моя гипотеза состоит в том, что полярность UART неверна для приемника, так что, в частности, перепутались стартовые/стоповые биты. Я установил SCKP
бит (см. стр. 302) для инвертирования данных на выводе TX/CK, но я не могу найти эквивалент для контакта RX/DT.
Что может быть причиной того, что прием UART не работает? Как я могу инвертировать данные на выводе RX/DT?
РЕДАКТИРОВАТЬ : этот ответ был изменен, чтобы отразить комментарий задавшего вопрос, и указывает, что он совершенно прав в своем диагнозе проблемы, что не очень полезная информация. Единственная полезная информация в разделе - это то, что бита инвертирования приема нет... Но, возможно, это поможет будущим людям диагностировать свои проблемы с UART.
Итак, давайте посмотрим
a сопоставляется с O, что означает, что 01100001 сопоставляется с 01001111
b сопоставляется с ', что означает, что 01100010 сопоставляется с 00100111
Предположим, что перед каждым из них стоит неявная 1, а после (стартовый и стоповый биты) неявный 0. Модуль RX получает непрерывный низкий сигнал, затем стоповый бит отправляется как высокий, который будет использоваться как сигнал ожидания, затем начальный 0 будет использоваться как стоповый бит. Тогда оставшиеся биты будут инвертированы,
so 'a' == 1 10000110 0 initially (we send least significant bit first)
1 (implicit start bit) and starting 1 are both consumed as idle bits
then the first 0 is treated as a start bit
so received == 00001100 inverted (the extra zeros are the stop bit and idle bits after transmission has ended)
11110011 and reverse it (it was sent LSB first)
11001111 is what the inverted input would look like
01001111 is what's actually received which is super close!
if what you actually sent was "abc" all in a row, then the start bit of the b would make what was received 01001111 which matches exactly
'b' == 1 01000110 0 ==> 10001100 inverted and reversed gives
11001110 is what should have "logically" happened
00100111 actual
So that doesn't quite match, but if we assume that the "abc" is what happened again, we get
01001110 which is close enough (not sure where the shift came from)
Похоже, вы поставили диагноз, к сожалению, в приемнике на PIC нет аналогичного бита конфигурации «инвертировать сигнал». Хотя поставить инвертор на приемный тракт несложно, что я бы, кстати, и рекомендовал!
Как заметил Олин, стандартные сигналы RS-232 составляют от +3 В до +15 В для логической «1» и от -3 В до -15 В для логического «0». PIC разработан для работы на уровне «TTL», что означает «транзисторно-транзисторная логика». Идея состоит в том, что PIC предназначен для общения с другими объектами, которые физически находятся близко (т. е. на той же плате), и, таким образом, дополнительное расстояние передачи и шумоподавление, обеспечиваемые полными уровнями rs-232, не требуются для «стандартной» работы. Нецелесообразно иметь возможность полностью внутренне генерировать положительные / отрицательные напряжения, необходимые для работы RS-232, полностью внутри PIC, поэтому «нормальная» связь RS-232 никогда не была вариантом.
Поскольку уровни TTL не являются стандартом, а являются производными от стандарта (один и тот же протокол для синхронизации, стартовый и стоповый биты, контроль четности, но разные напряжения), вы не покупаете потребительский «адаптер RS-232» для своего компьютера, если только он придерживается стандарта. Они делают адаптеры rs-232 уровня TTL, и они очень популярны на сайтах любителей! Ознакомьтесь с кабелем Adafruit или прорывом Sparkfun FTDI . Я считаю, что в целом, если он подходит к разъему DB9, это, вероятно, адаптер уровня rs-232.
O
(буква), а не 0
(число). Итак 01100001
, 01100010
, 01100011
сопоставьте с , 01001111
соответственно . Кроме того, помните, что биты LSB отправляются первыми. Таким образом, если линия приема инвертирована, крайний правый бит является начальным. Так становится , становится и становится , все соответствует тому, что я получаю.
00100111
01001110
1
01100001
~10110000
01100010
~11011000
01100010
~10100111
Чтобы узнать, нужна ли вам инверсия, посмотрите на уровень простоя линии. Нормальный логический уровень UART сигнализирует о простое высоким уровнем. Поскольку вы инвертировали выход, на холостом ходу он должен быть низким. Если другое устройство использует инвертированные сигналы для приема (ваша передача), то почти наверняка оно использует те же уровни для своих передач (ваш прием). Проверьте с помощью осциллографа, но вам, вероятно, понадобится инверсия, которую можно выполнить с помощью логического элемента инвертора или просто транзистора и резистора или двух, учитывая низкую скорость передачи данных.
Как вы могли подумать, что прием будет работать без инверсии, когда это требуется для передачи!?
Теперь вы показали, что вы просто подключили линии PIC UART к линиям приема и передачи RS-232 и каким-то образом ожидали, что все будет работать. Цифровые логические уровни, используемые PIC, и уровни RS-232 несовместимы, а также инвертируются высокий/низкий уровни. RS-232 должен быть ниже -5 В для незанятой линии (пробел) и выше +5 В для активной (отметка). Очевидно, что PIC не может гарантировать эти уровни при передаче и может быть поврежден этими уровнями при приеме. Обычные цифровые логические уровни высоки для пробела и низки для метки, что также делает PIC, за исключением нескольких ограниченных, таких как ваша, где одна или обе линии могут быть инвертированы.
Некоторые микросхемы приемника RS-232 не соответствуют спецификациям RS-232 и работают с сигналами 0-5 В, управляющими их приемной линией. По-видимому, это относится и к вашему ПК, поэтому вы смогли получать символы на ПК после того, как просто инвертировали линию передачи PIC. Чтобы заставить ПК -> передачу PIC работать, вы должны инвертировать сигнал и сопоставить результат с диапазоном Vss до Vdd PIC. Несоблюдение этого требования может привести к повреждению PIC, что уже могло произойти.
Все это то, почему был создан тип микросхемы MAX232. Он питается от PIC Vdd и Vss, содержит собственные зарядовые насосы для создания напряжений RS-232, имеет соответствующие схемы драйвера и приемника с каждой стороны, а также выполняет инверсию. Многие компании делают несколько вариантов этого. Это очень распространенные и доступные чипы.
Вы также можете получить небольшие модули, которые имеют микросхему преобразователя, зарядный насос и крышки блока питания, а также стандартный разъем DB-9 в одном устройстве. Я делаю один из них, который даже продается на microchipdirect. См . http://www.microchipdirect.com/ProductSearch.aspx?Keywords=TEMRS002 .
EUSART
главу (стартовая страница 291 таблицы данных PIC16 ). Нет упоминания или предупреждения о прямом подключении к RS232 или MAX232. Где я ошибся в процессе? Я предполагал, что глава таблицы данных PIC16 по EUSART будет охватывать общий вариант использования: RS232.
апалопохапа
апалопохапа
Оле К.
OSCCONbits.IRCF
регистр настроен правильно?