Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 не срабатывает прерывание TC при включенном HC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Porty
Добрый день.

STM32F100RB
включены АЦП, USART1 и DMA chanel4

Настроил DMA на передачу данных в усарт и нужен был режим работы в котором при передаче половины буфера срабатывало бы прерывание, а так же по завершению.
Всё срабатывает нормально до поры до времени. Ровно до тех пор пока обработчик прерывания не вызовется с запозданием и если во время обработки половины буфера выставится флаг TC ( передача завершена) то прерывание TC не срабатывает, в итоге прога не сбрасывает флаг занятости USART и ждёт у моря погоды вечно (или пока принудительно не будешь опрашивать счётчик отсавшихся транзакций в ДМА и по нему ориентироваться).

Исходники

Прерывание
CODE
void DMA1_Channel4_IRQHandler(void) //TX
{
if (DMA_GetFlagStatus(DMA1_FLAG_TE4))
{
DMA_ClearFlag(DMA1_FLAG_TE4 | DMA1_FLAG_GL4);
error_add(ERROR_UART_TX_DMA);
};

if (DMA_GetFlagStatus(DMA1_FLAG_HT4))
{
DMA_ClearFlag(DMA1_FLAG_HT4 | DMA1_FLAG_GL4);
};

if (DMA_GetFlagStatus(DMA1_FLAG_TC4))
{
DMA_ClearFlag(DMA1_FLAG_TC4 | DMA1_FLAG_GL4);
usart_transmit_complite = true;
};

usart_check_shift();
}


Настройка ДМА:
CODE


RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;

STRUCT_CLEAR(NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

DMA_DeInit(DMA1_Channel4);


DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel4);

STRUCT_CLEAR(DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) &(USART1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) data;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

DMA_InitStructure.DMA_BufferSize = size;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel4, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel4, DMA_IT_TE | DMA_IT_HT | DMA_IT_TC, ENABLE);
USART1->SR=0;
DMA_Cmd(DMA1_Channel4, ENABLE);



В чём может быть проблема?
Стоит ли флаг глобального прерывания канала очищать?
Или достаточно очистить конкретный флаг не глобального а HT | TC?
В документации от СТМ не нашол ответа
Flexz
Цитата
Стоит ли флаг глобального прерывания канала очищать?

В документации черным по белому написано:
Цитата
Clears the GIF, TEIF, HTIF and TCIF flags in the DMA_ISR register

Вот сбрасывается опоздавшее прерывание.
PS а зачем вообще GF трогаете? у вас же прерывание по нему не включено.
maksimp
То есть нужно просто убрать " | DMA1_FLAG_GL4" ?
Так:
CODE
void DMA1_Channel4_IRQHandler(void) //TX
{
if (DMA_GetFlagStatus(DMA1_FLAG_TE4))
{
DMA_ClearFlag(DMA1_FLAG_TE4);
error_add(ERROR_UART_TX_DMA);
};

if (DMA_GetFlagStatus(DMA1_FLAG_HT4))
{
DMA_ClearFlag(DMA1_FLAG_HT4);
};

if (DMA_GetFlagStatus(DMA1_FLAG_TC4))
{
DMA_ClearFlag(DMA1_FLAG_TC4);
usart_transmit_complite = true;
};

usart_check_shift();
}

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.