реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32F4, UART и лишний бит при чтении, ума не приложу, что я сделал не так...
Я.К.
сообщение Feb 24 2016, 15:49
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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] - для короткого!!!
Go to the top of the page
 
+Quote Post
AlexMad
сообщение Feb 24 2016, 21:04
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 262
Регистрация: 18-02-05
Из: SPb
Пользователь №: 2 743



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

P.S. Админам и гуру: если мои мысли не верны - удаляйте.
Go to the top of the page
 
+Quote Post
Я.К.
сообщение Feb 24 2016, 21:06
Сообщение #3


Местный
***

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



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


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

<навостряет уши>
Go to the top of the page
 
+Quote Post
AlexMad
сообщение Feb 24 2016, 21:44
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 262
Регистрация: 18-02-05
Из: SPb
Пользователь №: 2 743



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

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

Применительно к моему высказыванию задам дополнительный вопрос - у Вас ВСЕГДА прилетает лишний FF, или только после инициализации?
Go to the top of the page
 
+Quote Post
Я.К.
сообщение Feb 24 2016, 21:45
Сообщение #5


Местный
***

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



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


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

Я должен закомментировать HAL_HalfDuplexInit(&huart5) — или чего что?
Go to the top of the page
 
+Quote Post
AlexMad
сообщение Feb 24 2016, 21:56
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 262
Регистрация: 18-02-05
Из: SPb
Пользователь №: 2 743



Цитата(Я.К. @ Feb 25 2016, 00:45) *
А что вы имеете в виду под инициализацией?

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

Я имею ввиду другое. Если прилетает несколько посылок, то лишний байт есть всегда? Или только после рестарта системы? Если всегда, то нужно копать глубже. Если только после рестарта/инициализации - то Вы на пути к флагам.
Go to the top of the page
 
+Quote Post
Я.К.
сообщение Feb 24 2016, 22:04
Сообщение #7


Местный
***

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



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


Увы, всегда. Я проделывал PingServo в цикле, и каждый раз было то же самое.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Feb 25 2016, 08:27
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Я.К. @ Feb 24 2016, 16:49) *

Я вот на осциллограму глянул, и по ней похоже, что у Вас там стоит какой-то чип шины типа RS-485: там такая полочка в самом начале перед, якобы, первым стартовым битом (в нуль), словно кто-то из третьего состояния в активное "1" выходит. Может быть там-таки есть подальше слева, за кадром, нулевой импульс, который воспринимается как стартовый (это всего-то 1мкс на ваших 1Mbit), после чего идет IDLE, которое воспринимается как 0xFF. В момент, например, когда чип шины пассивируется ПОСЛЕ передачи и ПЕРЕД приемом при полудуплексе. Вы бы осциллограмму зафиксировали от начала передачи до конца приема...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 25 2016, 08:34
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



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

Я не смотрел реализации, Но если у вас би директ, то необходимо после передачи, переходить на приём. Соответственно это запрещение/ разрешение прерываний, возможно ещё что-то. Не работал с би директом.
Поэтому перед приёмом флаги надо сбрасывать. Это просто очевидно, на мой взгляд.
С таким простым устройством как UART работать через HAL, только дополнительные трудности, а не упрощение. На мой взгляд.
Go to the top of the page
 
+Quote Post
Я.К.
сообщение Feb 25 2016, 10:43
Сообщение #10


Местный
***

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



Полные осциллограммы тоже сохранял. Вот, держите.
Прикрепленный файл  T0000CH1.rar ( 2.26 мегабайт ) Кол-во скачиваний: 32


Но там небольшое повышение уровня сигнала (та самая полочка) возникает именно перед тем, как моя серва начинает передавать данные. И возникает из-за того, что она тоже включает какие-то свои пулл-апы, подтягивая сигнал к 5В.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th June 2025 - 05:37
Рейтинг@Mail.ru


Страница сгенерированна за 0.01382 секунд с 7
ELECTRONIX ©2004-2016