Форум РадиоКот https://radiokot.ru/forum/ |
|
TIM1 внутри обработчика прерывания DMA https://radiokot.ru/forum/viewtopic.php?f=59&t=196827 |
Страница 1 из 1 |
Автор: | Jebocom [ Пн фев 17, 2025 19:33:02 ] |
Заголовок сообщения: | TIM1 внутри обработчика прерывания DMA |
Доброго времени суток. Балуюсь с отладочной платой на процессоре stm32f407zgt6. Не могу понять почему не работает моя программа. Программа читает данные из UART и пишет на флешку. Смысл ее простой. Сначала я открываю файл и жду данных из UART. Потом я заполняю буфер (64 8-битных слова) данными из UART через DMA. Когда посылка с UART прекращается я должен закрыть файл. Сначала я делал закрытие файла вручную (по кнопке) и программа прекрасно работала. Я отправлял посылку с терминала и через секунду другую жал на кнопку на плате чтобы принудительно закрыть файл. Все данные без проблем приходили на microSD и я читал их через адаптер на компе. Я решил сделать закрытие файла через таймер TIM1. Тупо настроен таймер на 5с (отдельно проверял работу таймера на светодиоде). И в середине посылки и в конце посылки внутри обработчика прерывания DMA таймер обнуляется и программа по моим расчетам должна ждать 5с после последней полупосылки и закрывать файл. Но получается ерунда. Передается только одна первая половина буфера и файл закрывается. Я не могу понять почему так. До этого я пытался читать данные с микрофона INMP441 и отправлять в UART (все на CMSIS). Конец передачи тоже пытался определить таймером. И была такая же проблема с таймером. То есть что-то не так именно с включением и обнулением таймера внутри прерывания DMA. Хотелось бы разобраться что не так. Ниже основные настройки и функции моего кода: СпойлерКод: // Настройка таймера void TIM1_sets(void) { RCC -> APB2ENR |= RCC_APB2ENR_TIM1EN; TIM1->SMCR &= ~ TIM_SMCR_SMS; // биты SMS в 000 TIM1->PSC = 9999; // биты предделителя (PSC + 1) TIM1->ARR = 35999; // биты счетчика (ARR + 1) TIM1->DIER |= TIM_DIER_UIE; NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0); } // Обработчик прерывания DMA void DMA1_Stream1_IRQHandler(void) { /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */ if((DMA1->LISR&0x400)==0x400) { res = f_write(&testFile, &transmit_SDIO[0], 32, &testBytes); clean_mass(&transmit_SDIO[0]); TIM1 -> CNT = 1; if(cnt1==0) TIM1 -> CR1 |= TIM_CR1_CEN; TIM1 -> CNT = 1; DMA1->LIFCR |= 0x400; cnt1++; } else if((DMA1->LISR&0x800)==0x800) { res = f_write(&testFile, &transmit_SDIO[32], 32, &testBytes); clean_mass(&transmit_SDIO[32]); TIM1->CNT = 1; DMA1->LIFCR |= 0x800; } } // Обработчик таймера void TIM1_UP_TIM10_IRQHandler(void) { if((TIM1->SR&0x1) == 0x1) { f_close(&testFile); TIM1->SR &= 0xFFFFFFFE; DMA1_Stream1->CR &= 0xFFFFFFFE; } } // Функция очистки массива void clean_mass(uint8_t *mass) { int i=0; for(i=0; i<32; i++) mass[i]=0; } |
Автор: | Adrift [ Пн фев 17, 2025 20:46:59 ] |
Заголовок сообщения: | Re: TIM1 внутри обработчика прерывания DMA |
PSC таймера обновляется во время Update, т.е. первый раз таймер переполнится в 10000 раз быстрее. |
Автор: | Jebocom [ Пн фев 17, 2025 21:07:19 ] |
Заголовок сообщения: | Re: TIM1 внутри обработчика прерывания DMA |
PSC таймера обновляется во время Update, т.е. первый раз таймер переполнится в 10000 раз быстрее. Спасибо вам! У меня не получалось догадаться уже дня 2. Там я немного менял программу и были немного другие проявления, это сбивало меня с толку. Но вы четко сейчас прочитали мою проблему. Я сработал EGR-ом прерывание первое и дальше все работает штатно. Спасибо! |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |