Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F4, UART и лишний бит при чтении
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Я.К.
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. Целиковый проект, на всякий случай:
Нажмите для просмотра прикрепленного файла
AlexMad
Возможно, скажу глупость, но попробую высказаться.
Как раз недавно занялся новым проектом на stm32. Решил, что стоит попробовать работать с HAL.
В сети куча описаний, как работать с контроллером прерываний, куча примеров под STL, значительно меньше примеров с HAL. В даташите и в книжках написано, что нужно обязательно сбрасывать флаг прерывания при инициализации. В примерах с STL это свято выполняется, даже все коментарии указывают, что вот именно здесь мы сбрасываем флаги прерываний.
В примерах с HAL такого нет! Я был уверен, что сброс флагов происходит где-то внутри хитрозакрученных макросов (там чёрт ногу сломит, что и как делается). Но выяснилось, что в примерах посто решили не сбрасывать флаги прерываний.
Возможно, что у Вас тот же случай - прерывание срабатывает до того, как что-то пришло.

P.S. Админам и гуру: если мои мысли не верны - удаляйте.
Я.К.
Цитата(AlexMad @ Feb 25 2016, 00:04) *
Возможно, что у Вас тот же случай - прерывание срабатывает до того, как что-то пришло.


Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить?

<навостряет уши>
AlexMad
Цитата(Я.К. @ Feb 25 2016, 00:06) *
Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить?

<навостряет уши>

Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации?
Я.К.
Цитата(AlexMad @ Feb 25 2016, 00:44) *
Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации?


А что вы имеете в виду под инициализацией?

Я должен закомментировать HAL_HalfDuplexInit(&huart5) — или чего что?
AlexMad
Цитата(Я.К. @ Feb 25 2016, 00:45) *
А что вы имеете в виду под инициализацией?

Я должен закомментировать HAL_HalfDuplexInit(&huart5) — или чего что?

Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам.
Я.К.
Цитата(AlexMad @ Feb 25 2016, 00:56) *
Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам.


Увы, всегда. Я проделывал PingServo в цикле, и каждый раз было то же самое.
KnightIgor
Цитата(Я.К. @ Feb 24 2016, 16:49) *

Я вот на осциллограму глянул, и по ней похоже, что у Вас там стоит какой-то чип шины типа RS-485: там такая полочка в самом начале перед, якобы, первым стартовым битом (в нуль), словно кто-то из третьего состояния в активное "1" выходит. Может быть там-таки есть подальше слева, за кадром, нулевой импульс, который воспринимается как стартовый (это всего-то 1мкс на ваших 1Mbit), после чего идет IDLE, которое воспринимается как 0xFF. В момент, например, когда чип шины пассивируется ПОСЛЕ передачи и ПЕРЕД приемом при полудуплексе. Вы бы осциллограмму зафиксировали от начала передачи до конца приема...
SasaVitebsk
Цитата(Я.К. @ Feb 25 2016, 00:06) *
Дык, это, я же вроде никаких прерываний не устанавливаю, а просто пишу и читаю в блокирующем режиме? Или там внутри эти прерывания всё равно дёргаются, и вектор прерываний таки надо сбросить?

Я не смотрел реализации, Но если у вас би директ, то необходимо после передачи, переходить на приём. Соответственно это запрещение/ разрешение прерываний, возможно ещё что-то. Не работал с би директом.
Поэтому перед приёмом флаги надо сбрасывать. Это просто очевидно, на мой взгляд.
С таким простым устройством как UART работать через HAL, только дополнительные трудности, а не упрощение. На мой взгляд.
Я.К.
Полные осциллограммы тоже сохранял. Вот, держите.
Нажмите для просмотра прикрепленного файла

Но там небольшое повышение уровня сигнала (та самая полочка) возникает именно перед тем, как моя серва начинает передавать данные. И возникает из-за того, что она тоже включает какие-то свои пулл-апы, подтягивая сигнал к 5В.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.