Емельянов Эдуард Владимирович (eddy_em) wrote,
Емельянов Эдуард Владимирович
eddy_em

Category:

RS-485 на STM32

Сегодня весь день пытался добиться надежной работы RS-485 на STM32F042 (исходники). Оказывается, это не настолько уж и тривиально, как просто поднять UART и радоваться!

Так как 485 работает в полудуплексе, необходимо перед приемом/передачей выставить соответствующий уровень на ноге, контролирующей направление передачи.
Выставляю — бац, косяк: сообщения "обрубаются" на последней паре символов. Оказалось, что переключать направление приемопередатчика из прерывания по окончанию передачи DMA нельзя, т.к. USART в это время еще не передал все данные.
Ладно, добавляю простой конечный автомат:
void usart_proc(){
    switch(st){
        case SENDING:
            if(txrdy) st = WAITING;
        break;
        case WAITING:
            if(USARTX->ISR & USART_ISR_TXE){ // last byte done -> Rx
                _485_Rx();
            }
        break;
        default:
        break;
    }
}

И опять косяк! "\n" в конце каждой передачи отсутствует! Тут до меня дошло: ведь USART_ISR_TXE выставляется, когда буфер для отправки пуст, но это отнюдь не значит, что данные уже "уехали". Заменил этот флаг на USART_ISR_TC, и передача пошла нормально.
Но тут появились проблемы с приемом: в принимающий буфер постоянно попадал какой-то мусор. Видимо, "китайские" MAX485 (хотя вроде бы эта партия покупалась у нормальных поставщиков) не закрывают полностью канал RO при подаче на ~RE единицы, либо 3.3В им не хватает!.. (схема рассчитана на MAX3485, у которых напряжение питания 3.3В, а впаял я первое, что под руку подвернулось — MAX485E, а судя по даташиту, этому 5В подавай!)
В общем, проблема приема мусора тоже решилась: USART я стал включать либо только на прием, либо только на передачу, переделав макросы переключения Rx/Tx:
#define _485_Rx()  do{RS485_RX(); st = READING; USARTX->CR1 = (USARTX->CR1 & ~USART_CR1_TE) | USART_CR1_RE;}while(0)
#define _485_Tx()  do{RS485_TX(); st = SENDING; USARTX->CR1 = (USARTX->CR1 & ~USART_CR1_RE) | USART_CR1_TE;}while(0)

Зачем я отдельно Rx и Tx подключал — тоже сейчас не вспомню, ведь намного логичней было бы сразу работать в single wire half-duplex: Rx/Tx MAX3485 соединить вместе и подать на Tx микроконтроллера. Правда, пришлось бы выпаивать MAX485 и впаивать вместо него MAX3485, чтобы избавиться от "мусора".
Вот такие пироги с казалось бы простейшим интерфейсом!
А ведь еще надо будет добавить обработку адреса устройства… Думаю, протокол будет таким же текстовым, как и по USB, но перед командой нужно будет писать число — адрес, выставляемый на плате переключателями (на фото он трехразрядный, хотя должен быть четырех — но мне с али еще новые dip-switches не пришли). Этот же адрес будет задавать идентификатор устройства на CAN-шине. Как закончу с обработкой адреса по RS-485, перейду к CAN'у. Для его отладки у меня есть старая девборда, которую надо будет по-быстрому переделать в USB<>CAN адаптер (а заодно и протокол придумать, по которому можно будет пакеты отправлять/принимать). Уже, кстати, давненько подумываю о том, что нужно на МК сделать какой-то "эмулятор баша" для отладки: чтобы при ручном вводе команд можно было стрелочками по истории гулять + табом автодополнение делать. По идее, оперативки у средних STM'ок столько, что они запросто эту хотелку должны потянуть!
Справа внизу на фото — переходник на основе PL2303 для работы с RS-485, который я брал когда-то на али. На 115200 бод и коротком шнурке вполне нормально справляется, с бóльшими скоростями как-то работать не планирую.

Tags: stm32, железяки
Subscribe

Recent Posts from This Journal

  • Дочка сейчас выдала: а зачем вообще людям "домашние" телескопы, если с компьютера можно намного удобней с телескопа данные получать? Да уж, вся в…

  • Рамп шаговика

    Сижу уже второй вечер, обдумываю алгоритм. Сначала хотел было без делений попробовать. Но не получается нормального трапецеидального рампа. В итоге…

  • О, in100грамм повеселел!

    Теперь не нужно, чтобы туда фотографию воткнуть, жамкать F12, переходить в режим "отображение со смартфона" и перезагружать страницу! Они таки…

promo eddy_em september 3, 12:13 8
Buy for 10 tokens
Уже больше полугода занимаюсь разработкой, вот, наконец-то в мастерских взялись за меня и начали выдавать первые детали. Сегодня сделал тестовую сборку (как обычно, местами пришлось "доработать напильником"): Пока прибор без названия (да и как-то не лезет в голову ничего, у меня нет…
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic
  • 8 comments