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

Stm32: Cubemx+Uart_Dma


verlaty

Рекомендуемые сообщения

Разобрался с регистрами. Но не с проблемой. В принципе все эти проверки уже реализованы в HAL. Грубо говоря все это повторил отдельно, зависания остались. Реализовал все через прерывания - та же фигня. В общем выложу на обсуждение свои мысли.

1.Зависает прием UART(именно прием, так как передача продолжает работать), программа продолжает работать. Зависает и DMA и IT. Один из вариантов, что виснет что то по железу (потому что платы изготавливал сам, возможно что то по питанию).

2.Вторая мысль, что прерывание, в котором складываю принятые данные в буфер, прерывается прерыванием передачи. НУ или что то такое(сам уже запутался). Пробовал выставлять разные приоритеты DMA на прием и передачу - не помогло. Если делать односторонюю передачу все работает отлично. Как писал выше статус уарта находится в примем или прием передаче, осциллографом вижу что на входе есть данные, а прога не реагирует.

Думаю сегодня написать небольшой кодик для отладочной платы. У меня stm32 f3 discovery. Хочу использовать два уарта этой платы и передавать без радиоканала, что бы избежать косяков железа.

Ну и основная идея - хочу найти причину зависания, и потом просто сделать проверку и какой нить сброс. Рассказывайте как лучше и легче выявить проблему. Для отладки пользуюсь STMStudio.

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Проверьте питание хорошо. Может не качественное питание , что и приводит к сбоям. У меня не было подобных проблем с юартом.

Что может быть лучше в радиоэлектронике, чем программирование микроконтроллеров ?

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Только, что написал для отладочной платы - зависает. Вопрос в железе отпал.

отправку делаю в основном теле программы вот так

if(TX2_Ready == 1)
{
TX2_Ready = 0;
TX2[0] = START_BYTE;
TX2[1] = IRdist;
TX2[2] = (IRdist >> 8) & 0xFF;
TX2[3] = START_BYTE*2;
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)TX2, 4);
}

if(TX1_Ready == 1)
{
TX1_Ready = 0;
TX1[0] = START_BYTE;
TX1[1] = FocusRealPos;
TX1[2] = (FocusRealPos >> 8) & 0xFF;
TX1[3] = ZoomRealPos;
TX1[4] = (ZoomRealPos >> 8) & 0xFF;
TX1[5] = IrisRealPos;
TX1[6] = (IrisRealPos >> 8) & 0xFF;
TX1[7] = shutter*100;
TX1[8] = 2*START_BYTE;
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)TX1, 9);
}

сбрасываю флаг вот здесь

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
{
if(UartHandle == &huart1)
TX1_Ready = 1;
if(UartHandle == &huart2)
TX2_Ready = 1;
}

Что скажешь по такой реализации?

Не буду пока что сбрасывать куски инициализации.

Запускаю прием тоже в основном теле программы вот так

if((huart1.State == HAL_UART_STATE_READY) || (huart1.State == HAL_UART_STATE_BUSY_TX))
{
HAL_UART_Receive_IT(&huart1, (uint8_t *)RX1byte, 1);
}
if((huart2.State == HAL_UART_STATE_READY) || (huart2.State == HAL_UART_STATE_BUSY_TX))
{
HAL_UART_Receive_IT(&huart2, (uint8_t *)RX2byte, 1);
}

Изменено пользователем verlaty
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

странно, вроде все должно работать

а может виснет модем а не проц?

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Я сейчас все собрал на stm32f3discovery. Использую два уарта и просто соединил вход выход проводами, без модема.

Запускаю прием через IT по одному байту, когда получаю нужный мне байт, запускаю прием пачки через DMA .

Хотя пробовал по разному и через дма все и через it.

Изменено пользователем verlaty
Ссылка на комментарий
Поделиться на другие сайты

Литиевые аккумуляторы EVE Energy и решения для управления перезаряжаемыми источниками тока (материалы вебинара)

Опубликованы материалы вебинара Компэл, посвященного литиевым аккумуляторам EVE Energy и решениям для управления перезаряжаемыми источниками тока.

На вебинаре мы представили информацию не только по линейкам аккумуляторной продукции EVE, но и по решениям для управления ею, что поможет рассмотреть эти ХИТ в качестве дополнительной альтернативы для уже выпускающихся изделий. Также рассмотрели нюансы работы с производителем и сервисы, предоставляемые Компэл по данной продукции. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

в принципе не исключено что камень битый и модуль уарта виснет по железу при нагреве или плохой погоде на марсе. У меня похожая тема была с железякой на управлении сервомашинкой. ШИМ по странным причинам подвисал. Бился бился, ничего не помогало, а спустя неделю камень сам сдох. Поменял контроллер, залил ту же прошу, глюки пропали сами по себе

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

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

принимаю сейча вот так

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
 countDMARX1++;
 radio1 = 200;
 if(huart1.RxXferSize == 1)
 {
  if(RX1byte[0] == START_BYTE)
   HAL_UART_Receive_DMA(&huart1, (uint8_t *)RX1, 3);
  else
   HAL_UART_Receive_IT(&huart1, (uint8_t *)RX1byte, 1);
 }
 else
 {
  if (RX1[2] == 2*START_BYTE)
  {
   IRRX = (RX1[1] << 8) | RX1[0];
   RX1[2] = 0;
  }
  HAL_UART_Receive_IT(&huart1, (uint8_t *)RX1byte, 1);
 }
}

Здесь реализовал без буфера приемного, но делал раньше и с буфером куда просто через прерывания складывал по одному байту, а в основном теле расшифровывал данные. Эта реализация мне как то интереснее, потому что мне не страшно потерять данные. У меня просто идет постоянный поток данных позиции мотора, то есть я постоянно в реальном времени выдергиваю одну пачку.

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

можно еще попробовать уарт сменить на прием и передачу. Реверснуть то есть

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

в принципе не исключено что камень битый и модуль уарта виснет по железу при нагреве или плохой погоде на марсе. У меня похожая тема была с железякой на управлении сервомашинкой. ШИМ по странным причинам подвисал. Бился бился, ничего не помогало, а спустя неделю камень сам сдох. Поменял контроллер, залил ту же прошу, глюки пропали сами по себе

У меня несколько таких плат и плюс отладочная. Пробовал на разных, так что вопрос железа на 99,99% откидываю. Смущает то что односторонний обмен работает прекрасно. какая то фигня в прерываниях видать.
Ссылка на комментарий
Поделиться на другие сайты

Используй прерывание только на прием , передавай не в прерывании.

Что может быть лучше в радиоэлектронике, чем программирование микроконтроллеров ?

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

Используй прерывание только на прием , передавай не в прерывании.

Да, сейчас попробую. Раньше так пробовал, но программа очень тормозила. Точнее была видна задержка реакции исполнительного механизма, он двигался мелкими рывками.

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

чудес не бывает. Само по себе ничего не происходит. Значит чего то в коде не хватает. Есть еще версия оверрана на приеме, там буфер же на уарте есть и при некоторых условиях можно попасть на его переполнение, что вызовет ошибку ДМА. Может стоит поковырять обработчик ошибок на предмет залетания в него? Вернее на предмет возникновения флагов ошибок

Хотя на такой мизерной скорости это конечно маловероятно....

возможно стоит добавить флуш после каждого успешного приема пакета или байта (так и так попробовать)

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Золотые слова: Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Прочитал - Ржу.

А по сути вопроса - ты верно сказал. Чудес не бывает. Где допустил косячок. Надо как то искать ошибку.

Изменено пользователем verlaty
Ссылка на комментарий
Поделиться на другие сайты

Это мой код работы с MP3 плейером, я там флуш закоментил, потому как он не нужен был, но процедуру скопировал из более шустрого кода на залупленных вайфаях со скоростью по мегабиту каждый

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static short int UART1_rxindex = 0;
static short int UART2_rxindex = 0;
static uint8_t UART1_ErrorFlag = UART_PACKET_OK;
static uint8_t UART2_ErrorFlag = UART_PACKET_OK;
//__HAL_UART_FLUSH_DRREGISTER(&huart1); // Clear the buffer to prevent overrun
if (huart->Instance == USART1)
{
if (UART1_rxBuffer == 8 || UART1_rxBuffer == 127) // If Backspace or del
{
UART1_rxindex--;
if (UART1_rxindex < 0) UART1_rxindex = 0;
}
else if (UART1_rxBuffer == '\n') // If Enter
{
if (UART1_ErrorFlag == UART_PACKET_OK)
{
rxString[uART1_rxindex] = 0;
UART1_rxindex = 0;

mp3_command_processor(rxString); // command handler
}
else
{
while (huart1.State == HAL_UART_STATE_BUSY_TX_RX) {}; UART_Send ("ERROR > UART1 packet too long\n");
UART1_ErrorFlag = UART_PACKET_OK; // reset error state
}
}
else
{
if (UART1_rxBuffer != '\r' && UART1_ErrorFlag == UART_PACKET_OK) // Ignore return
{
rxString[uART1_rxindex] = UART1_rxBuffer; // Add that character to the string
UART1_rxindex++;
if (UART1_rxindex >= MAXSTRING) // User typing too much, we can't have commands that big
{
 UART1_ErrorFlag = UART_PACKET_TOO_LONG;
 UART1_rxindex = 0;
 rxString[uART1_rxindex] = '\000';
}
}
}
}
if (huart->Instance == USART2)
{
/* 7E FF 06 xx xx xx xx xx xx EF */
/* 0 1 2 3 4 5 6 7 8 9 */

if (UART2_rxindex == 0 && UART2_rxBuffer == 0x7E) // Start Of Packet! (0x7E)
{
mp3_recv_buf[uART2_rxindex] = UART2_rxBuffer; // Add that character to the string
//UART2_rxindex++;
UART2_ErrorFlag = UART_PACKET_OK;
}


else if (UART2_rxindex == 8 && UART2_rxBuffer == 0xEF) // If End Of Packet (0xEF)
{
UART2_rxindex++;
mp3_recv_buf[uART2_rxindex] = UART2_rxBuffer; // Add that character to the string
UART2_rxindex = 0;
UART2_ErrorFlag = UART_PACKET_CORRUPT;
UART2_callback_echo();
}

else if (UART2_ErrorFlag == UART_PACKET_OK)
{
if (UART2_rxindex >= MP3_MAX_STRING) // DF sends too much
{
UART2_ErrorFlag = UART_PACKET_CORRUPT;
UART2_rxindex = 0;

uint8_t i0 = mp3_recv_buf[0];
uint8_t i1 = mp3_recv_buf[1];
uint8_t i2 = mp3_recv_buf[2];
uint8_t i3 = mp3_recv_buf[3];
uint8_t i4 = mp3_recv_buf[4];
uint8_t i5 = mp3_recv_buf[5];
uint8_t i6 = mp3_recv_buf[6];
uint8_t i7 = mp3_recv_buf[7];
uint8_t i8 = mp3_recv_buf[8];
uint8_t i9 = mp3_recv_buf[9];

while (huart1.State == HAL_UART_STATE_BUSY_TX_RX) {}; UART_Send ("ERROR > UART2 packet corrupt\n");
}
else
{
UART2_rxindex++;
mp3_recv_buf[uART2_rxindex] = UART2_rxBuffer; // Add that character to the string
//UART2_rxindex++;
}
}
}
}

на отладочное эхо не обращаем внимания

коменты на инглише, потому как кейл коверкает родной наш

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Смущало то, что в HAL_UART_RxCpltCallback у меня большая обработка. Думал может там только флаги стоит сбрасывать, но смотрю у тебя в коде побольше всего будет. Так что надеюсь что и не в этом проблема.

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

колбэк этот кстати весьма тормозит на скоростях, но тут у меня всего пара прыжков по if и все. В другой версии под FreeRTOS этот колбэк просто кидает данные в очередь а операционка по мере появления свободного времени обрабатывает очередь пакетом за системный квант. Так быстрее и прерывания становятся более шустрыми. Данный код работал на 115200. На мегабите уже были пропуски

под ОС это уже выглядело так

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
//__HAL_UART_FLUSH_DRREGISTER(&huart1); // Clear the buffer to prevent overrun
xQueueSendToBackFromISR( myQueue01Handle, &UART1_rxBuffer, 0 );
//TODO - USART1 Recieve func
}
if (huart->Instance == USART2)
{
xQueueSendToBackFromISR( myQueue01Handle, &UART2_rxBuffer, 0 );

}
if (huart->Instance == USART3)
{
//xQueueSendToBackFromISR( myQueue01Handle, &UART3_rxBuffer, 0 );
//TODO - USART1 Recieve func
}
}

просто данные из трех уартов кидались в очередь и все

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Хочу перенести обработку принятых байтов в

void DMA1_Channel4_IRQHandler(void)
{
 /* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
 /* USER CODE END DMA1_Channel4_IRQn 0 */
 HAL_DMA_IRQHandler(&hdma_usart1_tx);
 /* USER CODE BEGIN DMA1_Channel4_IRQn 1 */
 /* USER CODE END DMA1_Channel4_IRQn 1 */
}

Подскажите как правильно сделать обработку по окончанию приема ( не по половине)

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

не пойму зачем это делать именно здесь

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

не пойму зачем это делать именно здесь

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

Все правильно. Выше уже писал, что хал уже делает все эти проверки. Это уже просто от безысходности всякие варианты ищу. А ты опять дал понять что не зачем туда лезть. Спасибо.

Голова уже квадратная стала. Надо думать как выявить причину, как отследить где затык.

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

да я вроде давал рецепты

лично всегда организую эхо в консоль компа, 99% ошибок позволяет отловить. Затыки тоже. Начните с этого.

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

можно через USB в режиме транслятора, но проще просто взять свободный уарт, повесить уарт-усб донгл и просто отправлять туда все символы без обработки, которые принимает основной порт. CP2102 или MCP430 чтото в этом роде. кмк так проще и быстрее. В тексте моей процедуры виден сброс отладочной инфы в порт

UART2_callback_echo();

там в функции просто отправка байта в другой порт по моему была, сейчас найду

void UART2_callback_echo (void)
{
char EchoBuffer[MP3_MAX_STRING * 5 + 1];

for (uint8_t i=0; i<MP3_MAX_STRING; i++)
{
sprintf(&EchoBuffer[i*5], "0x%02X", mp3_recv_buf[i]);
if (i>0) EchoBuffer[i*5-1] = ' ';
}
EchoBuffer[MP3_MAX_STRING * 5-1] = '\n';
EchoBuffer[MP3_MAX_STRING * 5] = '\000';
while (huart1.State == HAL_UART_STATE_BUSY_TX_RX) {}; UART_Send(EchoBuffer);
}

не совсем просто отправка, чутка с форматированием, чтобы строки разделять и информационные поля. Удобнее смотреть было цепочки байт

операции с константой подменяются компилятором на константы, так что умножений и вычитаний не производится по факту

текст посылки

void UART_Send (const char message[])
{
HAL_UART_Transmit_DMA(&huart1, (uint8_t*)message, strlen(message));
}

элементарно отправляется отформатированный массив (неявно передается по ссылке)

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

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