2021-10-12 08:38 AM
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.
Could you please confirm ?
2021-10-12 08:52 AM
Blind sending to USART1 is going to be an issue.
You want to only send to USART3 when the TXE is flagging
2021-10-12 09:00 AM
Sorry, that was a typo.
It is sent to USART3 in fact.
I have fixed the above source code.
Please continue to check.
2021-10-12 09:15 AM
> 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.
2021-10-12 09:16 AM
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
}
}
2021-10-12 09:19 AM
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.
2021-10-12 09:27 AM
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.
2021-10-12 10:08 AM
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.
2021-10-12 10:21 AM
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.
2021-10-24 08:41 AM
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