Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Параллельная работа нескольких каналов DMA

Ср апр 25, 2018 12:55:16

Доброго времени суток! Возникла необходимость запустить 3 ЮСАРТА на STM32, желательно через DMA. С одним каналом нет проблем. Не понятно, как запустить параллельно несколько каналов. Это вообще возможно?
ПС. Собственно, на прерываниях тоже вполне устроит. Но пока не получается настроить. Код следующий:
Код:
//--- Конфиг USART1 ----------
USART1->BRR = 0x88C;
USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_TCIE;
NVIC_SetPriority (USART1_IRQn, 2);
NVIC_EnableIRQ(USART1_IRQn);
//----------

void put_char_rs232(uint8_t data){
   while(!(USART1->SR & USART_SR_TC));
   
   USART1->DR = data;
}


void USART1_IRQHandler(){
   if (USART1->SR & USART_SR_RXNE){
      USART1->SR&=~USART_SR_RXNE;
      uart_data = USART1->DR;
   }

   if(USART1->SR & USART_SR_TC){
      USART1->SR&=~USART_SR_TC;
      if(UartAnswers--)   USART1->DR = 'S';
   }
}





В бесконечном цикле с частотой 10 Гц посылаю
Код:
UartAnswers = 2;
put_char_rs232('B');


В порт летит постоянно 0x28. Остальная программа не выполняется. Такое ощущение, что где-то не сброшены флаги.

Re: Параллельная работа нескольких каналов DMA

Ср апр 25, 2018 13:09:04

Для каждого Usart своя пара каналов, только их номера и меняются, потому не вижу в чем у тебя вообще проблема, если один канал работает...

Re: Параллельная работа нескольких каналов DMA

Ср апр 25, 2018 13:20:50

Проблема послать одновременно

Добавлено after 1 minute 21 second:
При работе на разных потоках никаких проблем нет, на разных каналах - есть.

Добавлено after 3 minutes 4 seconds:
Настройка DMA
Код:
void Start_DMA_USART1_Tx (uint8_t am_bytes, uint8_t *m_data){
      
    DMA2_Stream7->CR = 0;                           // Отключаем поток. Нужно обеспечить, чтобы не была вызвана
                                                                              // функция Start_DMA_USART3_Rx, когда предыдущая передача
                                                    // еще не завершилась, иначе данные будут потеряны.
    while(DMA2_Stream7->CR & DMA_SxCR_EN);          // ждем пока поток эффективно остановится
                                                    // поток готов к настройке
    DMA2_Stream7->PAR = (uint32_t) & USART1->DR;    // устанавливаем адрес периферии
    DMA2_Stream7->M0AR = (uint32_t) m_data;
    DMA2_Stream7->NDTR = am_bytes;                           // количество байт
 
    DMA2_Stream7->CR = DMA_SxCR_EN | DMA_SxCR_DIR_0 | DMA_SxCR_CHSEL_2 | DMA_SxCR_MINC | DMA_SxCR_TCIE ;   
   
    USART1->CR3 |= USART_CR3_DMAT;
      NVIC_EnableIRQ( DMA2_Stream7_IRQn );
}

void Start_DMA_USART6_Tx (uint8_t am_bytes, uint8_t *m_data){
      
    DMA2_Stream7->CR = 0;                           // Отключаем поток. Нужно обеспечить, чтобы не была вызвана
                                                                              // функция Start_DMA_USART3_Rx, когда предыдущая передача
                                                    // еще не завершилась, иначе данные будут потеряны.
    while(DMA2_Stream7->CR & DMA_SxCR_EN);          // ждем пока поток эффективно остановится
                                                    // поток готов к настройке
    DMA2_Stream7->PAR = (uint32_t) & USART6->DR;    // устанавливаем адрес периферии
    DMA2_Stream7->M0AR = (uint32_t) m_data;
    DMA2_Stream7->NDTR = am_bytes;                           // количество байт
 
    DMA2_Stream7->CR = DMA_SxCR_EN | DMA_SxCR_DIR_0 | DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_0 |DMA_SxCR_MINC | DMA_SxCR_TCIE ;   
   
    USART6->CR3 |= USART_CR3_DMAT;
      NVIC_EnableIRQ( DMA2_Stream7_IRQn );
}


Запуск отправки данных (с частотой 10 Гц)
Код:
Start_DMA_USART1_Tx(rec_bt, config_6);   
         Start_DMA_USART6_Tx(rec_bt, config_6);
         
         DMA2_Stream7->CR |= DMA_SxCR_EN;



Добавлено after 4 minutes 30 seconds:
При этом по USART1 прилетает хотя бы 1й байт массива, а вот по USART6 вообще тишина

Re: Параллельная работа нескольких каналов DMA

Ср апр 25, 2018 13:21:10

Ты хочешь прям совсем синхронно 3 канала запустить?

Re: Параллельная работа нескольких каналов DMA

Ср апр 25, 2018 13:27:14

Совсем синхронно не получится, не ПЛИС всё таки. Хотя бы друг за другом - отправил посылку по USART1, следом эту же посылку отправляю по USART6. Засовывал уже даже в прерывание по окончанию передачи DMA отправку по USART6 - раз в 10 минут чё-то выкидывает.

Добавлено after 2 minutes 10 seconds:
О, даже раз в 10 минут перестал выкидывать

Re: Параллельная работа нескольких каналов DMA

Ср апр 25, 2018 13:32:36

Мк какой? USART6 без USART1 я так понимаю нормально работает?

Re: Параллельная работа нескольких каналов DMA

Ср апр 25, 2018 13:36:52

STM32f401, да, один без другого работает нормально

Добавлено after 1 minute 58 seconds:
Всё, нашёл проблему. Как обычно, невнимательность...

Добавлено after 1 minute 31 second:
Код:
void DMA2_Stream7_IRQHandler(void){
   if( DMA2->HISR & DMA_HISR_TCIF7){
      DMA2->HIFCR = DMA_HIFCR_CTCIF7;
   
      if((DMAState)<1){
         Start_DMA_USART6_Tx(rec_bt, config_6);
         DMAState++;
      }
      else{
         DMA2_Stream7->CR &=~ DMA_SxCR_EN;
      }
   
        }
}


В бесконечном цикле не обнулял DMAState. Спасибо, что уделили время!
Ответить