2015-08-04 02:12 PM
Hello all,
I am using a STM32F103 MCU and a FT232RQ USB controller which is connected to UART4 in my configuration. I use polling to read data from UART4 (later I will use interrupt as soon as I am sure that everything work fine). I read data from UART4 in the main ''while'' loop as below: int main() { initF232RQ(); while (1) { while (USART_GetFlagStatus(UART4, USART_FLAG_RXNE) == RESET); uint8_t ch = (uint8_t)USART_ReceiveData(UART4); } } and ''UART4'' is initialized in the function ''initF232RQ'' as below: void initF232RQ() { USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate = 115200; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(UART4, &USART_InitStruct); USART_Cmd(UART4, ENABLE); } The code above seems to work fine when I use echo which means, send the received character in PuTTY, but the only problem in echo test, is that all upper case characters are sent as lower case characters. The other problem is that when I check the received value of the sent char, the value is totally different from the ASCII code of the sent character. For instance, when I send ''a'', the value ''3'' will be sent, or if I send ''b'' the value ''4'' will be sent to the MCU. and if I send ''w'', value ''223'' will be sent to the MCU. I also tried to send a block of data from a Windows host machine, using the code: ::WriteFile(GetFileHandle(), pData, pWriteByteCount, &lNumberOfBytesWritten, lPtrAsyncStruct) where: ''pData'' is an array of data, ''pWriteByteCount'' is the size of array in bytes, ''lNumberOfBytesWritten'' is the number of bytes written to the serial port, and ''lPtrAsynchStruct'' is a data structure used in the write function. In this case, when I send a block of data, using the code above at the MCU side, only one byte is always received and the rest of data seems to be lost. I tried to follow the examples for USART, but it seems that I have missed something. Can anybody help? Regards, Dan. #know-your-tools2015-08-04 04:55 PM
I think you need to look at the signal integrity with a scope, especially at the bit timing.
You could try configuring the PC side with 2 stop bits, as this will expand the inter-symbol delay, and perhaps permit better synchronization. The fact it echos back, and you receive odd values if you look at them suggests whatever problem you have could be symmetrical in nature. Your USB adapter looks to be CMOS vs RS232, so I can't explain the data pattern issue with that.2015-08-05 07:18 AM
2015-08-05 08:34 AM
This is where one uses an oscilloscope to understand what's happening. If you send an 'a' from the PC you should get an 'a' (0x61) at the STM32
Send 'U' characters and confirm the bit timing on the data sent by your USB adapter, and by the STM32. I'm assuming a direct wiring of the TX/RX pins between the two. If you have something else going on provide a schematic or diagram.One the STM32 side you need to make sure the define for HSE_VALUE actually reflects the speed of the external crystal being used.If you have a different USB-to-CMOS Serial adapter, one using a crystal, give that a try also.2015-08-05 10:33 AM
This looks like a baud rate mismatch. I see from your code the ST side runs at 115K while the PC side (and I assume this sets the FT rate also) is set at 9600.
Jack Peacock2015-08-05 10:47 AM
I'm lead to believe the two different posts were testing slightly different configurations, the first using Putty with the ''same'' settings.
The latter ''Using this, I know exactly the properties of the data sent to the MCU. Then I have exactly same configuration at the MCU side, but the data is still incorrect.''There's clearly some disconnect between what the OP wants to happen, and what's transacting on the wire, all other things being equal, the scope decides.2015-08-07 07:52 AM
I am not sure whether this is a timing problem or not. However, when I play around with the baudare values, both at PC and MCU sides, I simply get different results. I have attached the configuration I use which consists of a FT232R USB UART IC and STM32F103 as MCU, where FT232R is controlled using UART4 in MCU. Should both parties i.e. PC and MCU have exactly same baudrate? I have tested with same baudrate with no success. At the same time, in this configuration, I think the baudrate is important *only* for communication between MCU-FT232R and also FT232R-PC, so it shouldn't be important that the baudrate be same, since FT232 is in between. Anyway, any tip/advice is highly appreciated. By the way, in my tests, number of stop bits, word length, and parity is exactly same in MCU and PC side.
Regards, Dan.2015-08-07 08:05 AM
Ok, if you're feeding 12 MHz into the STM32 have you changed HSE_VALUE to reflect that, and the configuration of the PLL?
The default assumption are 8 MHz, ie #define HSE_VALUE 8000000The math to determine the baud rate as clock ticks is predicated on this.2015-08-07 08:11 AM
Thanks a lot. Yes, I am feeding 12 MHz. But, would you please let me know how HSE should be change and what attribute of PLL should be changed to reflect 12 MHz input clock? I see that HSE_VALUE is readonly.
Thanks again, Dan.2015-08-07 08:34 AM
You'd typically pull library files that need to be board specific into your own project directory, remove the read-only attribute and modify them when necessary.
Feeding -DHSE_VALUE=12000000 on the compiler command line is one method, modifying stm32f1xx_conf.h to add #define HSE_VALUE 12000000 before the peripheral libraries are pulled in. For the PLL you're going to have to play games with the multiplier and dividers to get 72 MHz or whatever you want. This would be in system_stm32f1xx.c For 8 MHz you have (8 / 1) * 9 = 72, for 12 MHz you could have (12 / 1) * 6 = 72 On the F4 DISCO this happens, not sure I like the undefine methodology, but whatever...
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_CONF_H
#define __STM32F4xx_CONF_H
#if defined (HSE_VALUE)
/* Redefine the HSE value; it's equal to 8 MHz on the STM32F401-DISCOVERY Kit */
#undef HSE_VALUE
#define HSE_VALUE ((uint32_t)8000000)
#endif /* HSE_VALUE */
/* Includes ------------------------------------------------------------------*/
/* Uncomment the line below to enable peripheral header file inclusion */
#include ''stm32f4xx_adc.h''
#include ''stm32f4xx_crc.h''
...
/* PLL configuration: PLLCLK = HSE * 6 = 72 MHz, where HSE = 12 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);