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

4th

Новичок
  • Постов

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

  • Посещение

Репутация

0 Обычный
  1. DMA(UART+ADC) ARM

    Найдено решение: В обработчике прерывания DMA(UART) было добавлено: проверку условия срабатывания прерывания: if( HAL_DMA_GetState(&hdma_usart2_tx)==HAL_DMA_STATE_READY) {...} принудительную остановку передачи в DMA по UART - HAL_UART_DMAStop(&huart2); запуск АЦП - HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_buffer, sizeof(adc_buffer)); Следует отметить что без принудительной остановки HAL_UART_DMAStop(&huart2) - отказывается работать. Также следует отметить что условий срабатывания прерывания DMA(UART) уйма, точнее сказать на любое состояние DMA: typedef enum { HAL_DMA_STATE_RESET = 0x00, /*!< DMA not yet initialized or disabled */ HAL_DMA_STATE_READY = 0x01, /*!< DMA initialized and ready for use */ HAL_DMA_STATE_READY_HALF = 0x11, /*!< DMA Half process success */ HAL_DMA_STATE_BUSY = 0x02, /*!< DMA process is ongoing */ HAL_DMA_STATE_TIMEOUT = 0x03, /*!< DMA timeout state */ HAL_DMA_STATE_ERROR = 0x04, /*!< DMA error state */ }HAL_DMA_StateTypeDef; Поэтому в прерывании DMA(UART) следует выполнять проверку на причину возникновения прерывания. Листинг основных кусков кода ниже: int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_USART2_UART_Init(); HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_buffer, sizeof(adc_buffer)); while (1) {} } void DMA1_Channel1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_adc1); uart_buffer[0]=adc_buffer>>8; uart_buffer[1]=adc_buffer; HAL_UART_Transmit_DMA(&huart2, uart_buffer, sizeof(uart_buffer)); HAL_ADC_Stop_DMA(&hadc1); } void DMA1_Channel7_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart2_tx); if( HAL_DMA_GetState(&hdma_usart2_tx)==HAL_DMA_STATE_READY){ HAL_UART_DMAStop(&huart2); HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_buffer, sizeof(adc_buffer)); } } Думаю такое решение будет кому-то полезным :tongue:
  2. DMA(UART+ADC) ARM

    Предлагаете сразу через DMA копировать данные. Понимаю. Но это не совсем подходящее решение. Предполагается, что перед копированием в буфер UARTa, может выполнять работа с данными. Поэтому делал изначально в прерывании. Это не решает задачу полностью, но все-равно спасибо.
  3. DMA(UART+ADC) ARM

    Вечер добрый. Чисто в учебных целях было решено оцифровывать сигнал с ADC1, сохранять его в uint16_t переменной и в прерывании от DMA(ADC1) копировать результат в массив uint8_t mass[2] и запускать отправку по UART через тот же DMA. А в прерывании DMA(UART) запускать преобразование АЦП заново. И так по кругу... В режиме отладки при включенных бряках на DMA1_Channel1_IRQHandler (АЦП) и DMA1_Channel1_IRQHandler (UART) этот результат достигается. Но при роботе в реальном времени (ну или без брейкпоинтов) происходит следующее: из main запускается HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_buffer, sizeof(adc_buffer)); при завершении преобразования уходит в прерывание DMA1_Channel1_IRQHandler; копирует данные из adc_buffer в uart_buffer[]; запускает посылку по UART: HAL_UART_Transmit_DMA(&huart2, uart_buffer, sizeof(uart_buffer)); и останавливает АЦП: HAL_ADC_Stop_DMA(&hadc1); после этого он должен попасть в обработчик завершения передачи DMA1_Channel7_IRQHandler, но этого не происходит (но происходит только при пошаговой отладке) В общем не могу понять что мешает ему работать как задумано. Ниже куски кода, которые наверняка захотят увидеть: int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_USART2_UART_Init(); HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_buffer, sizeof(adc_buffer)); while (1) { } } void DMA1_Channel1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_adc1); uart_buffer[0]=adc_buffer>>8; uart_buffer[1]=adc_buffer; HAL_UART_Transmit_DMA(&huart2, uart_buffer, sizeof(uart_buffer)); HAL_ADC_Stop_DMA(&hadc1); } void DMA1_Channel7_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart2_tx); HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_buffer, sizeof(adc_buffer)); //заходит сюда только в пошаговом режиме }
×
×
  • Создать...