源: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. gridview列绑定HyperLink

    <asp:HyperLink ID="HyperLink1" Target="_blank" runat="server" Navig ...

  2. js实现td排序及分组分类

    如题 <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...

  3. 全文检索工具推荐FileLocator

    全文检索工具推荐FileLocator https://www.baidu.com/link?url=_vaDZaJ_OePrAX-BTUD5hjTymnvN7_1oIAnWyS25hqxAg0nUH ...

  4. Hibernate 系列教程12-继承-Join策略

    Employee public class Employee { private Long id; private String name; HourlyEmployee public class H ...

  5. POJ 2182/暴力/BIT/线段树

    POJ 2182 暴力 /* 题意: 一个带有权值[1,n]的序列,给出每个数的前面比该数小的数的个数,当然比一个数前面比第一个数小的个数是0,省略不写,求真正的序列.(拗口) 首先想到的是从前到后暴 ...

  6. 动画——animation(2)

    日常中,我们使用的动画来源有两个方面—— 第一个,自己去定义. 通过@keyframes去定义即可,格式如下: @keyframe animatename{ 0%{ //这里面写初始的对象的css样式 ...

  7. 转:selenium 并行启动多个浏览器

    https://github.com/fool2fish/selenium-doc/blob/master/official-site/selenium-grid.md Selenium Grid 快 ...

  8. Linux 监控文件事件

    某些应用程序需要对文件或者目录进行监控,来侦测其是否发生了某些事件.Linux很贴心的为我们提供了inotify API,也是Linux的专有. inotify API 在使用之前一定要有一个inot ...

  9. 为什么有时候必须添加sys.setdefaultencoding('utf-8')

    今天在尝试Python的CGI模块时遇到中文字符不能正确显示的问题,很郁闷.在网上仔细找了找,终于解决了这个问题,现在将解决方法陈述如下,以防下次失误. 页面源代码如下 #-*- coding: ut ...

  10. Django之路:QuerySet API,后台和表单

    一.Django QuerySet API Django模型中我们学习了一些基本的创建和查询.这里专门讲以下数据库接口相关的接口(QuerySet API),当然你也可以选择暂时跳过这节.如果以后用到 ...