Easyelectronics.ru

Электроника для всех
Текущее время: 23 окт 2019, 23:29

Часовой пояс: 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
Сообщения: 1027
У 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
Сообщения: 2867
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
Сообщения: 1108
Как уже написал ранее VladislavS

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

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

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


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

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


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

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2867
Гляньте осцилом или ЛА линию 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 часов


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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

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