Перейти к содержанию
    

stm32f100 USART задержка передачи и потеря символов

вот что удалось понять.

 

не зря обратил внимание, что байт уходит на передачу вовсе не сразу.

получается , что после инициирования приемопередатчика , несмотря на то, что он был явно сброшен вначале, он еще не готов к работе. ему необходим один (а может два) формальных циклов передачи, прежде чем он будет работать правильно. после того, как будут переданы пара байт, дальше приемопередатчик будет работать без пропусков и перестановок. это объясняет, почему не всегда на это поведение обращают внимание. в готовом приборе после первой битой посылки обмен будет происходить без замечаний.

 

 

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

 

    USART3->SR&=~USART_SR_TC;
    USART3->DR=0xff;
    while((USART3->SR&USART_SR_TC)==0){
;
                                         }
    
    
    USART3->SR&=~USART_SR_TC;

 

после инициализации и вот такого кусочка кода, дальше посылки уходят правильно.

 

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

 

 

посмотрю еще как все это себя ведет , может засада эшелонированная.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все не так, ребята! (с) ВВС

Проверьте все свои тактовые частоты на шинах.

Нужно проверять

if (USART2->SR & USART_SR_TXE && USART2->CR1 & USART_CR1_TXEIE) {

...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а что значит проверить? скорости обмена соответствуют для линейки от 1200 до 115200. для шин 1 и 2 выбрано 1:1.

 

и это как-то может объяснить, что приемопередатчик умудряется переставить два байта местами? кстати, это означает, что унутре у него вовсе все не так устроено, как на блок схеме нарисовано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и это как-то может объяснить, что приемопередатчик умудряется переставить два байта местами? кстати, это означает, что унутре у него вовсе все не так устроено, как на блок схеме нарисовано.

Я принимаю и передаю и никаких проблем не имею. Все согласно документации.

 

Первый байт посылаете не в прерывании. Разрешаете прерывания от TXE. Остальные байты посылаете по прерыванию. Сбрасывать флаг не нужно. Перед передачей последнего байта ('\n'), запрещаете прерывания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мне не нужно TXE , мне нужно TC. фокусы с \n не пройдут (да где вы все работаете что у вас символьные строки бегают до сих пор ?!). все что происходит я описал подробнейшим образом. и как лечится тоже.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мне не нужно TXE , мне нужно TC. фокусы с \n не пройдут (да где вы все работаете что у вас символьные строки бегают до сих пор ?!). все что происходит я описал подробнейшим образом. и как лечится тоже.

Я всякое передаю. Последний байт может быть любым, главное, знать, что он последний. Попробуйте TXE, если не хотите время терять (как свое, так и процессора).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот на самом деле именно обратно! чтобы понять, что мы окончили передачу, нужно использовать TC, иначе сразу начинается геморрой с выдержкой времени после TXE, да еще перестраиваемая в зависимости от скорости.

 

это, кстати, на одноплатках народ попадается - там тяп ляп сделано и когда используют RS485 и аппаратное управление направлением передачи, то в конце посылки 485 переключается на прием в момент, когда последний байт переписывается в сдвиговый регистр и еще не передался (но прерывание возникло, что в уарт можно писать следующее!), а его обкусили т к посчитали, что все уже передали.

 

TXE я, наверное, посмотрю, как он себя ведет. но дело не в них.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TXE и TC - это две большие разницы.

Записывать в буфер передатчика нужно по TXE, а после записи последнего байта пакета

разрешаем прерывание от TC. При возникновении TC можно быть уверенным, что байт полностью передан.

Сбрасывать флаги нужно как написано в документации (rc_w0), а не "как обычно".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TC поднимается когда TXE выставлен -> записывая в буферный регистр по TC мы имеем двойную гарантию что делаем это вовремя: и из буферного регистра в сдвиговый переписались и уже и из сдвигового выдвинули.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TC поднимается когда TXE выставлен -> записывая в буферный регистр по TC мы имеем двойную гарантию что делаем это вовремя:
Первой гарантии достаточно. Вторая гарантия даст только паузы между байтами если программа делет что-нибудь еще кроме передачи.

да если посмотреть примеры кода в сети , то народ чтением модификацией стирает
Да если посмотреть примеры в сети, то народ и дорогу на красный переходит, и через двойную сплошную переезжает... Продолжать?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сразу не сообразил.

чтение модификация запись - как раз точно то, что надо и делает.

флаг помечен как rc_w0 - т е его можно прочитать и он сбрасывается записью нуля.

ну так, чтение модификация запись собственно это и делает. мы прочитали (да, этого можно было и не делать) , сбросили нужный бит и записали .

все в стандартной, принятой для битовой работе манере. и то, что нужно по описанию регистру

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну какой же вы тупой! (с)

ну так, чтение модификация запись собственно это и делает. мы прочитали (да, этого можно было и не делать) , сбросили нужный бит и записали .

Вам уже и пример привели, и на словах объяснили. Вы прочитали, там ещё несколько нулей. И все эти биты вы сбросили записью. А между тем моментом, когда вы прочитали, и записью, могли взвестись ещё флаги. И вы их таким образом потеряете.

Именно для того, чтобы избежать таких ситуаций, делают rc_w0. Чтобы можно было смело писать единичку в остальные биты, и от этого их состояние не менялось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... а после записи последнего байта пакета

разрешаем прерывание от TC. При возникновении TC можно быть уверенным, что байт полностью передан.

А когда (зачем) это нужно знать? А, ну если приемопередатчики RS-485 переключать со входа на выход...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну какой же вы тупой! (с)

 

Вам уже и пример привели, и на словах объяснили. Вы прочитали, там ещё несколько нулей. И все эти биты вы сбросили записью. А между тем моментом, когда вы прочитали, и записью, могли взвестись ещё флаги. И вы их таким образом потеряете.

Именно для того, чтобы избежать таких ситуаций, делают rc_w0. Чтобы можно было смело писать единичку в остальные биты, и от этого их состояние не менялось.

 

это надумано. тогда подумайте что будет в момент между чтением флагов когда мы решили что они нули и записью туда 0 прямой командой записи.

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

а как научитесь, милости просим на форум.

 

А когда (зачем) это нужно знать? А, ну если приемопередатчики RS-485 переключать со входа на выход...

 

ну двухпроводной уарт в промышленности практически не используется (если только диагностический порт с морды или какой прибор с несетевым обменом). если только при общении с беспроводными модулями - у них еще отдельные TX RX. А так, поголовно RS485 (там где не TCP).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

это надумано. тогда подумайте что будет в момент между чтением флагов когда мы решили что они нули и записью туда 0 прямой командой записи.

Вы не разобрались, как работает rc_w0. Такой бит можно прочитать, или сбросить, записав 0. А записать 1 в него невозможно. И поэтому можно смело записывать единицы, они не повредят.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...