Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прием по USART1 через DMA1
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
MK2
Столкнулся с проблемой приема байтов по USART1 через DMA.
инициализация такая:

Код

USART_InitStructure.USART_BaudRate = 125000;
   USART_InitStructure.USART_WordLength = USART_WordLength_9b;
   USART_InitStructure.USART_StopBits = USART_StopBits_2;
     USART_InitStructure.USART_Parity = USART_Parity_Odd;
      USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
       USART_InitStructure.USART_Mode =/* */USART_Mode_Rx |  USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStructure);
  /* for speed */
  USART1->BRR = 0x0C << 4;     //125 кбит/с скорость

  DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART1_DR_Address;
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
   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_VeryHigh;
   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
   DMA_Init(DMA1_Channel5, &DMA_InitStructure);

         DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);


Код
       for(;i<=MAXSIZE_UART_BUF-1; i++)
             UART_Buf_Rx[i]=0;                            // очищаем буфер куда скадывает ДМА

      USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

      NVIC_SetPriority (DMA1_Channel5_IRQn, 14);
     NVIC_EnableIRQ (DMA1_Channel5_IRQn);
    
     NVIC_SetPriority (USART1_IRQn, 15);
     NVIC_EnableIRQ (USART1_IRQn);
    
     NVIC_SetPriority (DMA1_Channel4_IRQn, 13);
     NVIC_EnableIRQ (DMA1_Channel4_IRQn);
    
     DMA1_Channel5_IRQHandler();


Код
void DMA1_Channel5_IRQHandler(void)
{
    if (DMA_GetFlagStatus(DMA1_FLAG_TC5))
    {      
             DMA_Cmd(DMA1_Channel5, DISABLE);
     DMA_ClearFlag(DMA1_FLAG_TC5);
      DMA_ClearITPendingBit(DMA1_IT_TC5);
    
       flag_state_ready_dma = STOP_DMA_UART;
        Send_DMA_UART(STOP_TRANSFER_ATTRIBUTE); // послыаем 2 байта через ДМА канал 5 по USART1

    }
    else
    {
       DMA1_Channel5->CNDTR = MAXSIZE_UART_BUF;
        DMA1_Channel5->CMAR = (uint32_t) &UART_Buf_Rx[0];
        
          USART_Cmd(USART1, ENABLE);
           DMA1_Channel5->CNDTR = MAXSIZE_UART_BUF;
    
           DMA_Cmd(DMA1_Channel5, ENABLE);
            Send_DMA_UART(CONTINE_TRANSFER_ATTRIBUTE);    // послыаем 2 байта через ДМА канал 5 по USART1
            
  }
}


Инициализация проходит успешно, первый массив принимается, этот канал DMA останавливается. Массив обрабатывается и все дальше DMA не хочет запускаться
Счетчик стоит в 3FF, бит EN в 1 и все! ничего не идет. Так же используется канал 6 DMA на нем висит I2C прием. Камень F100C4, среда IAR 6.40

Что делать? Кто-нибудь сталкивался?
TAutomatic
Цитата(MK2 @ Sep 6 2012, 21:21) *
Столкнулся с проблемой приема байтов по USART1 через DMA.

Инициализация проходит успешно, первый массив принимается, этот канал DMA останавливается. Массив обрабатывается и все дальше DMA не хочет запускаться
Счетчик стоит в 3FF, бит EN в 1 и все! ничего не идет. Так же используется канал 6 DMA на нем висит I2C прием. Камень F100C4, среда IAR 6.40

Что делать? Кто-нибудь сталкивался?

Я использую другой камень, но я сталкнулся с аналогичной ситуацией: после приема нужного количества байт прерывание генерируется, но более не принимаются данные. Решил проблему путем частичной переинициализации DMA после приема. Тоесть там где я обработал очередной блок данных, снова устанавливаею в DMA нужное количество данных для приема и начальный адрес буфера приемника. Может это не совсем красиво, но работает. Другого способа я не нашел.
SSerge
Цитата(MK2 @ Sep 7 2012, 01:21) *
Инициализация проходит успешно, первый массив принимается, этот канал DMA останавливается. Массив обрабатывается и все дальше DMA не хочет запускаться

Ну, Вы же сами написали
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
напишите
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
тогда DMA должно автоматически перезапускаться.

Но тогда желательно разрешить прерывания ещё и на половине буфера, чтобы иметь время для обработки пришедших данных:
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE );
MK2
Цитата(SSerge @ Sep 7 2012, 15:32) *
Ну, Вы же сами написали
....
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
тогда DMA должно автоматически перезапускаться.


Пробовал и с DMA_Mode_Circular, не помогло... вернее помогло но в том случае если сразу перезапускать без обработки данных
в случае задержки включения DMA, аналогичная ситуация
Кстати, I2C нормально работает в режиме DMA_Mode_Normal.
В дальнейшем хотел DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE ) обработчик сделать, но все равно требуется отловить возникновение задержек в обработчике массива
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.