Skip to main content
Myasu.1
Associate III
October 12, 2021
Question

USART Issue with STM32F100RB

  • October 12, 2021
  • 6 replies
  • 2737 views

I want to do serial communication between my PC and STM32F100RB.

the connection is as follows.

[STM32F100RB] -----[USBtoSERIAL transfer Module] --------------[PC]

PB10(Rx) <----------> TXD USB <----------> USB

PB11(Tx) <----------> RXD

​Currently, the transmission from PC to STM32F100RB is working, but the transmission from STM32F100RB to PC is not. Therefore, I don't think there is any possibility that USBtoSERIAL transfefr Module is broken.

The source code is shown below.

int main(void){
 
…
 
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
 
 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);
 USART_Cmd(USART3, ENABLE);
 
 while (1)
 {
 USART_SendData(USART3, 0x0001);
 }
}

I use the function USART_* in the following folder, which is provided by default in TrueStudio.

STM32F10x_StdPeriph_Driver

The following are the values of the registers that I checked on TrueStudio. They seem to be set correctly.

However, I am concerned that the value I want to send does not seem to be written in the DR register.

0693W00000FCG8FQAX.png

Could you please confirm ?

This topic has been closed for replies.

6 replies

Tesla DeLorean
Guru
October 12, 2021

Blind sending to USART1 is going to be an issue.

You want to only send to USART3 when the TXE is flagging

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Myasu.1
Myasu.1Author
Associate III
October 12, 2021

Sorry, that was a typo.

It is sent to USART3 in fact.

I have fixed the above source code.

Please continue to check.

Tesla DeLorean
Guru
October 12, 2021

Like I said you can't keep cramming down data on the USART, try something that pays attention to the status flags

while(1)
 {
 static uint8_t data = 0x55;
 
 if (USART_GetFlagStatus(USART3, USART_FLAG_TXE) != RESET)
 {
 USART_SendData(USART3, data);
 }
 
 if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) != RESET)
 {
 data = USART_ReceiveData(USART3);
 }
 
 if (USART_GetFlagStatus(USART3, (USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)) != RESET)
 {
 USART_ReceiveData(USART3); // Clear
 }
 }

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
TDK
Super User
October 12, 2021

> However, I am concerned that the value I want to send does not seem to be written in the DR register.

The DR register is not a memory address. It is an interface that allows you to send/receive data to the UART. Data you write is sent out on TX and data you read is what comes in on RX.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Tesla DeLorean
Guru
October 12, 2021

Might also be advisable not to look at the registers in the debugger, as reading the DR is invasive, clearing bits in the SR.

Close the peripheral view once you've concluded that the CRx/BRR are set appropriately, and the APB appears to be clocking it properly.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
TDK
Super User
October 12, 2021

You're also sending 1 which is not a printable character. It's unclear how you're receiving data on the PC, but the terminal program might simply be discarding it. Try sending a character like 'X' which is 0x58.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Myasu.1
Myasu.1Author
Associate III
October 12, 2021

Thank you for quick reply.

I tried implementing the following as advised, but it still does not send. Receiving is working.

 
 static uint8_t data = 0x58
 if (USART_GetFlagStatus(USART3, USART_FLAG_TXE) != RESET)
 {
 USART_SendData(USART3, data);
 }

By the way, I used Teraterm to check the transmission and reception on the PC side.

In the receiving confirmation, I type a character on the teraterm and check that the ascii code is stored in the DR register. 

In the sending, I want to make sure that X is output on the teraterm in the case of the above source code, but nothing is output.

Tesla DeLorean
Guru
October 12, 2021

Then you'll probably want to get a scope on things and check the signal at the pins.

Sending a stream of 0x55 should look like a square-wave, should be able to confirm bit-timing also.

No idea of the board, or usb-to-serial in use. The STM32 is not RS232 compatible, you'd need a USB to CMOS Serial adapter.

Check the HSE_VALUE

Check the AFIO and pin mapping. make sure it's not conflicting with anything else.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Myasu.1
Myasu.1Author
Associate III
October 24, 2021

Hello @Community member​ , @TDK​ ,

I was able to successfully send the message by changing the sending method to interrupt as shown below.

static uint8_t g_send_data = 0x55; /* global value */
 
int main(void) 
{
 while (1)
 {
 if (USART_GetFlagStatus(USART3, USART_FLAG_TXE) != RESET)
 {
 USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
 	 g_send_data += 1;
 	 USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
 }
 }
}
 
/* USART Interrupt handler */
void USART3_IRQHandler(void)
{
 // transfer procedures
 if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET)
 {
 USART_SendData(USART3, g_send_data); 
 }
}

I would like to ask the following two questions.

1.

Shouldn't we send from the main function ?

2.

When a message was sent from a PC, the value received by the PC was added by one.​

Probably "g_send_data += 1;" in the main function is being processed.

Does TXE become 1 when a message is received?

Best Regards,

Myasu

TDK
Super User
October 24, 2021

1. You can send data in main if you want, but if you do, you'll need to disable the interrupt otherwise it will be stuck in the ISR forever. It's unclear what you're trying to accomplish in the while loop.

2. TXE means the register used to send out data is empty and can accept data. Received data will trigger the RXNE flag.

If you want to know the details, the reference manual has all of this information.

"If you feel a post has answered your question, please click ""Accept as Solution""."