amiller 2 January 20 Posted January 20 (edited) · Report post Столкнулся с интересной штукой. Если разрешаю transfer complete interrupt, то сразу после разрешения канала DMA улетаю в прерывание. Какие бы флаги не сбрасывал и задержки не вставлял. А если сначала разрешаю прерывание по половине буфера, а потом до конца, то всё ок. Кто нибудь сталкивался и как объехать? Код прерывания сейчас такой: void DMA1_Stream0_IRQHandler(void) { int32u temp; temp = DMA1->LISR; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream if (temp & DMA_LISR_HTIF0) { setmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); clrmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); } else { clrmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); setmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); Prn.dma_reset = true; } } А перезапуск происходит так: clrmask(DMA1_Stream0->CR, DMA_SxCR_EN); DMA1_Stream0->NDTR = Prn.size; DMA1_Stream0->M0AR = (int32u)Prn.ptr_x; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream setmask(DMA1_Stream0->CR, DMA_SxCR_EN); Edited January 20 by haker_fox Пользуйтесь инструментом для оформления кода. Quote Share this post Link to post Share on other sites More sharing options...
Variant99 0 January 20 Posted January 20 · Report post А какой флаг у прерывания выставляется при возникновении прерывания? Возможно, фраг ошибки конфигурации? Quote Share this post Link to post Share on other sites More sharing options...
amiller 2 January 21 Posted January 21 · Report post Нет, именно TCIF. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 83 January 22 Posted January 22 · Report post В 20.01.2023 в 17:01, amiller сказал: Код прерывания сейчас такой: void DMA1_Stream0_IRQHandler(void) { int32u temp; temp = DMA1->LISR; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream if (temp & DMA_LISR_HTIF0) { setmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); clrmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); } else { clrmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); setmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); Prn.dma_reset = true; } } Не знаю как там в STMH743, но в предыдущих STM32F4 в мануале был явный запрет на модификацию битов регистра CR при включенном DMA-канале. В STMH743 такого запрета нет? Или вы просто не читали мануал? Советую всё же прочитать его, до того как начинать быдлокодить. Да и вообще - на кой тут все эти игры с запретом/разрешением TCIE, HTIE??? В нормальном коде нужные прерывания разрешают перед разрешением DMA-канала и больше их не трогают до останова работы DMA-канала. Также - очень полезно разрешать прерывание по ошибке DMA-канала (TEIE или как там оно называется в STMH743). И обрабатывать его в ISR. Чтобы хотя-бы быть в курсе возникающих ошибок. В 20.01.2023 в 17:01, amiller сказал: А перезапуск происходит так: clrmask(DMA1_Stream0->CR, DMA_SxCR_EN); DMA1_Stream0->NDTR = Prn.size; DMA1_Stream0->M0AR = (int32u)Prn.ptr_x; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream setmask(DMA1_Stream0->CR, DMA_SxCR_EN); Во-первых: Запрет работающего DMA-канала - само по себе крайне плохое решение. И не следует такое делать без реальной необходимости. Во-вторых: Не знаю, что у вас делается внутри clrmask(), но думается, что вы также не прочитали мануал на предмет правильной последовательности зпрета работающего DMA-канала (опять-же - сужу по мануалу на STM32F4; на STMH743 не читал, но вряд-ли там сделано иначе). В 20.01.2023 в 17:01, amiller сказал: Если разрешаю transfer complete interrupt, то сразу после разрешения канала DMA улетаю в прерывание. Что у вас там происходит - тут нет телепатов угадывать ваш код инициализации и запуска DMA-передачи. Видимо делаете это криво. PS: И если задаёте вопрос, то правило хорошего тона: Приводить исходный код всех используемых функций/макросов и типы всех переменных вашего кода. Ещё раз - телепатов тут нет это угадывать. Quote Share this post Link to post Share on other sites More sharing options...