|
|
  |
STM32F4, UART и лишний бит при чтении, ума не приложу, что я сделал не так... |
|
|
|
Feb 24 2016, 15:49
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 4-12-08
Из: Москва
Пользователь №: 42 205

|
C фронтами сигнала из прошлого поста я разобрался, но появились новые глюки. Мой STM32F4 почему-то принимает целый лишний байт (!) в начале ответной посылки от периферии, общаясь с нею по UARTу. Периферия говорит ему: FF, FF, 01, 02, 00, FB.А микроконтроллер, зараза такая, принимает: FF, FF, FF, 01, 02, 00, FC.Имею спросить: как бы мне это забороть? P.S. Вот начало ответной посылки моей периферии. Тут явно видно, что посылают всё-таки два стартовых FF-байта, а не три.
Код инициализации UARTа: Код void MX_UART5_Init(void) {
huart5.Instance = UART5; huart5.Init.BaudRate = 1000000; huart5.Init.WordLength = UART_WORDLENGTH_8B; huart5.Init.StopBits = UART_STOPBITS_1; huart5.Init.Parity = UART_PARITY_NONE; huart5.Init.Mode = UART_MODE_TX_RX; huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart5.Init.OverSampling = UART_OVERSAMPLING_8; HAL_HalfDuplex_Init(&huart5);
} P.P.S. Код обращения к периферии (не бойтесь, printf там происходит уже после того, как получена ответная часть): CODE void PingServo(UART_HandleTypeDef* uartPtr) { uint32_t timeout = 1000; // в миллисекундах uint8_t txData[6]; uint8_t servoId = 1; uint8_t len = 2; uint8_t instruction = 1; uint8_t checksum = ~(servoId + len + instruction); txData[0] = 0xFF; txData[1] = 0xFF; txData[2] = servoId; txData[3] = len; txData[4] = instruction; txData[5] = checksum; HAL_StatusTypeDef txStatus = HAL_UART_Transmit(uartPtr, txData, 6, timeout); if(txStatus != HAL_OK) { printf("TX ERROR\r\n"); } uint8_t rxData[7]; HAL_StatusTypeDef rxStatus = HAL_UART_Receive(uartPtr, rxData, 7, timeout); if(rxStatus != HAL_OK) { printf("RX ERROR\r\n"); } else { uint8_t rxId = rxData[3]; uint8_t rxLen = rxData[4]; uint8_t rxErr = rxData[5]; uint8_t rxChecksum = rxData[6]; if(rxChecksum != checksum) { printf("CHECKSUM ERROR: received %x vs sent %x\r\n", rxChecksum, checksum); } for(int i = 0; i < 7; i++) { printf("rxData[%i] == %x\r\n", i, rxData[i]); } } printf("\r\n\r\n"); } P.P.P.S. Целиковый проект, на всякий случай:
TestUART.rar ( 8.53 мегабайт )
Кол-во скачиваний: 33
Сообщение отредактировал IgorKossak - Feb 24 2016, 18:45
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Feb 24 2016, 21:04
|
Местный
  
Группа: Свой
Сообщений: 262
Регистрация: 18-02-05
Из: SPb
Пользователь №: 2 743

|
Возможно, скажу глупость, но попробую высказаться. Как раз недавно занялся новым проектом на stm32. Решил, что стоит попробовать работать с HAL. В сети куча описаний, как работать с контроллером прерываний, куча примеров под STL, значительно меньше примеров с HAL. В даташите и в книжках написано, что нужно обязательно сбрасывать флаг прерывания при инициализации. В примерах с STL это свято выполняется, даже все коментарии указывают, что вот именно здесь мы сбрасываем флаги прерываний. В примерах с HAL такого нет! Я был уверен, что сброс флагов происходит где-то внутри хитрозакрученных макросов (там чёрт ногу сломит, что и как делается). Но выяснилось, что в примерах посто решили не сбрасывать флаги прерываний. Возможно, что у Вас тот же случай - прерывание срабатывает до того, как что-то пришло.
P.S. Админам и гуру: если мои мысли не верны - удаляйте.
|
|
|
|
|
Feb 24 2016, 21:06
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 4-12-08
Из: Москва
Пользователь №: 42 205

|
Цитата(AlexMad @ Feb 25 2016, 00:04)  Возможно, что у Вас тот же случай - прерывание срабатывает до того, как что-то пришло. Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить? <навостряет уши>
|
|
|
|
|
Feb 24 2016, 21:44
|
Местный
  
Группа: Свой
Сообщений: 262
Регистрация: 18-02-05
Из: SPb
Пользователь №: 2 743

|
Цитата(Я.К. @ Feb 25 2016, 00:06)  Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить?
<навостряет уши> Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации?
|
|
|
|
|
Feb 24 2016, 21:45
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 4-12-08
Из: Москва
Пользователь №: 42 205

|
Цитата(AlexMad @ Feb 25 2016, 00:44)  Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации? А что вы имеете в виду под инициализацией? Я должен закомментировать HAL_HalfDuplexInit(&huart5) — или чего что?
|
|
|
|
|
Feb 24 2016, 21:56
|
Местный
  
Группа: Свой
Сообщений: 262
Регистрация: 18-02-05
Из: SPb
Пользователь №: 2 743

|
Цитата(Я.К. @ Feb 25 2016, 00:45)  А что вы имеете в виду под инициализацией?
Я должен закомментировать HAL_HalfDuplexInit(&huart5) — или чего что? Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам.
|
|
|
|
|
Feb 25 2016, 08:27
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Я.К. @ Feb 24 2016, 16:49)  Я вот на осциллограму глянул, и по ней похоже, что у Вас там стоит какой-то чип шины типа RS-485: там такая полочка в самом начале перед, якобы, первым стартовым битом (в нуль), словно кто-то из третьего состояния в активное "1" выходит. Может быть там-таки есть подальше слева, за кадром, нулевой импульс, который воспринимается как стартовый (это всего-то 1мкс на ваших 1Mbit), после чего идет IDLE, которое воспринимается как 0xFF. В момент, например, когда чип шины пассивируется ПОСЛЕ передачи и ПЕРЕД приемом при полудуплексе. Вы бы осциллограмму зафиксировали от начала передачи до конца приема...
|
|
|
|
|
Feb 25 2016, 08:34
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Я.К. @ Feb 25 2016, 00:06)  Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить? Я не смотрел реализации, Но если у вас би директ, то необходимо после передачи, переходить на приём. Соответственно это запрещение/ разрешение прерываний, возможно ещё что-то. Не работал с би директом. Поэтому перед приёмом флаги надо сбрасывать. Это просто очевидно, на мой взгляд. С таким простым устройством как UART работать через HAL, только дополнительные трудности, а не упрощение. На мой взгляд.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|