Перепрограммирование начального адреса DMA с использованием микроконтроллера STM32F103 (Cortex-M3)

#c #linked-list #microcontroller #cortex-m3 #dma

#c #связанный список #микроконтроллер #cortex-m3 #dma

Вопрос:

Приведенный ниже обработчик IRQ удаляет из USART3 входящие 32 байта данных. Первое событие IRQ TC считывает первые 6 байтов, затем перепрограммирует механизм DMA для чтения последних 24 байтов. Второй TC перепрограммирует его для повторного чтения заголовка Этот метод позволит использовать сообщения переменной длины с использованием DMA. Однако, похоже, я не могу изменить начальный адрес DMA. Я хотел бы иметь возможность сохранять каждое сообщение в отдельном буфере, однако он просто перезаписывает первый буфер при получении каждого сообщения. Что я делаю не так? Микроконтроллер представляет собой STM32F103ze (Cortex-M3).

 void DMA1_Channel3_IRQHandler(void)
{
    uint32_t tmpreg = 0;
     /* Test on DMA1 Channel3 Transfer Complete interrupt */
     if(DMA_GetITStatus(DMA1_IT_TC3)) 
     {
          if (rx3_dma_state == RECIEVE_HEADER )
          {
               DMA_Cmd(DMA1_Channel3, DISABLE);/* Disable DMA1_Channel2 transfer*/
               // Now that have received the header. Configure the DMA engine to receive
               // the data portion of the message
               DMA_SetCurrDataCounter(DMA1_Channel3,26);
               DMA_Cmd(DMA1_Channel3, ENABLE);
          } else if ( rx3_dma_state == RECIEVE_MSG )
          {
               //CurrDataCounterEnd3 = DMA_GetCurrDataCounter(DMA1_Channel3);
               DMA_Cmd(DMA1_Channel3, DISABLE);
               /* Get Current Data Counter value after complete transfer */
               USART3_Rx_DMA_Channel_Struct->CMAR = (uint32_t) RxBuffer3LookUp[rx_buffer_index];
               DMA_SetCurrDataCounter(DMA1_Channel3, 6);
               DMA_Cmd(DMA1_Channel3,ENABLE);
               // Set up DMA to write into the next buffer slot (1 of 8)
                 rx_buffer_index;
               rx_buffer_index %= 8;
          }
          /* Clear DMA1 Channel6 Half Transfer, Transfer Complete and Global interrupt pending bits */
          DMA_ClearITPendingBit(DMA1_IT_GL3);
     }      
     // Update the state to read fake header of 6 bytes
     // or to read the fake data section of the message 26 bytes
       rx3_dma_state;
     rx3_dma_state %= 2;
     isr_sem_send(dma_usart3_rx_sem);
}
  

Ответ №1:

Вы говорите:

…перепрограммирует механизм DMA для чтения в последних 24 байтах.

но ваш код говорит:

DMA_SetCurrDataCounter(DMA1_Channel3,26);

Это правильно? Это 24 или 26?

Комментарии:

1. Я должен сказать «перепрограммирует механизм DMA для чтения в последних 26 байтах». Что он и делает. Однако передача DMA начинается с начала буфера, а не с 6 байтов в буфер. Также в соответствии с инструкцией if «rx3_dma_state == RECIEVE_MSG» я перепрограммирую регистр CMAR для запуска следующего DMA xfer в следующем слоте в буферном массиве, но это не подтверждается, поскольку передаваемые данные всегда отображаются в RxBuffer3 [0] . Буфер определяется как «char RxBuffer[8] [128]». У меня нет проблем с перенастройкой размера передачи DMA, только начального адреса DMA.