一、基本原理

1、主从多机通信拓扑图

2、主从多机通信的具体过程

1)使所有的从机的SM2位置1,以便接收主机发来的地址;

2)主机发出一帧地址信息,其中包括8位需要与之通信的从机地址,第9位为1;

3)所有从机接收到地址帧后,各自将所接收到的地址与本机地址比较,对于地址相同的从机,使SM2位清零以接收主机随后发来的所有信息。对于地址不符合的从机,仍保持SM2=1的状态,对主机随后发来的数据不予理睬,直至发送新的地址帧;

4)主机给已被寻址的从机发送控制命令和数据(数据帧的第9位为0);

5)本次通信结束后,从机重置SM2=1,主机可再寻址其它从机。

二、主从模式

首先要设定工作方式3:(主从模式+波特率可变)

SCON位定义:

SCON串口功能寄存器:SM0=1;SM1=1(工作方式3)

注:主机和从机都要为工作方式3。

1、工作方式2 (SM0 SM1 :1 0):

串行口为11位异步通信接口。发送或接收一帧信息包括1位起始位“0”、8位数据位、1位可编程位、1位停止位“1”。

发送数据:发送前,先根据通信协议由软件设置TB8为“奇偶校验位”或“数据标识位”,然后将要发送的数据写入SBUF,即能启动发送器。

发送过程是由执行任何一条以SBUF为目的寄存器的指令而启动的,把8位数据装入SBUF,同时还把TB8装到发送移位寄存器的第9位上,然后从TXD(P3.1)端口输出一帧数据。

接收数据:先置REN=1,使串行口为允许接收状态,同时还要将RI清“0”。然后再根据SM2的状态和所接收到的RB8的状态决定此串行口在信息到来后是否置R1=1,并申请中断,通知CPU接收数据。

当SM2=0时,不管RB8为“0”还是为“1”,都置RI=1,此串行口将接收发送来的信息。当SM2=1时,且RB8=1,表示在多机通信情况下,接收的信息为“地址帧”, 此时置RI=1,串行口将接收发来的地址。

当SM2=1时,且RB8=0,表示在多机通信情况下,接收的信息为“数据帧”, 但不是发给本从机的,此时RI不置为“1”,因而SBUF中接收的数据帧将丢失。

2、工作方式3 (SM0 SM1 :1 1):

为波特率可变的11位异步通信方式,除了波特率有所区别之外,其余方式都与方式2相同。

三、代码编写

1、主机.

1)主机的配置发送“地址”时,把TB8设定为1,发送数据时TB8设定为0;

2)主机在配置SCON寄存器时,不需要配置SM2=1;该位主要用于从机接收地址和数据时的区分;

3)其发送帧结构为:

主机的配置,及相关程序为:

//主机为STC12C5A60S2单片机,下面是初始化程序

void UART_init()

{

TMOD =0x20; //定时器1,工作方式2:8位、自动重装

PCON=0x00;//波特率不加倍$

TH1 = 0xfd; //fd: 9600bps @ 11.0592M

TL1 = 0xfd; //e8: 1200bps @ 11.0592M

SCON|= 0xd8; //串行口工作方式3 主机模式,不需设置SM2=1

TR1 = 1; //启动定时器1

ES = 1; //开串口中断

EA = 1; //中断 总开关

}

//主机端发送程序,使用为串口多机通信

void TXdata(unsignedchar addr,unsigned char *str)

TB8 = 1; //发送地址

SBUF = addr; //把地址发送出去

while(!TI); //判断是否发送成功(发送成功后TI会置1,需手动清0)

TI = 0;!

TB8 = 0; //发送数据

while(*str != '0') //发送数组

{

SBUF = (*str);

while(!TI);

TI = 0;-

str++;)

}

}

//中断程序

void UartReceive()interrupt 4 //串口中断服务函数

{!

ES = 0; //关闭串口中断

if(RI) //再次判断,是否接收到数据(接收到数据后,RI会置1,需手动清0)

{

RXData = SBUF;

if(RXData== '*') //判断是否接收到数据结束标志 $

{

LCD_Write_String(0,0,ReceiveData);

j_yang=0;$

}

else if(RXData=='#')

{

LCD_Write_String(0,1,ReceiveData);

j_yang=0;

}9 B7 W. E8 g) U3 i8 E

else //接收到 结束标志 $

{

ReceiveData[j_yang] = RXData;//没有接收到结束标志,正常保存数据至数组

j_yang++;

}

}

RI = 0; //清除接收标志位

ES = 1; //重新开启串口中断

}

2、从机

1)从机接收时,首先串口初始化时,使SM2=1(接收地址模式,即只能接收到TB8=1的数据,才触发中断),主机发送TB8=0的数据,被认为是总线上的主机发送给别机的通信数据,本机丢弃,不产生中断。

2)接收的地址与本机地址相符后,使SM2=0(接收数据模式,接收数据正常触发中断)

从机的配置及相关程序:

//使用的单片机是STC15W4K48S4,该单片机设置独立定时器为波特率发生器,配置程序,若是不使用此种单片机或者是此种波特率发生器,则除了SM2设置不一样之外,其他设置与主机是一致的。

void Serial_Init()

{

SCON = 0xf8; //8位数据,可变波特率

AUXR = 0x14; //允许独立波特率发生器运行,独立波特发生器每1个时钟周期记一次数

AUXR |= 0x01; // 独立波特率发生器作为串口1的波特率发生器,此时定时器1得到释放,可以作为独立定时器使用

T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值,其中FOSC为外部晶振的频率,BAUD为定义的波特率,此处为9600

T2H = (65536 - (FOSC/4/BAUD))>>8;

ES = 1; //使能串口中断

EA = 1;

//中断服务程序

void Uart(void)interrupt 4

{

ES = 0; //关闭串口中断

if(RI) //再次判断,是否接收到数据(接收到数据后,RI会置1,需手动清0)

{

RXData = SBUF;)

if(RXstart) //判断是否接收到过本地址;

{

if(RXData != '*') //判断是否接收到数据结束标志*

{

ReceiveData[j_yang] = RXData; //没有接收到结束标志,正常保存数据至数组

j_yang++;

}

else //接收到 结束标志*

{

RXstart= 0; //本次接收结束

UartSends(ReceiveData);//将接受的数据反过来发送回去

UartSendChar('#');//默认接收以#结束

SM2 = 1; //重新 配置为:只接收地址模式,下次发送TB8=1才中断

j_yang = 0;

Uart_flag1=1;

}

}

if(RXData == 2) //判断是否呼叫本机,地址范围:000– 254(00 - FE)

{

RXstart = 1; //开始接收数据

SM2 = 0; //配置为:接收数据 模式

}

}

RI = 0; //清除接收标志位'

ES = 1; //重新开启串口中断

}

四、注意事项

1)在写主机程序时,发现如果不写中断服务程序,单片机会默认一直发送第一个字节,最后发现应该是串口中断程序影响的,没有串口中断就会一直发送第一个字节,究其原因是数据发送完成后TI会置1,这将导致中断的产生,一旦没有中断服务程序,默认不产生中断,就一直发不清零。

2)主机程序配置时,不需要配置SM2,这样从机不管是谁发送数据,主机都可以接收的到,但是是在通信的时候做区分,比如主机给从机1发消息,发送完成后,从机1立马给主机发送请求的数据,发送完成之后,从机再配置SM2=1,只接收地址的模式。

3)波特率一定要设置的一致,否则无法正常通信。

【如果你喜欢EDA365的文章,记得关注和点赞哦!】

mfc如何将一个数组中的字节数据用串口发送出去_RS232串口多机通信相关推荐

  1. mfc如何将一个数组中的字节数据用串口发送出去_[翻译] 串口通信的帧(frame)...

    在串口通信中,只传输一个字节是简单的,但是如果要传送一个帧(多个字节),将面临以下问题: receiver从串口接收的是字节流,那它是如何知道帧的开始或结束呢?它又是如何知道这个帧有多长? 真实的物理 ...

  2. numpy使用[]语法索引二维numpy数组中指定范围数据行的数值内容(accessing rows in numpy array with specific range)

    numpy使用[]语法索引二维numpy数组中指定范围数据行的数值内容(accessing rows in numpy array with specific range) 目录

  3. 请编写fun()函数,函数的功能是删去一维数组中相同的数据在一起出现的数,相同的数只保留一个

    <程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p143 7.1.2 上级实训内容 [实训内容13]请编写fun()函数,函数的功能是删去一维数组中相同 ...

  4. 工具类:关于如何找到两个List数组中不同的数据的算法!

    找到两个List数组中不同的数据的算法! import java.util.ArrayList; import java.util.HashMap; import java.util.List; im ...

  5. 将一个数组中的字符串用指定字符分割开,分别放到另一个数组中

    #include "stdafx.h" #include <stdio.h> #include <string.h> #pragma warning(dis ...

  6. php两个数组去掉相同的,php如何删除两个数组中相同的数据

    php如何删除两个数组中相同的数据 发布时间:2021-03-12 10:27:42 来源:亿速云 阅读:77 作者:小新 这篇文章给大家分享的是有关php如何删除两个数组中相同的数据的内容.小编觉得 ...

  7. C语言学习之将一个数组中的值按逆序重新存放。例如,原来顺序为8,6,5,4,1. 要求改为1,4,5,6,8。

    将一个数组中的值按逆序重新存放.例如,原来顺序为8,6,5,4,1. 要求改为1,4,5,6,8. #include <stdio.h> #define N 5 void main(){i ...

  8. C语言试题四十六之将m行n列的二维数组中的字符数据,按列的顺序依次放到一个字符串中。

    1. 题目 请编写一个函数function,它的功能是:将m行n列的二维数组中的字符数据,按列的顺序依次放到一个字符串中. 2 .温馨提示 C语言试题汇总里可用于计算机二级C语言笔试.机试.研究生复试 ...

  9. angularjs 元素重复指定次数_[LeetCode] 442. 数组中重复的数据

    [LeetCode] 442. 数组中重复的数据 题目链接: https://leetcode-cn.com/problems/find-all-duplicates-in-an-array 难度:中 ...

最新文章

  1. 计算机中丢失qt5svg,无法找到“Qt5Svg”提供了一个程序包配置文件
  2. ASP.NET2.0+SQL Server2005构建多层应用 [转]
  3. 一些C语言学习的国外资源
  4. how does Fiori Mock server serve OData request with 202
  5. windows内存结构概述
  6. git 如何撤销提交
  7. aptana php 调试,aptana 3 + xdebug php
  8. python3练习-查找文件
  9. 北京2018网络赛 hihocoder#1828 : Saving Tang Monk II (BFS + DP +多开一维)
  10. 内存测试软件 ddr 4,DDR4内存理论性能测试
  11. C语言之判断直角三角形
  12. 处理火狐浏览器播放哔哩哔哩(BiliBili)视频时无法倍速问题
  13. 数据可视化第八章使用matplotlib绘制高级图表
  14. ffmpeg保存rtsp视频流为mp4文件
  15. 慢慢整理一下用到的游戏相关工具
  16. vscode能写winform窗体吗_VSCode——愉快的写C#
  17. 【IDEA】出现 Wrong tag ‘Author_‘ 错误的 Author 标签等的黄色警告问题
  18. [敏捷开发实践] 使用RACI Matrix划分敏捷团队的RR
  19. linux开启redis端口的防火墙
  20. 信息安全系统设计基础实验二—20135215黄伟业20135222胡御风

热门文章

  1. 超全整理|Python 操作 Excel 库 xlwings 常用操作详解!
  2. SAP BTP 平台 Cloud Application Programming 编程模型概述
  3. SAP UI5 应用开发教程之十五 - 对话框和 Fragments 的使用方式
  4. SAP Spartacus 如何获得当前渲染页面的 CMS 元数据
  5. 如何删除Github上一个pull request
  6. SAP UI5和Angularjs事件处理机制的实现比较
  7. SAP Spartacus里如何查看HTTP请求的状态
  8. 使用Windows10 software center升级版本1909
  9. SAP BSP, Java Web Project,Android和微信小程序的初始页面设置
  10. SAP新一代全栈开发工具:SAP Business Application Studio