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

STM32F4, UART и лишний бит при чтении

C фронтами сигнала из прошлого поста я разобрался, но появились новые глюки.

 

Мой STM32F4 почему-то принимает целый лишний байт (!) в начале ответной посылки от периферии, общаясь с нею по UARTу.

 

Периферия говорит ему: FF, FF, 01, 02, 00, FB.

А микроконтроллер, зараза такая, принимает: FF, FF, FF, 01, 02, 00, FC.

 

Имею спросить: как бы мне это забороть?

 

 

P.S. Вот начало ответной посылки моей периферии. Тут явно видно, что посылают всё-таки два стартовых FF-байта, а не три.

 

post-42205-1456328464_thumb.png

 

Код инициализации 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

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

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


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

Возможно, скажу глупость, но попробую высказаться.

Как раз недавно занялся новым проектом на stm32. Решил, что стоит попробовать работать с HAL.

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

В примерах с HAL такого нет! Я был уверен, что сброс флагов происходит где-то внутри хитрозакрученных макросов (там чёрт ногу сломит, что и как делается). Но выяснилось, что в примерах посто решили не сбрасывать флаги прерываний.

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

 

P.S. Админам и гуру: если мои мысли не верны - удаляйте.

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


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

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

 

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

 

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

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


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

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

 

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

Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации?

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


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

Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации?

 

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

 

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

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


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

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

 

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

Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам.

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


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

Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам.

 

Увы, всегда. Я проделывал PingServo в цикле, и каждый раз было то же самое.

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


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

Я вот на осциллограму глянул, и по ней похоже, что у Вас там стоит какой-то чип шины типа RS-485: там такая полочка в самом начале перед, якобы, первым стартовым битом (в нуль), словно кто-то из третьего состояния в активное "1" выходит. Может быть там-таки есть подальше слева, за кадром, нулевой импульс, который воспринимается как стартовый (это всего-то 1мкс на ваших 1Mbit), после чего идет IDLE, которое воспринимается как 0xFF. В момент, например, когда чип шины пассивируется ПОСЛЕ передачи и ПЕРЕД приемом при полудуплексе. Вы бы осциллограмму зафиксировали от начала передачи до конца приема...

 

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


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

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

Я не смотрел реализации, Но если у вас би директ, то необходимо после передачи, переходить на приём. Соответственно это запрещение/ разрешение прерываний, возможно ещё что-то. Не работал с би директом.

Поэтому перед приёмом флаги надо сбрасывать. Это просто очевидно, на мой взгляд.

С таким простым устройством как UART работать через HAL, только дополнительные трудности, а не упрощение. На мой взгляд.

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


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

Полные осциллограммы тоже сохранял. Вот, держите.

T0000CH1.rar

 

Но там небольшое повышение уровня сигнала (та самая полочка) возникает именно перед тем, как моя серва начинает передавать данные. И возникает из-за того, что она тоже включает какие-то свои пулл-апы, подтягивая сигнал к 5В.

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


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

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

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

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

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

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

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

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

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

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