Я.К. 0 24 февраля, 2016 Опубликовано 24 февраля, 2016 (изменено) · Жалоба 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 там происходит уже после того, как получена ответная часть): 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 Изменено 24 февраля, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexMad 0 24 февраля, 2016 Опубликовано 24 февраля, 2016 · Жалоба Возможно, скажу глупость, но попробую высказаться. Как раз недавно занялся новым проектом на stm32. Решил, что стоит попробовать работать с HAL. В сети куча описаний, как работать с контроллером прерываний, куча примеров под STL, значительно меньше примеров с HAL. В даташите и в книжках написано, что нужно обязательно сбрасывать флаг прерывания при инициализации. В примерах с STL это свято выполняется, даже все коментарии указывают, что вот именно здесь мы сбрасываем флаги прерываний. В примерах с HAL такого нет! Я был уверен, что сброс флагов происходит где-то внутри хитрозакрученных макросов (там чёрт ногу сломит, что и как делается). Но выяснилось, что в примерах посто решили не сбрасывать флаги прерываний. Возможно, что у Вас тот же случай - прерывание срабатывает до того, как что-то пришло. P.S. Админам и гуру: если мои мысли не верны - удаляйте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Я.К. 0 24 февраля, 2016 Опубликовано 24 февраля, 2016 · Жалоба Возможно, что у Вас тот же случай - прерывание срабатывает до того, как что-то пришло. Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить? <навостряет уши> Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexMad 0 24 февраля, 2016 Опубликовано 24 февраля, 2016 · Жалоба Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить? <навостряет уши> Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Я.К. 0 24 февраля, 2016 Опубликовано 24 февраля, 2016 · Жалоба Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации? А что вы имеете в виду под инициализацией? Я должен закомментировать HAL_HalfDuplexInit(&huart5) — или чего что? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexMad 0 24 февраля, 2016 Опубликовано 24 февраля, 2016 · Жалоба А что вы имеете в виду под инициализацией? Я должен закомментировать HAL_HalfDuplexInit(&huart5) — или чего что? Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Я.К. 0 24 февраля, 2016 Опубликовано 24 февраля, 2016 · Жалоба Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам. Увы, всегда. Я проделывал PingServo в цикле, и каждый раз было то же самое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба Я вот на осциллограму глянул, и по ней похоже, что у Вас там стоит какой-то чип шины типа RS-485: там такая полочка в самом начале перед, якобы, первым стартовым битом (в нуль), словно кто-то из третьего состояния в активное "1" выходит. Может быть там-таки есть подальше слева, за кадром, нулевой импульс, который воспринимается как стартовый (это всего-то 1мкс на ваших 1Mbit), после чего идет IDLE, которое воспринимается как 0xFF. В момент, например, когда чип шины пассивируется ПОСЛЕ передачи и ПЕРЕД приемом при полудуплексе. Вы бы осциллограмму зафиксировали от начала передачи до конца приема... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить? Я не смотрел реализации, Но если у вас би директ, то необходимо после передачи, переходить на приём. Соответственно это запрещение/ разрешение прерываний, возможно ещё что-то. Не работал с би директом. Поэтому перед приёмом флаги надо сбрасывать. Это просто очевидно, на мой взгляд. С таким простым устройством как UART работать через HAL, только дополнительные трудности, а не упрощение. На мой взгляд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Я.К. 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба Полные осциллограммы тоже сохранял. Вот, держите. T0000CH1.rar Но там небольшое повышение уровня сигнала (та самая полочка) возникает именно перед тем, как моя серва начинает передавать данные. И возникает из-за того, что она тоже включает какие-то свои пулл-апы, подтягивая сигнал к 5В. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться