[STM32L4+] 【STEVAL-STWINKT1B测评】5、RS485通讯

[复制链接]
 楼主| xinmeng_wit 发表于 2024-9-2 21:33 | 显示全部楼层 |阅读模式
<
ev, TE, ST, RS, RS485
一、RS485介绍

RS-485(目前称为EIA/TIA-485)是通信物理层的标准接口,一种信号传输方式,OSI(开放系统互连)模型的第一级。 创建 RS-485 是为了扩展 RS-232 接口的物理功能。
串行 EIA-485 连接是使用两根或三根电线的电缆完成的:一根数据线、一根带反转数据的电线,通常还有一根零线(接地,0 V)。 这样,发射器和接收器通过 22 或 24 AWG 实心线的双绞线电缆交换数据。
这里的主要思想是通过两根电线传输一个信号。 当一根电线传输原始信号时,另一根电线传输其反向副本。 这种传输方法提供了对共模干扰的高抵抗力。 用作传输线的双绞线可以是屏蔽或非屏蔽的。
1.png

二、接口确认
2.jpeg

3.jpeg

通过原理图可以看出,RS485接口与stlink共用了USART2端口,引脚分别为:
USART2_RST ---->  PD4
USART2_TX-------> PD5
USART2_RX-------> PD6

三、cubreMX配置
2.png

3.png

四、应用程序编写
生成usart驱动后,就可以编写应用程序了,主要是封装一层对485收发器的控制代码。
rs485.c和rs485.h文件如下。

rs485.c:
  1. #include "usart.h"
  2. #include "main.h"
  3. #include "stm32l4xx_hal_uart.h"

  4. static uint8_t rx_buffer = 0;
  5. static uint8_t rx_flag = 0;

  6. void rs485_send( uint8_t *str, uint16_t len )
  7. {
  8.     if ( str != 0 )
  9.     {
  10.         while( __HAL_UART_GET_FLAG( &huart2, UART_FLAG_TXE ) != 1 );

  11.         HAL_GPIO_WritePin(GPIOD, RS485_DE_Pin, GPIO_PIN_SET);   
  12.         HAL_UART_Transmit(&huart2, str, len, 1000);
  13.         HAL_GPIO_WritePin(GPIOD, RS485_DE_Pin, GPIO_PIN_RESET);         
  14.     }
  15. }

  16. void rs485_start_recv( void )
  17. {
  18.     HAL_UART_Receive_IT(&huart2, &rx_buffer, 1);
  19. }

  20. uint8_t rs485_get_rx_data( void )
  21. {
  22.     return rx_buffer;
  23. }

  24. void rs485_set_rx_flag( void )
  25. {
  26.     rx_flag = 1;
  27. }

  28. void rs485_clr_rx_flag( void )
  29. {
  30.     rx_flag = 0;
  31. }

  32. uint8_t rs485_get_rx_flag( void )
  33. {
  34.     return rx_flag;
  35. }


  36. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  37. {
  38.    rs485_set_rx_flag();
  39.    rs485_start_recv();
  40. }
rs485.h:
  1. /* Define to prevent recursive inclusion -------------------------------------*/
  2. #ifndef RS485_H
  3. #define RS485_H

  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif

  7. /* Includes ------------------------------------------------------------------*/
  8. #include "main.h"

  9. void rs485_send( uint8_t *str, uint16_t len );
  10. void rs485_start_recv( void );
  11. uint8_t rs485_get_rx_data( void );
  12. void rs485_set_rx_flag( void );
  13. void rs485_clr_rx_flag( void );
  14. uint8_t rs485_get_rx_flag( void );
  15. /**
  16.   * @}
  17.   *
  18.   */

  19. #ifdef __cplusplus
  20. }
  21. #endif

  22. #endif /*RS485_H */

  23. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


五、测试结果
测试下来,可以通过485端口发送数据到pc,但是pc发送给mcu的数据收不到。
然后又测试了通过jlink的虚拟串口收发,发现也是一样的问题,感觉是不是硬件上哪里有问题,同样的代码在其它板子上是可以跑的,搞了很长时间也没有找到具体原因,先记录下来,后面空了再来看。


呐咯密密 发表于 2024-9-20 10:11 | 显示全部楼层
是不是因为和STLLINK的接口冲突了
yangjiaxu 发表于 2024-9-20 10:14 | 显示全部楼层
其实,485通讯和串口通讯一样,UART这种,主要是有个使能端,其实现在有很多都不用使能端了,直接全双工
4y1b3 发表于 2024-9-21 11:41 来自手机 | 显示全部楼层
这里的主要思想是通过两根电线传输一个信号
Henryko 发表于 2024-9-21 12:10 | 显示全部楼层
485跟串口是不是除了电平都一样啊?
 楼主| xinmeng_wit 发表于 2024-9-24 19:37 | 显示全部楼层
Henryko 发表于 2024-9-21 12:10
485跟串口是不是除了电平都一样啊?

不仅仅是电平不一样,485是半双工,串口是全双工
您需要登录后才可以回帖 登录 | 注册

本版积分规则

70

主题

276

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部