Urgent help, about the USART serial communication (sp3232) problem of STM32F407VGT6 chip (please help if you pass by)
[Copy link]
Today I would like to ask you a question about the serial port communication of STM32F407 . Actually, this is a very basic question, but I have to ask you.
1. Problem description
The microcontroller used is STM32F407VGT6 chip, 100 pins. The serial port channel is USART3, and the serial port chip is SP3232 chip. The communication rate is 115200-8-n-1.
When testing the microcontroller, it was found that the received and sent data were garbled and could not be used at all.
2. Troubleshooting
(1) First check the hardware problem.
The hardware circuit diagram is as follows:
The circuit diagram was designed according to the data sheet and the circuit diagram of Atom. The voltages at each point were tested: (16-pin voltage 3.27V, 2-pin voltage 5.89V, 6-pin voltage -5.3V, 1-pin voltage 2.9V, 4-pin voltage 5.56V).
The microcontroller was connected to the PC externally through a USB to TTL tool and a cross connection was made.
(2) Check the debugging tool
. It was suspected that the debugging tool was the problem. Three USB to TTL converters from different manufacturers were tested. The displayed results were the same, and the communication was garbled. The communication tool was ruled out.
(3) Check the serial port assistant
. Three serial port debugging assistants were also replaced, including Atom's serial port assistant. The problem was the same.
(4) Check the communication chip.
a. In view of the fact that there are many fake SP2332s on the Internet and my own experience, the SP3232 tested was replaced with a new one. During this period, it was replaced with MAX232 (the chip voltage was changed to 5V through flying wires), and then replaced with max3232 through regular channels. The same result was garbled communication.
b. Perform a loopback test on SP3232, that is, short-circuit USART3 (pin 9 and pin 10), and send data through the serial port debugging assistant. At this time, the data is sent normally. Short-circuit USART6 (pin 11 and pin 12), and the data is sent normally, indicating that the communication chip is normal.
(5)
The test method for detecting the communication pins of the microcontroller is to remove the SP3232 chip, directly connect the TXD and RXD of USART3 to the RXD and TXD of the USB to TTL tool, and send data through the debugging assistant. It can also send and receive data normally, and the data sent is the same as the data returned.
At this time, re-solder the SP3232 chip, and the communication is still garbled, which is simply unbelievable.
(6) Check the peripheral components of the microcontroller
a. First check for any cold soldering problems.
Re-solder the peripheral components of the microcontroller and repair them
b. Check the circuit problems and carefully verify them against the official schematic diagram and the schematic diagram of the STM32F407VGT6 chip on the Internet. No problems were found.
The schematic diagram is as follows (about the power supply and crystal oscillator):
c. Check the crystal oscillator. The crystal
oscillator is 8MHz and there is no problem with the welding. Test the voltage of the crystal oscillator pins, which are 1.81V and 1.69V respectively.
Remove the crystal oscillator Y3 (32.768KHz).
(7) Check the program problem
. There are two test examples for this test, one is "Experiment 4 Serial Port Experiment" by Atom Brother, and the other is "USART2-USART2 Transmitter" by Wildfire. Don't be surprised, there is really no other way.
a. Atom Brother's "Experiment 4 Serial Port Experiment"
Modify the pin, clock and interrupt configuration :
//Redefine fputc function
int fputc(int ch, FILE *f)
{
while((USART3->SR&0X40)==0);//Loop sending until sending is completed
USART3->DR = (u8) ch;
return ch;
}
#endif
#if EN_USART1_RX //If reception is enabled
//Serial port 1 interrupt service routine
//Note that reading USARTx->SR can avoid inexplicable errors
u8 USART_RX_BUF[USART_REC_LEN]; //Receive buffer, maximum USART_REC_LEN bytes.
//Receive status
//bit15, receive completion flag
//bit14, received 0x0d
//bit13~0, number of valid bytes received
u16 USART_RX_STA=0; //Receive status mark
//Initialize IO Serial port 1
//bound: baud rate
void uart_init(u32 bound){
//GPIO port settings
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //Enable GPIOA clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //Enable USART1 clock //Serial port 1 corresponding pin multiplexing mapping GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_USART3); //GPIOA9 is multiplexed as USART1 GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_USART3); //GPIOA10 is multiplexed as USART1 //USART1 port configuration GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //GPIOA9 and GPIOA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //Multiplexing function GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //Push-pull multiplexing output GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //Pull up GPIO_Init(GPIOD,&GPIO_InitStructure); //Initialize PA9, PA10 //USART1 initialization settings USART_InitStructure.USART_BaudRate = bound; //Baud rate setting USART_InitStructure.USART_WordLength = USART_WordLength_8b;//Word length is 8-bit data formatUSART_InitStructure.USART_StopBits = USART_StopBits_1;//One stop bitUSART_InitStructure.USART_Parity = USART_Parity_No;//No parity bitUSART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//No hardware data flow controlUSART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Transmit and receive modeUSART_Init (USART3, &USART_InitStructure); //Initialize serial port 1 USART_Cmd(USART3, ENABLE); //Enable serial port 1 USART_ClearFlag(USART3, USART_FLAG_TC); #if EN_USART1_RX USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // Enable related interrupts // Usart1 NVIC configuration
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //Serial port 1 interrupt channel
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //Preemption priority 3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //Sub-priority 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ channel enable
NVIC_Init(&NVIC_InitStructure); //Initialize VIC registers according to the specified parameters,
#endif } void USART3_IRQHandler(void) //Serial port 1 interrupt service routine { u8 Res; #ifdef OS_TICKS_PER_SEC //If the clock tick number is defined, it means that ucosII is to be used. OSIntEnter(); #endif if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //Receive interrupt (the received data must end with 0x0d 0x0a) { Res =USART_ReceiveData(USART3);//(USART1->DR); //Read received data if((USART_RX_STA&0x8000)==0)//Reception is not completed { if(USART_RX_STA&0x4000)//Received 0x0d { if(Res!=0x0a)USART_RX_STA=0;//Reception error, restart else USART_RX_STA|=0x8000; //Reception is completed } else //Not received 0X0D { if(Res==0x0d)USART_RX_STA|=0x4000; else { USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//Receive data error, restart receiving } } } } #ifdef OS_TICKS_PER_SEC //If the clock beat number is defined, it means that ucosII is to be used. OSIntExit(); #endif } After modification in the main function: while(1) { if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//Get the length of the data received this time printf("\r\nThe message you sent is:\r\n"); for(t=0;t<len;t++) { USART_SendData(USART3, USART_RX_BUF[t]); //Send data to serial port 1while (USART_GetFlagStatus(USART3,USART_FLAG_TC)!=SET);//Wait for the end of sending }
printf("\r\n\r\n");//Insert line
breakUSART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\nALIENTEK Explorer STM32F407 Development Board Serial Port Experiment\r\n");
printf(" Punctaneous Atom @ALIENTEK\r\n\r\n\r\n");
}
if(times%200==0)printf("52353535\r\n");
if(times%30==0)LED0=!LED0;//Blink LED to indicate that the system is running.
delay_ms(10);
}
}
View the clock configuration:
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if defined (STM32F40_41xxx)
uint32_t SystemCoreClock = 168000000;
#endif /* STM32F40_41xxx */
/************************* PLL Parameters *************************************/
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || (STM32F429 _439xx ) || defined(STM32F401xx) || defined(STM32F469_479xx)
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M
simulation to view the configuration of USART3:
After comparing it with the data sheet, no problems were found.
b. Wildfire's "USART2 - USART2 Transmission"
//Pin definition
/********************************************************/
#define RS232_USART USART3
#define RS232_USART_CLK RCC_APB1Periph_USART3
#define RS232_USART_RX_GPIO_PORT GPIOD
#define RS232_USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOD
#define RS232_USART_RX_PIN GPIO_Pin_9
#define RS232_USART_RX_AF GPIO_AF_USART3
#define RS232_USART_RX_SOURCE GPIO_PinSource9
#define RS232_USART_TX_GPIO_PORT GPIOD
#define RS232_USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOD
#define RS232_USART_TX_PIN GPIO_Pin_8
#define RS232_USART_TX_AF GPIO_AF_USART3
#define RS232_USART_TX_SOURCE GPIO_PinSource8
#define RS232_USART_IRQHandler USART3_IRQHandler
#define RS232_USART_IRQ USART3_IRQn
/************************************************************/
//串口波特率
#define RS232_USART_BAUDRATE 115200
/**
* @brief配置嵌套向量中断控制器NVIC
* @param无
* @retval 无
*/
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置中断源 */
NVIC_InitStructure.NVIC_IRQChannel = RS232_USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @briefRS232_USART GPIO 配置,工作模式配置。115200 8-N-1 ,中断接收模式
* @param无
* @retval 无
*/
void Debug_USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_AHB1PeriphClockCmd( RS232_USART_RX_GPIO_CLK|RS232_USART_TX_GPIO_CLK, ENABLE);
/* 使能 UART 时钟 */
RCC_APB1PeriphClockCmd(RS232_USART_CLK, ENABLE);
/* 连接 PXx 到 USARTx_Tx*/
GPIO_PinAFConfig(RS232_USART_RX_GPIO_PORT,RS232_USART_RX_SOURCE, RS232_USART_RX_AF);
/*连接 PXx 到 USARTx__Rx*/
GPIO_PinAFConfig(RS232_USART_TX_GPIO_PORT,RS232_USART_TX_SOURCE,RS232_USART_TX_AF);
/* 配置Tx引脚为复用功能*/
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = RS232_USART_TX_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(RS232_USART_TX_GPIO_PORT, &GPIO_InitStructure);
/* Configure Rx pin as multiplexed function*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = RS232_USART_RX_PIN;
GPIO_Init(RS232_USART_RX_GPIO_PORT, &GPIO_InitStructure); /* Configure serial port RS232_USART mode*/ USART_InitStructure.USART_BaudRate = RS232_USART_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_Init(RS232_USART, &USART_InitStructure); NVIC_Configuration(); /*Configure serial port receive interrupt*/ USART_ITConfig(RS232_USART, USART_IT_RXNE, ENABLE); USART_Cmd(RS232_USART, ENABLE); } //Interrupt receive function extern uint8_t Rxflag; extern uint8_t ucTemp; void RS232_USART_IRQHandler(void) { if(USART_GetITStatus( RS232_USART, USART_IT_RXNE ) != RESET) { Rxflag=1; ucTemp = USART_ReceiveData( RS232_USART ); } } Main function: while(1) { /* Receive data from the DEBUG_USART port, analyze and process it. You can encapsulate this code into a function and call it in other processes of the main program */ if(Rxflag) { if (usRxCount < sizeof(ucaRxBuf)) { ucaRxBuf[usRxCount++] = ucTemp; } else { usRxCount = 0; } /* Simple communication protocol. When a carriage return and line feed character is encountered, it is considered as a command frame. You can add other judgments to implement custom commands*/ /* When a line feed character is encountered, it is considered to have received a command*/ if (ucTemp == 0x0A) /* Line feed character*/ { /*When a carriage return character is detected, the data is returned to the host computer*/ Usart_SendStr_length( RS232_USART, ucaRxBuf, usRxCount ); //Usart_SendString(); usRxCount = 0; } Rxflag=0; } } Similarly, change the system clock to 8MHz and test it. 3. Search for information about various methods mentioned on the Internet, such as changing the file attribute from read-only to editable; such as the frequency division of the system clock, changing the system's total clock to 72Mhz for testing, all ended in failure.
4. I really have no other choice but to ask for emergency help
. I hope that friends who see this post can give me some suggestions on something that I have not noticed. Thank you very much.
|