源:http://blog.chinaunix.net/uid-26921272-id-3506640.html

RS485缺点:

RS485总线是一种常规的通信总线,它不能够做总线的自动仲裁,也就是不能够同时发送数据以避免总线竞争,所以整个系统的通信效率必然较低,数据冗余量较大,对于速度要求高的应用场所不适应用RS485总线。同时由于RS485总线上通常只有一台主机,所以这种总线方式是典型的集中—分散型控制系统。一旦主机出现故障,会使整个系统的通信限于瘫痪状态,因此做好主机的在线备份是一个重要措施。

**传统光电隔离的典型电路:

VDD与+5V1(VCC485)是两组不共地的电源,一般用隔离型的DC-DC来实现。通过光耦隔离来实现信号的隔离传输,ISL3152EIBZ与MCU系统不共地,完全隔离则有效的抑制了高共模电压的产生,大大降低485的损坏率,提高了系统稳定性。但也存在电路体积过大、电路繁琐、分立器件过多,传输速率受光电器件限制等缺点,对整个系统的稳定性也有一定影响。

***RXD1 :串口接收端

***TXD1 :串口传输端

***TRE1 :为控制位:控制发送还是接收数据;

当TRE1=1(高电平时),光耦电路121截止,/RE=1(无效),DE=1(有效),即发送数据;

当TRE=0   (低电平时),光耦电路导通,/RE=0(有效),即接收数据,DE=0(无效);

/RE: 485接收端

DE:485发送端

第一步,配置好串口发送、接收端引脚和485控制引脚;

因为RXD1引脚相对于STM32芯片来说是接收外来数据,所以设置为输入;

TXD1引脚相对于STM32芯片来说是对外发送数据,所以设置为输出;

TRE1 引脚是对外发送“1”或“0”高低电平命令,所以设置为输出;

  1. /*****************************************************************
  2. *函数名称:  UART2Init
  3. *功能描述:  对串口2参数进行设置、485控制端口初始化
  4. *
  5. *输入参数:无
  6. *返 回 值:无
  7. *其他说明:无
  8. *当前版本:v1.0
  9. *作    者: 尹宣
  10. *完成日期:2012年8月3日
  11. *修改日期      版本号      修改人      修改内容
  12. *-----------------------------------------------------------------
  13. *
  14. ******************************************************************/
  15. void UART2Init(void)
  16. {
  17. GPIO_InitTypeDef GPIO_InitStructure;
  18. USART_InitTypeDef USART_InitStructure;
  19. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  20. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  21. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  22. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能外设时钟
  23. //GPIO结构的成员设置如下:
  24. /*--------------485控制端初始化------PA1----------*/
  25. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
  26. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
  27. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  28. GPIO_Init(GPIOA, &GPIO_InitStructure);
  29. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;          //485_TX
  30. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  31. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
  32. GPIO_Init(GPIOA, &GPIO_InitStructure);
  33. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;           //485_RX
  34. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  35. GPIO_Init(GPIOA, &GPIO_InitStructure);
  36. //串口的结构成员设置如下:
  37. USART_InitStructure.USART_BaudRate = 9600;
  38. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  39. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  40. USART_InitStructure.USART_Parity = USART_Parity_No;
  41. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  42. USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  43. USART_Init(USART2, &USART_InitStructure);
  44. USART_Cmd(USART2, ENABLE);
  45. /*方法一: 清发送完成标志*/
  46. //  USART_ClearFlag(USART3, USART_FLAG_TC);
  47. /*方法二:获取串口1状态标志位*/
  48. USART_GetITStatus(USART1, USART_FLAG_TC);
  49. }

第二步:发送数据

这里需要注意的是:

/* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去

如下两个方法语句解决第1个字节无法正确发送出去的问题 */

方法一:USART_ClearFlag(USART3, USART_FLAG_TC); /*清发送完成标志,Transmission Complete flag */

方法二:/*获取串口1状态标志位*/

               USART_GetITStatus(USART1, USART_FLAG_TC);

刚上电时出现乱码的原因:

while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);  // USART_FLAG_TXE---检测发送数据寄存器空标志位

如果USART_FLAG_TC---发送完成标志位

(1)       当设为USART_FLAG_TXE---检测发送数据寄存器空标志位—为空,但是发送移位寄存器不为空,数据还没有完全的发送出去,又有数据就被写进来了,所以就会容易出现乱码;

(2)       当设为USART_FLAG_TC—检测发送完成标志位—为空,即发送移位寄存器为空,数据才真正的发送出去,因此此时又有数据被写进来也不会发生乱码

STM32的数据发送有两个中断标志,一个是发送数据寄存器空标志,一个是发送完毕标志。两个标志都可以引起中断. 

要以中断的方式发送一个数据包,流程是这样的:

1.设置RS485的方向为发送,使能发送寄存器空中断,使能完毕进入串口中断。

2.串口中断里读取串口状态,并填充一个数据到发送数据寄存器,硬件自动清除发送数据寄存器空标志,串口数据发送开始。

3.串口发送完一个数据,发送数据寄存器变空,再进入中断,继续填充下一个数据,直到最后一个数据填充完,使能串口

 发送完毕中断。

4.最后一个数据发送完毕,再次进入中断,清除发送数据寄存器空标志,清除发送完毕中断标志,清除这两个中断标志

 的使能位,设置RS485的方向为接收.

  1. /*****************************************************************
  2. *                                      宏定义
  3. ******************************************************************/
  4. #define RX_485  GPIO_SetBits(GPIOA,GPIO_Pin_1);
  5. #define TX_485  GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  6. /*****************************************************************
  7. *函数名称:  UART2_TX485_Puts
  8. *功能描述:  发送字符串数据
  9. *
  10. *输入参数:str:要发送的字符串
  11. *返回值:无
  12. *其他说明:无
  13. *当前版本:v1.0
  14. *作    者: 梁尹宣
  15. *完成日期:2012年8月3日
  16. *修改日期      版本号      修改人      修改内容
  17. *-----------------------------------------------------------------
  18. *
  19. ******************************************************************/
  20. void UART2_TX485_Puts(char * str)
  21. {
  22. while(*str)
  23. {
  24. TX_485;     //打开485发送DE端口,关闭接收/RE端口
  25. DelayNmS(1);
  26. USART_SendData(USART2, *str++);
  27. /* Loop until the end of transmission */
  28. while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);  //检测发送数据寄存器空标志位
  29. DelayNmS(1);
  30. RX_485;     //关闭发送DE端口,打开接收/RE485端口,
  31. }
  32. }<span style="font-family:Times New Roman;font-size:14px;"> </span>

在485芯片的通信中,尤其要注意对485控制端DE的软件编程。为了可靠工作,在485总线状态切换时需要做适当延时,再进行数据收发。具体的做法是在数据发送状态下,   先将控制端置“1”,延时1ms左右的时间,在发送有效的数据,一包数据发送结束后再延时1ms后,将控制端置“0”,这样处理会使总线在状态切换时,有一个稳定的工作过程。

RS485通讯协议的应用 (转)的更多相关文章

  1. STM32菜鸟成长记录---RS485通讯协议的应用

    写作原因:近来蛋闲?非也  !  昨天一同事合作的项目代码出现的bug-----他的上位机每200ms给我发送命令向我这边下位机读取一些数据,在此过程会按下按键做一些另外操作并给他返回数据:(通信是通 ...

  2. 第41章 RS-485通讯实验—零死角玩转STM32-F429系列

    第41章     RS-485通讯实验 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...

  3. MODBUS-RTU通讯协议简介

    MODBUS-RTU通讯协议简介   什么是MODBUS? MODBUS 是MODICON公司最先倡导的一种软的通讯规约,经过大多数公司 的实际应用,逐渐被认可,成为一种标准的通讯规约,只要按照这种规 ...

  4. ISO7816通讯协议在工控主板EM9160中的实现方案

    在新的国家电网智能终端相关标准中,规定了通过专门的加密芯片来保证设备数据安全性的方法,而设备主控单元与加密芯片采用了广泛应用的ISO7816通讯协议.工控主板EM9160为了适应这一新的技术需求,对其 ...

  5. 如何快速掌握plc或工控机与其他设备的modbus通讯协议?包括格式与实际过程 RT,本人从事工控行业多年,对于PLC与触摸屏也算比较熟悉,唯独对这个通讯协议比较难理解,请教高人指导,从什么地方开始下手,或者是说如何正确理解报文格式或正确写入

    Modbus协议是OSI模型的第七层的应用层通讯协议,定义了不同类型设备间交换信息方式,以及信息的格式. Modbus的工作方式是请求/应答,每次通讯都是主站先发送指令,可以是广播,或是向特定从站的单 ...

  6. Modbus通讯协议

    <ignore_js_op> O1CN01P1wxTI1dCdw5nAeMO_!!85243700.jpg (287.43 KB, 下载次数: 0) 下载附件  保存到相册 2019-6- ...

  7. 基于dubbo框架下的RPC通讯协议性能测试

    一.前言 Dubbo RPC服务框架支持丰富的传输协议.序列化方式等通讯相关的配置和扩展.dubbo执行一次RPC请求的过程大致如下:消费者(Consumer)向注册中心(Registry)执行RPC ...

  8. 【读书笔记】iOS-防止通讯协议被轻易破解的方法

    开发者可以选择类似Protobuf之类的二进制通讯协议或者自己实现通讯协议,对于传输的内容进行一定程度的加密,以增加黑客破解协议的难度. 参考资料: <iOS开发进阶> --唐巧

  9. CNN 美国有线电视新闻网 wapCNN WAP 指无线应用通讯协议 ---- 美国有线电视新闻网 的无线应用

    wapCNN  wap指无线应用通讯协议  CNN美国有线电视新闻网   固, wapCNN 美国有线电视新闻网的无线应用 -------------------------------------- ...

随机推荐

  1. implement a system call in minix

    http://www.papervisions.com/implementing-system-call-in-minix-os/

  2. Spring.NET 中的 ADO.NET 数据访问的示例

    Spring.NET 1.3.1 中提供了一个使用 AdoTemplate 的完整示例,包括使用泛型和使用非泛型技术进行数据访问,这个示例位于下载的压缩包中\Spring.NET-1.3.1\Spri ...

  3. 官方windows10升级工具

    https://www.microsoft.com/zh-cn/software-download/windows10

  4. 硬盘安装win8系统方法汇总

    从硬盘安装 (推荐)硬盘安装方法一 使用Nt6 hdd installer进行安装,此方法适合XP,vista, Windows 7等系统. 下载Nt6 hdd installer(Win8硬盘安装工 ...

  5. ListView控件的Insert、Edit和Delete功能(第二部分)

    本系列文章将通过一个简单的实例,结合我自己使用ListView的情况,展示如何用ASP.NET 3.5 ListView控件进行基本的Insert.Edit和Delete操作. 系统要求: Windo ...

  6. WPF之TabControl控件用法

    先创建实体基类:NotificationObject(用来被实体类继承) 实现属性更改通知接口: using System; using System.Collections.Generic; usi ...

  7. vim 设置默认显示行号

    vim 要默认打开的时候显示行号,这样就可以不用每次编辑的时候在手动在命令模式下:set number 来显示行号. 具体做法是: 创建一个 .vimrc的配置文件. 在启动vim时,当前用户根目录下 ...

  8. 为什么要 urlencode()

    1.是因为当字符串数据以url的形式传递给web服务器时,字符串中是不允许出现空格和特殊字符的2. 因为 url 对字符有限制,比如把一个邮箱放入 url,就需要使用 urlencode 函数,因为 ...

  9. 【转】linux grep命令详解

    简介 grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它 ...

  10. Trie/最短的名字

    题目链接 /* 简单trie树的应用,注意在初始化的时候要把cnt也初始化,不然,WA! 下面的四分代码各有特点 */ //数组型,名字查询. #include<cstdio> #incl ...