Доброго времени суток. Балуюсь с отладочной платой на процессоре 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;
}