Easyelectronics.ru

Электроника для всех
Текущее время: 26 май 2020, 18:23

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
 Заголовок сообщения: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 10 сен 2019, 16:12 
Заглядывает иногда

Зарегистрирован: 21 фев 2012, 10:14
Сообщения: 79
Доброго дня всем.
Решил перейти со 103 на 303 камень.
Начал переделывать код.
Отправка и чтение по прерыванию проходит нормально.
А вот отправка с ДМА нет.

Иницализация
Код:
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
    DMA_InitTypeDef   DMA_InitStructure;
   
    /* Enable USART3, DMA1 and GPIOB clock                                   */
    RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_GPIOB, ENABLE );
    RCC_APB1PeriphClockCmd ( RCC_APB1Periph_USART3, ENABLE );
    RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_DMA1, ENABLE );
   
    /* Configure DMA1 Chanel 2 - для для передачи данных                     */
    DMA_DeInit ( DMA1_Channel2 );
    DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t )&(USART3->TDR);
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)&rs485_data.buffer_tx[0];
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize         = TX_BUF_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_Circular;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
    DMA_Init ( DMA1_Channel2, &DMA_InitStructure );
    //DMA_Cmd ( DMA1_Channel2, ENABLE );
   
    /* Connect PB10 to USART3_Tx                                             */
    GPIO_PinAFConfig ( GPIOB, GPIO_PinSource10, GPIO_AF_7);
    /* Connect PB11 to USART3_Rx                                             */
    GPIO_PinAFConfig ( GPIOB, GPIO_PinSource11, GPIO_AF_7);
   
    /* Configure the GPIOs                                                   */
    /* Configure USART3 Tx (PB.10)  as alternate function push-pull          */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init ( GPIOB, &GPIO_InitStructure );
    /* Configure USART3 Rx (PB.11) as alternate function push-pull           */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;
    GPIO_Init ( GPIOB, &GPIO_InitStructure );
   
    USART_InitStructure.USART_BaudRate            = 115200;
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_Parity              = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init ( USART3, &USART_InitStructure );

    /* Enable the USART3 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init ( &NVIC_InitStructure );

    USART_ITConfig ( USART3, USART_IT_RXNE, ENABLE );
    USART_ClearITPendingBit( USART2, USART_IT_RXNE );
   
    USART_DMACmd ( USART3, USART_DMAReq_Tx, ENABLE );
    DMA_ITConfig ( DMA1_Channel2, DMA_IT_TC, ENABLE );
    //DMA_ITConfig ( DMA1_Channel2, DMA_IT_HT, ENABLE );
    //DMA_ITConfig ( DMA1_Channel2, DMA_IT_TE, ENABLE );
//    USART_DMACmd ( USART3, USART_DMAReq_Rx, ENABLE );
//    DMA_ITConfig ( DMA1_Channel3, DMA_IT_TC, ENABLE );
   
    NVIC_EnableIRQ ( DMA1_Channel2_IRQn );
//    NVIC_EnableIRQ ( DMA1_Channel3_IRQn );
    NVIC_EnableIRQ ( USART3_IRQn);
    USART_Cmd ( USART3, ENABLE );
}



Прерывание ДМА по приему
Код:
void DMA1_Channel2_IRQHandler ( void )
{
    /* Если обмен завершен                                                   */
    if ( DMA1->ISR & DMA_ISR_TCIF2 ) {
        DMA_ClearITPendingBit ( DMA1_IT_TC2 );
        DMA_Cmd ( DMA1_Channel2, DISABLE );
        rs485_data.Status_Tx = tx_End;
        //rs485_dir_off();
        RECEIVE_ON;
    }
    /* Если передана половина буфера                                         */
    if ( DMA1->ISR & DMA_ISR_HTIF2 ) {
        DMA_ClearITPendingBit ( DMA1_IT_HT2 );
        rs485_data.Status_Tx = tx_Wait;
    }
    /* Если произошла ошибка при обмене                                      */
    if ( DMA1->ISR & DMA_ISR_TEIF2 ) {
        DMA_ClearITPendingBit ( DMA1_IT_TE2 );
        DMA_Cmd ( DMA1_Channel2, DISABLE );
        rs485_data.Status_Tx = tx_Error;
        //rs485_dir_off();
        RECEIVE_ON;
    }
}


Отправка данных
Код:
    TRANSMITE_ON;
    DMA_Cmd ( DMA1_Channel2, DISABLE );
    //DMA1_Channel2->CCR  &= ( uint16_t )(~DMA_CCR_EN);
    DMA1_Channel2->CNDTR = 2;
    DMA_Cmd ( DMA1_Channel2, ENABLE );
    //DMA1_Channel2->CCR  |= DMA_CCR_EN;


При отправке данных в терминалке вижу абсолютно другое.
В чем косяк не могу понять.
Кто либо сталкивался с подобным?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 10 сен 2019, 16:49 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 1434
У f303 источник тактировпния USART может быть разный. RCC->CFGR3 проверь.

Кстати, я вижу у тебя rs-485. Переводить его в приём когда закончил работу dma рано. Надо дождаться TC в uart. И вообще, у 303 есть аппаратный r/w для rs-485.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 11 сен 2019, 07:39 
Заглядывает иногда

Зарегистрирован: 21 фев 2012, 10:14
Сообщения: 79
VladislavS писал(а):
У f303 источник тактировпния USART может быть разный. RCC->CFGR3 проверь.

Кстати, я вижу у тебя rs-485. Переводить его в приём когда закончил работу dma рано. Надо дождаться TC в uart. И вообще, у 303 есть аппаратный r/w для rs-485.


С аппаратным DE немного промахнулся ( плату разводил под L4xx).Насчет перевода не согласен. Выставляется в прерывание ДМА по окончании передачи.
Тактирование посмотрю, но проста передача байта по ожиданию флага - проходит и чтение в прерывание проходит. Значит тактирование USART в норме


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 11 сен 2019, 08:12 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2870
elesy_ural писал(а):
Насчет перевода не согласен. Выставляется в прерывание ДМА по окончании передачи.

Флаг TC у DMA означает лишь то, что DMA закончил трансфер данных в DR USART. Данные при этом еще не ушли физически. Алгоритм должен быть следующий - дождались TC по DMA, включили TC у USART, дождались TC у USART и лишь затем изменили состояние DE/RO на rs485.
На F103 выглядит так:
Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 11 сен 2019, 08:21 
Старожил

Зарегистрирован: 16 окт 2013, 01:27
Сообщения: 1447
Как уже написал ранее VladislavS

У 303 внимательно смотрите тактирование, разные USART тактируются с разных шин, причем коэффициенты делителей у них отличаются, сейчас нет под рукой проекта на 32F373 но помню несколько часов искал в чем причина, пока внимательно не изучил страничку со схемой тактирования.

У вас CNTDR=2; всего 2 байта отправляете или это ошибка ?
Как реализован кольцевой буфер ? может быть там ошибка.

P\S
По приему можно использовать прерывание по таймауту после подьема флага IDLE, вам все равно между посылками паузу ждать надо но это конечно если у вас ModBus RTU.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 11 сен 2019, 08:46 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 1434
elesy_ural писал(а):
Насчет перевода не согласен.
Ну тогда расчехляем логический анализатор, он же в тумбочке за банкой кофе у любого эмбеддера лежит, и смотрим что там передаётся. А то избаловались, по любому чиху портянки свои HAL-овские на форум вывешивать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 11 сен 2019, 09:37 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2870
Гляньте осцилом или ЛА линию RS485 R/W и TxD на USART. Там еще байта полтора-два останется на передачу, т.к. TC у DMA случится, когда DR опустеет, однако при этом сдвиговый выходной регистр USART еще передаёт предпоследний байт.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 11 сен 2019, 14:55 
Заглядывает иногда

Зарегистрирован: 21 фев 2012, 10:14
Сообщения: 79
sed_alex писал(а):
Как уже написал ранее VladislavS

У 303 внимательно смотрите тактирование, разные USART тактируются с разных шин, причем коэффициенты делителей у них отличаются, сейчас нет под рукой проекта на 32F373 но помню несколько часов искал в чем причина, пока внимательно не изучил страничку со схемой тактирования.

У вас CNTDR=2; всего 2 байта отправляете или это ошибка ?
Как реализован кольцевой буфер ? может быть там ошибка.

P\S
По приему можно использовать прерывание по таймауту после подьема флага IDLE, вам все равно между посылками паузу ждать надо но это конечно если у вас ModBus RTU.



Да всего два байта. Для отладки


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F303CC USART3 DMA передача
СообщениеДобавлено: 11 сен 2019, 14:56 
Заглядывает иногда

Зарегистрирован: 21 фев 2012, 10:14
Сообщения: 79
Hold писал(а):
Гляньте осцилом или ЛА линию RS485 R/W и TxD на USART. Там еще байта полтора-два останется на передачу, т.к. TC у DMA случится, когда DR опустеет, однако при этом сдвиговый выходной регистр USART еще передаёт предпоследний байт.



Спасибо. Гляну


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: VladislavS


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB