1. First of all, I would like to explain that the STM32 chip I used this time is STM32F103RB, and the resource used is USART1 on the chip.
2. Below is my circuit connection diagram:
Note: The circuit can be slightly modified to be better. Connect pull-down resistors to ground and pull-up resistors to 5V at B and A respectively. The resistance value can be selected as 10K. This is to ensure that the status of the two data lines is a certain value when no data transmission is in progress.
Let me give you a brief explanation:
(1) PA8 is the transmit/receive enable pin of sp3485. sp3485 can only support half-duplex communication, so this pin is used to control whether the chip receives or sends data.
(2) In some circuit connections, one of the A and B terminals of the sp3485 will be connected to a pull-up resistor to 3.3V, and the other will be connected to a pull-down resistor to GND. The purpose of this is to not affect the stability of the network when the sp3485 is not involved in communication.
3. This debugging method
PC - USB to 232 converter - RS232/RS485 bidirectional converter - sp3485 - STM32. Since it was the first time to debug the sp3485 chip, of course I didn't take it too seriously. I used the computer to debug it first, and then looked at the communication between the boards after the debugging was successful.
4. Code for this experiment:
main function:
int main(void)
{
/* Configure the system clocks */
RCC_Configuration();
/* NVIC Configuration */
NVIC_Configuration();
/* Configure the GPIOs */
GPIO_Configuration();
/* Configure the USART1 */
USART_Configuration();
GPIO_SetBits(GPIOA, GPIO_Pin_8); //PA8 is the send/receive control terminal of sp3485. Set it to send here first (the function realized is that after power-on, STM32 sends a 4 and a 3 to PC first)
delay_ms(2); //Slightly delay, please check the manual of sp3485 for the reason
USART_ClearFlag(USART1,USART_FLAG_TC);//This sentence is very important. Without this sentence, the 4 will fail to send or send an error.
//In fact, the manual says that after enabling the send bit, a useless frame will be sent, so after that frame is sent, this
//The sending completion flag USART_FLAG_TC is of course also set.
USART_SendData(USART1, 4);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);//The send completion flag is cleared above, so here we can wait for the send completion flag to be set to determine whether the frame has been sent
USART_SendData(USART1, 3);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
while(1)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_8); // Now clear PA8 and try to receive data sent by the PC
delay_ms(2); //Slightly delay, please check the manual of sp3485 for the reason
USART_ClearFlag(USART1,USART_FLAG_RXNE);//Since the send completion flag is cleared before sending, the receive completion flag is also cleared here, just treat it as a good habit.
while(1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)//Judge whether a frame of data has been received
{
buf[j++] = USART_ReceiveData(USART1); //If the reception is completed, put it directly into the buffer area
}
if(10 == j) // After receiving 10 messages, it will jump out and stop receiving messages. It is OK if there is a meaning.
break;
}
j = 0; // Clear the j variable so that the experiment can repeatedly receive 10 data sent by the PC
GPIO_SetBits(GPIOA, GPIO_Pin_8); //Set sp3485 to send data
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
delay_ms(2); //Slightly delay, please check the manual of sp3485 for the reason
for(i = 0; i < 10; i++)
{
USART_SendData(USART1, buf[i]); //Send the data in sequence
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
}
}
Note: When using the STM32 serial port for 485 communication, when sending data, it is detected that the flag bit after the last data is sent has been set, but the sending pin of the 485 chip cannot be disabled immediately, because although the flag bit has been set, the data of the 485 chip has not been completely sent out. At this time, a delay of ms level is required, and generally there is no problem with about 2 milliseconds.
RCC setting function:
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
/* Enable USART1 and GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
}
GPIO setting function:
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PC. as Output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP = 0x10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP = 0x10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
USART setup function:
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
/* Configure the USART1 synchronous paramters */
USART_ClockInit(USART1, &USART_ClockInitStructure);
USART_InitStructure.USART_BaudRate = 9600;
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;
/* Configure USART1 basic and asynchronous paramters */
USART_Init(USART1, &USART_InitStructure);
/* Enable USART1 */
USART_Cmd(USART1, ENABLE);
}
NVIC setup function:
void NVIC_Configuration(void)
{
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}
5. Experimental results
It failed. I searched for the reason for a long time. First, please check the connection line between sp3485 and 232/485 bidirectional conversion head. The correct connection method I got was that sp3485 A was connected to T/R+, and sp3485 B was connected to T/R-.
After changing the connection sequence, a very strange phenomenon still occurred. Every time after powering on, the PC's serial port debugging assistant would receive 04 03 00, with an extra 00 (hexadecimal). There was an even stranger phenomenon. When I entered ten data on the PC and clicked send, 20 data were returned. The first 10 data were wrong, and the last 10 were the data I sent. . .
This phenomenon was very strange. I modified the program repeatedly but still couldn't solve the problem. I even suspected that sp3485 was broken. Finally, after a whole day of work, I removed the 120-ohm resistor between the sp3485A and B pins, and everything returned to normal!
To explain: the distance between my sp3485 and the 232/485 converter is about 20cm, so at this distance there should be no need to connect a 120 ohm matching resistor.
Previous article:STM32 Series Part 1 - Preliminary Study
Next article:STM32 peripheral driver - DHT11 temperature and humidity sensor
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- Molex leverages SAP solutions to drive smart supply chain collaboration
- Pickering Launches New Future-Proof PXIe Single-Slot Controller for High-Performance Test and Measurement Applications
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- Unboxing the newly purchased PIC Kit4, looking forward to its improved functions
- EEWORLD University Hall----Live playback: AVNET uses on-chip CIP and intelligent analog to build complex embedded control functions
- Step 2: Power supply project establishment, DIY high-efficiency bidirectional DC-DC converter from scratch!
- TMC2300-LA dual-phase stepper motor chip can replace DRV8846
- Urgent! Urgent! Urgent! Can the teacher provide a 50A/1000W mature constant current source circuit. The adjustable constant current source can be controlled by a single chip microcomputer.
- 【K210 Series】2. Download tool and latest firmware for K210
- TI's Arm Cortex-A8 family with 3D graphics, industrial Ethernet and flexible peripherals
- DSP temperature control device
- C6455 EMIFA initialization error
- Small form factor Bluetooth Low Energy (BLE) reference design