cancel
Showing results for 
Search instead for 
Did you mean: 

USART Issue with STM32F100RB

Myasu.1
Senior

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 ?

11 REPLIES 11

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 Venmo Up vote any posts that you find helpful, it shows what's working..
Myasu.1
Senior

Sorry, that was a typo.

It is sent to USART3 in fact.

I have fixed the above source code.

Please continue to check.

TDK
Guru

> 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".

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 Venmo Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

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".

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 Venmo Up vote any posts that you find helpful, it shows what's working..
Myasu.1
Senior

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.

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 Venmo Up vote any posts that you find helpful, it shows what's working..
Myasu.1
Senior

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