4th 0 30 июня, 2016 Опубликовано 30 июня, 2016 · Жалоба Вечер добрый. Чисто в учебных целях было решено оцифровывать сигнал с 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)); //заходит сюда только в пошаговом режиме } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Immortal_Buka 0 1 июля, 2016 Опубликовано 1 июля, 2016 · Жалоба в RM написано, что есть "peripheral-to-peripheral transfers" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
4th 0 1 июля, 2016 Опубликовано 1 июля, 2016 · Жалоба в RM написано, что есть "peripheral-to-peripheral transfers" Предлагаете сразу через DMA копировать данные. Понимаю. Но это не совсем подходящее решение. Предполагается, что перед копированием в буфер UARTa, может выполнять работа с данными. Поэтому делал изначально в прерывании. Это не решает задачу полностью, но все-равно спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
4th 0 1 июля, 2016 Опубликовано 1 июля, 2016 · Жалоба Найдено решение: В обработчике прерывания 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: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lost_Viking 0 5 апреля, 2017 Опубликовано 5 апреля, 2017 · Жалоба у тебя, скорее всего, просто не успевали отправиться данные. ацп, наверняка, шпарил на всю катушку, быстрее, чем пересылка usart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться