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

verlaty

Members
  • Постов

    47
  • Зарегистрирован

  • Посещение

Весь контент verlaty

  1. verlaty

    Stm32: Cubemx+Uart_Dma

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

    Stm32: Cubemx+Uart_Dma

    Золотые слова: Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Прочитал - Ржу. А по сути вопроса - ты верно сказал. Чудес не бывает. Где допустил косячок. Надо как то искать ошибку.
  3. verlaty

    Stm32: Cubemx+Uart_Dma

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

    Stm32: Cubemx+Uart_Dma

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

    Stm32: Cubemx+Uart_Dma

    принимаю сейча вот так 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); } } Здесь реализовал без буфера приемного, но делал раньше и с буфером куда просто через прерывания складывал по одному байту, а в основном теле расшифровывал данные. Эта реализация мне как то интереснее, потому что мне не страшно потерять данные. У меня просто идет постоянный поток данных позиции мотора, то есть я постоянно в реальном времени выдергиваю одну пачку.
  6. verlaty

    Stm32: Cubemx+Uart_Dma

    Да надо искать причину зависания. Делитесь опытом как это делать
  7. verlaty

    Stm32: Cubemx+Uart_Dma

    Я сейчас все собрал на stm32f3discovery. Использую два уарта и просто соединил вход выход проводами, без модема. Запускаю прием через IT по одному байту, когда получаю нужный мне байт, запускаю прием пачки через DMA . Хотя пробовал по разному и через дма все и через it.
  8. verlaty

    Stm32: Cubemx+Uart_Dma

    Только, что написал для отладочной платы - зависает. Вопрос в железе отпал. отправку делаю в основном теле программы вот так 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); }
  9. verlaty

    Stm32: Cubemx+Uart_Dma

    Разобрался с регистрами. Но не с проблемой. В принципе все эти проверки уже реализованы в HAL. Грубо говоря все это повторил отдельно, зависания остались. Реализовал все через прерывания - та же фигня. В общем выложу на обсуждение свои мысли. 1.Зависает прием UART(именно прием, так как передача продолжает работать), программа продолжает работать. Зависает и DMA и IT. Один из вариантов, что виснет что то по железу (потому что платы изготавливал сам, возможно что то по питанию). 2.Вторая мысль, что прерывание, в котором складываю принятые данные в буфер, прерывается прерыванием передачи. НУ или что то такое(сам уже запутался). Пробовал выставлять разные приоритеты DMA на прием и передачу - не помогло. Если делать односторонюю передачу все работает отлично. Как писал выше статус уарта находится в примем или прием передаче, осциллографом вижу что на входе есть данные, а прога не реагирует. Думаю сегодня написать небольшой кодик для отладочной платы. У меня stm32 f3 discovery. Хочу использовать два уарта этой платы и передавать без радиоканала, что бы избежать косяков железа. Ну и основная идея - хочу найти причину зависания, и потом просто сделать проверку и какой нить сброс. Рассказывайте как лучше и легче выявить проблему. Для отладки пользуюсь STMStudio.
  10. verlaty

    Stm32: Cubemx+Uart_Dma

    Твой проект компилириуется. Видать вопрос в том, что у меня другой проц. Буду искать решение....
  11. verlaty

    Stm32: Cubemx+Uart_Dma

    Да через Cube делал . Значит надо разобраться что использует куб вместо этих
  12. verlaty

    Stm32: Cubemx+Uart_Dma

    Искал через поиск где лежат эти слова в папке проекта. Так вот в своем проекте их вообще не нашел.
  13. verlaty

    Stm32: Cubemx+Uart_Dma

    Решил принимать один байт через прерывания, а распознав принятый байт как стартовый - принимать пачку через DMA. Передавать пачку тоже через DMA. За основу взял статьи http://dss-nk.ru/node/20 и http://dss-nk.ru/node/21. Твой пример похож на решение из этой статьи.Возник такой вопрос. При компиляции ругается на USART1->SR, USART_SR_RXNE и USART1->DR. В чем может быть проблема?
  14. verlaty

    Stm32: Cubemx+Uart_Dma

    Он не в CIRCULAR работает. void HAL_UART_MspInit(UART_HandleTypeDef* huart) { GPIO_InitTypeDef GPIO_InitStruct; if(huart->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* Peripheral clock enable */ __USART1_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Peripheral DMA init*/ hdma_usart1_rx.Instance = DMA1_Channel5; hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_rx.Init.Mode = DMA_NORMAL; hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; HAL_DMA_Init(&hdma_usart1_rx); __HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx); hdma_usart1_tx.Instance = DMA1_Channel4; hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_tx.Init.Mode = DMA_NORMAL; hdma_usart1_tx.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_usart1_tx); __HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx); /* Peripheral interrupt init*/ HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } }
  15. verlaty

    Stm32: Cubemx+Uart_Dma

    .Я занялся STM буквально месяца 3 назад. Пришлось перейти с ARDUINO, так как STM гораздо функциональнее. И не смотря на то что многие Профи плюются на HAL, и Cube и HAL мне очень сильно упростили знакомство. Наверное UART первая проблема, которая заставила меня капнуть куда то глубже. В проекте использую I2C, USB, ADC, PWM, переписывал некоторые библиотеки с ARDUINO и в принципе посидев денек другой все нормально запускалось и работало. Без сомнения в дальнейшем придется разбираться и капать глубже. Для отладки использую STLink (на базе STM32F3-Discovery) и STM Studio. А для проекта изготовил свои платы и устройства на том же процессоре.
  16. verlaty

    Stm32: Cubemx+Uart_Dma

    Да, именно зависон и хочется найти, Разобраться с причиной, а не заново переписывать. Спасибо Вам за помощь и советы.
  17. verlaty

    Stm32: Cubemx+Uart_Dma

    Сейчас попробую объяснить идею. Я принимаю по одному байту. Если принятый байт будет равен START_BYTE, тогда принимаем пачку из трех байт. Если третий контрольный байт равен стоповому байту ( для упрощения я сделал так: if(uartRX[2]==2*START_BYTE, на самом деле этот контрольный байт можно рассчитывать по передаваемой информации) , то мы дешифрируем пачку. Допустим мы пропустили байт и третий принятый байт не равен стоповому байту, тогда мы начинаем снова ловить стартовый байт и просто пропускаем битую пачку. программа не зависнет. В моем проекте идет дистанционное управление исполнительным устройством, то есть постоянно передается информация для управления несколькими механизмами. Если я потеряю одну пачку, ничего страшного не произойдет. Дело в том что я пробовал все это реализовать и через прерывания и складывать в буфер по одному байту а уже в основной программе разбирать принятую информацию, но косячек все равно вылазил. Сейчас попробую работать напрямую с регистрами, так как посоветовал artos5. Повторюсь, если вы знаете уже готовые варианты двухстороннего обмена по уарт (что бы не изобретать велосипед), буду очень признателен.
  18. verlaty

    Stm32: Cubemx+Uart_Dma

    если пропадет.... Он принимает допустим 9 байт, и 9 - это контрольный, если пачка целай и не битая он ее дешифрирует, иначе просто принимает след байт, в этом случае программа не зависнет. Но суть то вопроса в том что он просто зависает. Я принимал и в прерываниях и в дма....результат один и тот же. А протокол обмена - это просто одно из решений. Спасибо. Попробую что нить использовать из него
  19. verlaty

    Stm32: Cubemx+Uart_Dma

    Да такую цель и преследовал. Принимать по байту, а если приходит нужный ( это или команда управления устройством или команда настройки устройства) то обрабатываю уже по типу входящей информации. Если я знаю что должно прийти 9 байт, то зачем по каждому байту обрабатывать в прерывании. Если есть код, покажи как ты принимаешь через прерывания. Повторюсь что в одну сторону обмен идет без проблем, а прием передача - подвисает.
  20. Не буду утверждать именно про этот дисплей, просто озвучил информацию что пользуюсь такой, Что она может читайте по ссылке, если надо могу помочь с настройкой.
  21. А если так мигать, без delay HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, ((HAL_GetTick() / 200) % 2));
  22. verlaty

    Stm32: Cubemx+Uart_Dma

    Есть такая задача. Надо организовать двухсторонний обмен данными между двумя устройствами по радиоканалу. Радиомодемы подключаются по UART. Решил использовать UART DMA режим. Настройку и сборку проекта делал через Cube. Проблема заключается в следующем: после некоторого времени работы устройства прекращается прием данных. В тоже время если на одном устройстве оставить только передающую, а на другом приемную часть программы – все прекрасно работает. Прошу помощи в решении этого вопроса (к сожалению большого опыта в программировании этих процессоров не имею). Может подскажите готовое решение для двухстороннего обмена данными по UART. Для примера и обсуждения выкладываю часть программы одного устройства (на втором все организовано аналогично, есть небольшие отличия в обработке принимаемого сигнала). Инициализация UART /* USART1 init function */ void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 19200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED ; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&huart1);} Инициализация DMA void MX_DMA_Init(void) { /* DMA controller clock enable */ __DMA1_CLK_ENABLE(); __DMA2_CLK_ENABLE(); /* DMA interrupt init */ HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0); // DMA1_Channel4 - передача uart HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn); HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0); // DMA1_Channel5 – прием UART HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); HAL_NVIC_SetPriority(DMA2_Channel1_IRQn, 0, 0);// DMA2_Channel1 – ADC HAL_NVIC_EnableIRQ(DMA2_Channel1_IRQn);} В main делаю отправку данных вот так: if(TX_Ready == 1) { TX_Ready = 0; HAL_UART_Transmit_DMA(&huart1, (uint8_t *)uartTX, 9); } Флаг сбрасывается вот здесь TX_Ready: void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) { TX_Ready = 1; } Прием данных делаю вот здесь: void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) { if(huart1.RxXferSize == 1) { if(RXbyte[0] == START_BYTE) HAL_UART_Receive_DMA(&huart1, (uint8_t *)uartRX, 3); else HAL_UART_Receive_DMA(&huart1, (uint8_t *)RXbyte, 1); } else { if (uartRX[2] == 2*START_BYTE) IRdist = (uartRX[1] << 8) | uartRX[0]; HAL_UART_Receive_DMA(&huart1, (uint8_t *)RXbyte, 1); } } Немного опишу теорию приема. Запускаю прием одного байта командой HAL_UART_Receive_DMA(&huart1, (uint8_t *)RXbyte, 1). Если принятый байт равен стартовому байту в отправленной пачке, то принимаю пачку из 3 байт HAL_UART_Receive_DMA(&huart1, (uint8_t *)uartRX, 3). Если не равен, снова принимаю байт (ожидаю нужный мне байт) Если принял пачку и контрольный третий байт равен ожидаемому, то формирую сигнал IRdist и снова принимаю один байт. if(huart1.RxXferSize == 1) этим смотрю что я принимал один байт или пачку. В ответном устройстве аналогично принимается пачка из 9 байт, а отправляется 3 байта.
  23. Если актуально - использую U8Glib. Вся информация есть тут https://github.com/olikraus/u8glib. Использую на STM32f3. есть переделанные файлы.
×
×
  • Создать...