STM32 Debug 485 (sp3485) Technical Summary

Publisher:沈阳阿荣Latest update time:2017-09-23 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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:


  1. int main(void)  

  2. {  

  3.   

  4.     /* Configure the system clocks */  

  5.     RCC_Configuration();  

  6.         

  7.     /* NVIC Configuration */  

  8.     NVIC_Configuration();  

  9.   

  10.     /* Configure the GPIOs */  

  11.     GPIO_Configuration();  

  12.     

  13.     /* Configure the USART1 */  

  14.     USART_Configuration();  

  15.   

  16.     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)  

  17.   

  18.     delay_ms(2); //Slightly delay, please check the manual of sp3485 for the reason  

  19.     USART_ClearFlag(USART1,USART_FLAG_TC);//This sentence is very important. Without this sentence, the 4 will fail to send or send an error.  

  20.   

  21.                                                                                            //In fact, the manual says that after enabling the send bit, a useless frame will be sent, so after that frame is sent, this  

  22.   

  23.                                                                                            //The sending completion flag USART_FLAG_TC is of course also set.  

  24.     USART_SendData(USART1, 4);  

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

  26.   

  27.     USART_SendData(USART1, 3);  

  28.     while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  

  29.   

  30.     while(1)  

  31.     {   

  32.   

  33.        GPIO_ResetBits(GPIOA, GPIO_Pin_8); // Now clear PA8 and try to receive data sent by the PC  

  34.   

  35.        delay_ms(2); //Slightly delay, please check the manual of sp3485 for the reason  

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

  37.        while(1)  

  38.       {  

  39.           if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)//Judge whether a frame of data has been received  

  40.           {              

  41.                buf[j++] = USART_ReceiveData(USART1); //If the reception is completed, put it directly into the buffer area    

  42.           }  

  43.          if(10 == j) // After receiving 10 messages, it will jump out and stop receiving messages. It is OK if there is a meaning.  

  44.          break;  

  45.       }  

  46.     j = 0; // Clear the j variable so that the experiment can repeatedly receive 10 data sent by the PC  

  47.    GPIO_SetBits(GPIOA, GPIO_Pin_8); //Set sp3485 to send data  

  48.     while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  

  49.    delay_ms(2); //Slightly delay, please check the manual of sp3485 for the reason  

  50.     for(i = 0; i < 10; i++)  

  51.    {  

  52.         USART_SendData(USART1, buf[i]); //Send the data in sequence  

  53.         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);   

  54.     }  

  55.  }  

  56. }  

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:


  1. void RCC_Configuration(void)  

  2. {  

  3.   /* RCC system reset(for debug purpose) */  

  4.   RCC_DeInit();  

  5.   

  6.   /* Enable HSE */  

  7.   RCC_HSEConfig(RCC_HSE_ON);  

  8.   

  9.   /* Wait till HSE is ready */  

  10.   HSEStartUpStatus = RCC_WaitForHSEStartUp();  

  11.   

  12.   if(HSEStartUpStatus == SUCCESS)  

  13.   {  

  14.     /* HCLK = SYSCLK */  

  15.     RCC_HCLKConfig(RCC_SYSCLK_Div1);   

  16.     

  17.     /* PCLK2 = HCLK */  

  18.     RCC_PCLK2Config(RCC_HCLK_Div1);   

  19.   

  20.     /* PCLK1 = HCLK/2 */  

  21.     RCC_PCLK1Config(RCC_HCLK_Div2);  

  22.   

  23.     /* Flash 2 wait state */  

  24.     FLASH_SetLatency(FLASH_Latency_2);  

  25.     /* Enable Prefetch Buffer */  

  26.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  

  27.   

  28.     /* PLLCLK = 8MHz * 9 = 72 MHz */  

  29.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  

  30.   

  31.     /* Enable PLL */   

  32.     RCC_PLLCmd(ENABLE);  

  33.   

  34.     /* Wait till PLL is ready */  

  35.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  

  36.     {  

  37.     }  

  38.   

  39.     /* Select PLL as system clock source */  

  40.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  

  41.   

  42.     /* Wait till PLL is used as system clock source */  

  43.     while(RCC_GetSYSCLKSource() != 0x08)  

  44.     {  

  45.     }  

  46.   }  

  47.      

  48.   /* Enable USART1 and GPIOA clock */  

  49.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);  

  50. }  

GPIO setting function:


  1. void GPIO_Configuration(void)  

  2. {  

  3.   GPIO_InitTypeDef GPIO_InitStructure;  

  4.   

  5.   /* Configure USART1 Tx (PA.09) as alternate function push-pull */  

  6.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  

  7.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

  8.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  9.   GPIO_Init(GPIOA, &GPIO_InitStructure);  

  10.       

  11.   /* Configure USART1 Rx (PA.10) as input floating */  

  12.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  

  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

  14.   GPIO_Init(GPIOA, &GPIO_InitStructure);  

  15.   

  16.  /* Configure PC. as Output push-pull */  

  17.  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  

  18.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP = 0x10  

  19.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  20.  GPIO_Init(GPIOA, &GPIO_InitStructure);  

  21.   

  22.   

  23.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  

  24.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP = 0x10  

  25.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  26.  GPIO_Init(GPIOC, &GPIO_InitStructure);  

  27. }  

USART setup function:


  1. void USART_Configuration(void)  

  2. {  

  3.   USART_InitTypeDef USART_InitStructure;  

  4.   USART_ClockInitTypeDef  USART_ClockInitStructure;  

  5.   

  6.   

  7. USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;  

  8. USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;  

  9. USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;  

  10. USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;  

  11. /* Configure the USART1 synchronous paramters */  

  12. USART_ClockInit(USART1, &USART_ClockInitStructure);  

  13.   

  14. USART_InitStructure.USART_BaudRate = 9600;  

  15. USART_InitStructure.USART_WordLength = USART_WordLength_8b;  

  16. USART_InitStructure.USART_StopBits = USART_StopBits_1;  

  17. USART_InitStructure.USART_Parity = USART_Parity_No ;  

  18. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

  19.   

  20.   

  21. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  

  22. /* Configure USART1 basic and asynchronous paramters */  

  23. USART_Init(USART1, &USART_InitStructure);  

  24.       

  25.   /* Enable USART1 */  

  26. USART_Cmd(USART1, ENABLE);  

  27. }  

NVIC setup function:


  1. void NVIC_Configuration(void)  

  2. {  

  3. #ifdef  VECT_TAB_RAM    

  4.   /* Set the Vector Table base location at 0x20000000 */   

  5.   NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);   

  6. #else  /* VECT_TAB_FLASH  */  

  7.   /* Set the Vector Table base location at 0x08000000 */   

  8.   NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);     

  9. #endif  

  10. }  

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.


Keywords:STM32 Reference address:STM32 Debug 485 (sp3485) Technical Summary

Previous article:STM32 Series Part 1 - Preliminary Study
Next article:STM32 peripheral driver - DHT11 temperature and humidity sensor

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号