2008-10-16 05:44 AM
stm32 receive data via serial port problem
2011-05-17 03:47 AM
The only operational difference between your code and mine is checking for IDLE, I don't use fwlib so my actual code is quite different.
I believe you must read the status register (the one with RXNE in it) for every data byte. Reading the status clears some hardware bits, if you don't do that then you get overrun errors (which you are ignoring) and no new data.2011-05-17 03:47 AM
Greetings to everybody!
My english rather poor. I have serial communication program which send several command of random byte length.. When program send a command, my stm32 module receive only first 1byte and can not second byte. I code as follow. ............... USART_InitStructure.USART_BaudRate = DEFAULT_BAUDRATE; 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_ClockInitStructure.USART_Clock = USART_Clock_Enable; USART_ClockInitStructure.USART_CPOL = USART_CPOL_High; USART_ClockInitStructure.USART_CPHA = USART_CPHA_1Edge; USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; /* Configure the USART1 */ USART_Init(USARTx, &USART_InitStructure); USART_ClockInit(USARTx, &USART_ClockInitStructure); /* Enable the USART Receive interrupt: this interrupt is generated when the USART1 receive data register is not empty */ USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); /* Enable USART1 */ USART_Cmd(USARTx, ENABLE); ................ void USART1_IRQHandler(void) { u16 TxCounter = 0; if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { /* Loop until the end of receive */ while(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) == SET) { /* Read one byte from the receive data register */ g_pComBuf[TxCounter ++] = USART_ReceiveData(USART1)& 0x7F; } } } In STR711, I prorammed as follow and there is not problem as before. void UART0_IRQHandler(void) { u32 vRxCount = ( u32 )g_pComBuf; UART_ItConfig( UART_PORT, UART_RxBufFull, DISABLE ); while( !( UART_TimeOutIdle & UART_ByteReceive( UART_PORT, (u8*)vRxCount++, UART_TIMEOUT ) ) ) ; UART_ItConfig( UART_PORT, UART_RxBufFull, ENABLE ); } I readed stm32 has only one byte FIFO for serial port. Certainly Must use DMA? Thank you very much for response jack2011-05-17 03:47 AM
Hello heilveil,
Thank you very much. I think that reception of command buffer from pc program without using DMA is impossible. really? So theses days I use DMA and received first command. But second command was not received. void USART1_IRQHandler(void) { if(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) == RESET) { if(USART1->CR3 & USART_DMAReq_Rx ){ g_blReadCommand = TRUE; USART_ClearFlag(USART1, USART_FLAG_RXNE); USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); } } ......... } int main (void) { #ifdef DEBUG debug(); #endif .................... /* DMA1 Channel5 (triggered by USART1 Rx event) Config */ DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)PACKET_DATA; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = GD_MAX_PACKET_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_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); ........ USART_DMACmd(USART1, USART_DMAReq_Rx , ENABLE); /* Enable DMA1 Channel5 */ DMA_Cmd(DMA1_Channel5, ENABLE); /* Enable the USART1 Receive Interrupt */ USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); while(1) { if ( g_blReadCommand == TRUE ){ // MakeResponse (); // SendResponse(); // ReadCommand(); g_blReadCommand = FALSE; USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); } } } I hope your help. happy to you.2011-05-17 03:47 AM
Quote:
I think that reception of command buffer from pc program without using DMA is impossible.
really?No - of course not!You can certainly receive from a PC without DMA - the IAP Bootloader App Note does exactly that! Of course, you'd have to keep the buffer down to a ''reasonable'' size - but, again, the IAP Bootloader App Note works perfectly well with 1K X/Y-Modem blocks at 115200 baud...2011-05-17 03:47 AM
Hello st7,
Thank you very for an idea. You are right, but it seem to be complex. I finaly implemented an idea by DMA. void DMA_Channel5_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; /* DMA1 Channel5 (triggered by USART1 Rx event) Config */ DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)PACKET_DATA; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = GD_MAX_PACKET_SIZE; ......... DMA_Init(DMA1_Channel5, &DMA_InitStructure); } void ReadCommand() { ............ /* Enable USART1 DMA RX request */ USART_DMACmd(USART1, USART_DMAReq_Rx , ENABLE); /* Enable USART1 Transmit interrupt */ while(DMA_GetFlagStatus(DMA1_FLAG_TC5) == RESET); DMA_ClearFlag(DMA1_FLAG_TC5); g_blReadCommand = TRUE; } PC Program is following. BOOL SendCmdPacket() { DWORD w_nSendCnt = 0; LONG w_nResult = 0; WORD w_nSize = 0; w_nSize = GetCommandLength(); //w_nResult = m_ClaSerial.Write(m_Packet, w_nSize + 6, &w_nSendCnt, NULL, GD_COMM_TIMEOUT_FP_NON_DELAY); w_nResult = SerialWrite(m_Packet, GD_MAX_PACKET_SIZE, &w_nSendCnt, NULL, timeout); ........... return TRUE; } But there is an problem. I can't predict length of command. When the application send a command as it's length then not reached to statement (g_blReadCommand = TRUE;) Only by sending buffer of length GD_MAX_PACKET_SIZE, the reading was completed. If GD_MAX_PACKET_SIZE = 500 and length of a command =16, then unavoidably must send extra empty data as 500-16. It is not efficient and communication speed very slow. Please help me. Thank you. [ This message was edited by: jki79ros81 on 16-10-2008 18:17 ]