STM32 USART2 per DMA Problem
I have a problem that maybe someone can help with. I've spend the last few days on this and I just don't understand why it's not working.
I have a STM32 where I want to send out a buffer over USART 2 using DMA to a RS485 chip that sends it to a Hyperterminal via FTDI cable. I had this working using USART without DMA... by just feeding the Register with the buffer one by one. So I know that the USART and the RS485 chip works. After inital problems i have gone to a simple example from ST Library and modified it but still can't get it to work. Here is my code.. I'm trying to continuosly send out data over USART2. The problem: It doesn't send at all... or only once.. and usually gets stuck here: while (DMA_GetFlagStatus(DMA1_FLAG_TC7) == RESET) Can anyone see what I'm doing wrong?/* Includes ------------------------------------------------------------------*/
&sharpinclude ''stm32f10x.h''/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
&sharpdefine TxBufferSize2 (countof(TxBuffer2) - 1)/* Private macro -------------------------------------------------------------*/
&sharpdefine countof(a) (sizeof(a) / sizeof(*(a)))/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure; uint8_t TxBuffer2[] = ''USART DMA Test Buffer\n''; uint8_t RxBuffer1[TxBufferSize2];/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); void DMA_Configuration(void);/* Private functions ---------------------------------------------------------*/
int main(void)
{ /* System Clocks Configuration */ RCC_Configuration(); /* NVIC configuration */ NVIC_Configuration();/* Configure the GPIO ports */
GPIO_Configuration();/* Configure the DMA */
DMA_Configuration();/* USART2 Initialization */
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_Tx; /* Configure USART2 */ USART_Init( USART2, &USART_InitStructure);/* Disable the DMA Interrupts
I do want to use the interrupts later (that's the whole point) but I want to get it working without them first. */ DMA_ITConfig( DMA1_Channel7, DMA_IT_TC|DMA_IT_HT|DMA_IT_TE, DISABLE) ;/* Enable USARTy DMA TX request */
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); /* Enable USART2 */ USART_Cmd(USART2, ENABLE);while(1)
{ /* Do I need to clear these flags before sending? */ DMA_ClearFlag(DMA1_FLAG_TC7); DMA_ClearFlag(DMA1_FLAG_HT7); DMA_ClearFlag(DMA1_FLAG_TE7); DMA_ClearITPendingBit( DMA1_IT_TC7); DMA_ClearITPendingBit( DMA1_IT_TE7); DMA_ClearITPendingBit( DMA1_IT_HT7); /* Enable USARTy DMA TX Channel Transmit should now start and usually sends one time. */ DMA_Cmd(DMA1_Channel7, ENABLE);/* Wait until USARTy TX DMA1 Channel Transfer Complete
It gets stuck here. Why is the flag not set? */ while (DMA_GetFlagStatus(DMA1_FLAG_TC7) == RESET) { } DMA_Cmd(DMA1_Channel7, DISABLE); //Do i need to this? }}
void RCC_Configuration(void)
{ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);/* Enable GPIO clock */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);/* Enable USART2 Clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); }void GPIO_Configuration(void)
{ GPIO_InitTypeDef GPIO_InitStructure;/* Enable the USART2 Pins Software Remapping */
//GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); /* Configure USART2 Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure);/* UART Direction */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIOA->BSRR = GPIO_Pin_1; //Set Pin High..TX }void NVIC_Configuration(void)
{ NVIC_InitTypeDef NVIC_InitStructure;/* Enable the USARTz Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }void DMA_Configuration(void)
{ DMA_InitTypeDef DMA_InitStructure;/* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
DMA_DeInit(DMA1_Channel7); DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer2; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = TxBufferSize2; 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_Channel7, &DMA_InitStructure);}
#dma #stm32-usart-interrupt-dma #dma-tc-interrupt-usart