485通讯协议程序怎么写(51单片机的485通信程序案例)
RS485程序

//-----------------------函数声明,变量定义--------------------------------------------------------#include <reg51.h>sbit RE_DE=P1^0;#define COUNT 10 // 定义接收缓冲区大小#define ADD 5 //定义设备地址unsigned char buffer[COUNT]; //定义接收缓冲区unsigned char point; //定义接收数据个数指示变量void UART_init(); //串口初始化函数void COM_send(void); //串口接收函数unsigned char CLU_checkdata(void);//计算校验位函数//--------------------------------------------------------------------------------------------------// 函数名称:UART_init()串口初始化函数// 函数功能:在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s// 串口接收中断允许,发送中断禁止//--------------------------------------------------------------------------------------------------void UART_init(){//初始化串行口和波特率发生器SCON =0x0F0; //选择串口工作方式为3,打开接收允许TMOD =0x21; //定时器1工作在方式2,定时器0工作在方式1TH1 =0xfd; //实现波特率9600(系统时钟11.0592MHZ)TL1 =0xfd; //实现波特率9600(系统时钟11.0592MHZ)TR1 =1; //启动定时器T1ET1 =0;ES=1; //允许串行口中断PS=1; //设计串行口中断优先级EA =1; //单片机中断允许SM2=1; //设备处于地址监听状态}//--------------------------------------------------------------------------------------------------// 函数名称:com_interrup()串口接收中断处理函数// 函数功能:接收包括起始位0xFE,地址位和终止位0xEF在内的十位数据到数据缓冲区,// 地址不匹配,则接收到的是无效数字,不写到接收缓冲区//--------------------------------------------------------------------------------------------------com_interrupt(void) interrupt 4 using 3{unsigned char RECEIVR_buffer;if(RI){ //处理接收中断RI=0; //清除中断标志位RECEIVR_buffer=SBUF; //接收串口数据if(point==0) //如果还没有接收到起始位{if(RECEIVR_buffer==0xFE) //判断是否起始标志位buffer[point++]=RECEIVR_buffer;//起始正确,接收起始位elsepoint=0; //不是,继续等待起始位}else if(point==1) //是否地址位{if(RECEIVR_buffer==ADD) //判断地址是否匹配buffer[point++]=RECEIVR_buffer;//地址匹配,接收开始接收elsepoint=0; //不匹配,继续下一个起始位}else if(point>0&&point<10) //判断是否接收够十位数据buffer[point++]=RECEIVR_buffer; //不够,把接收到的数据放入接收缓存区else point=0; //缓冲区已满,清除缓存区内数据重新接收}if(TI) //串口发送中断{TI=0; //清除发送中断}}//--------------------------------------------------------------------------------------------------// 函数名称:COM_send()串口发送函数// 函数功能:把数据缓冲区的十位数据发送出去//--------------------------------------------------------------------------------------------------void COM_send(void){RE_DE=1; //设置MAX483进入发送状态for(point=0;point<=10,TI=1;point++) //连续发送十位数据//把缓存区的数据都发送到串口{SBUF=buffer[point];TI=0;}RE_DE=0; //设置MAX483进入接收状态}//--------------------------------------------------------------------------------------------------// 函数名称:主函数// 函数功能:调度个子函数,完成通信过程//--------------------------------------------------------------------------------------------------void main(void){UART_init(); //初始化串口do{}while(point!=10); //判断数据是否接收完成COM_send(); //地址匹配,数据完整接收,调用发送程序通知主机SM2=0; //设置为点对点通信状态}。
手把手教你学51单片机之十八RS485通信与Modbus协议

在工业控制、电力通讯、智能仪表等领域,通常情况下是采用串口通信的方式进行数据交换。
最初采用的方式是RS232接口,由于工业现场比较复杂,各种电气设备会在环境中产生比较多的电磁干扰,会导致信号传输错误.除此之外,RS232接口只能实现点对点通信,不具备联网功能,最大传输距离也只能达到几十米,不能满足远距离通信要求。
而RS485则解决了这些问题,数据信号采用差分传输方式,可以有效的解决共模干扰问题,最大距离可以到1200米,并且允许多个收发设备接到同一条总线上。
随着工业应用通信越来越多,1979年施耐德电气制定了一个用于工业现场的总线协议Modbus协议,现在工业中使用RS485通信场合很多都采用Modbus协议,本节课我们要讲解一下RS485通信和Modbus协议。
单单使用一块KST-51开发板是不能够进行RS485实验的,应很多同学的要求,把这节课作为扩展课程讲一下,如果要做本课相关实验,需要自行购买USB转485通信模块。
18.1 RS485通信实际上在RS485之前RS232就已经诞生,但是RS232有几处不足的地方:1、接口的信号电平值较高,达到十几V,容易损坏接口电路的芯片,而且和TTL电平不兼容,因此和单片机电路接起来的话必须加转换电路。
2、传输速率有局限,不可以过高,一般到几十Kb/s就到极限了。
3、接口使用信号线和GND与其他设备形成共地模式的通信,这种共地模式传输容易产生干扰,并且抗干扰性能也比较弱。
4、传输距离有限,最多只能通信几十米。
5、通信的时候只能两点之间进行通信,不能够实现多机联网通信。
针对RS232接口的不足,就不断出现了一些新的接口标准,RS485就是其中之一,他具备以下的特点:1、我们在讲A/D的时候,讲过差分信号输入的概念,同时也介绍了差分输入的好处,最大的优势是可以抑制共模干扰。
尤其工业现场的环境比较复杂,干扰比较多,所以通信如果采用的是差分方式,就可以有效的抑制共模干扰。
485通信程序(51单片机)

485通信程序(51单片机)什么是485通信?RS-485是一种串行通信协议,它使用差分信号传输数据。
485通信支持了在两个或以上设备之间传输数据的需求,比如用于电子计算机、通信设备、工业自动化等等。
RS-485已广泛应用于数控机床、自动化设备控制等领域中。
单纯的485通信包含四种通信模式:点对点、总线形、多主机和简介式通信。
其中,点对点通信指的是一对一的通信方式;总线形通信指的是一对多的群通信方式,所有设备都在同一条总线上发送和接收数据;多主机通信指的是多台主机的通信方式,多个设备都可以同时发送数据;简介式通信是一种用于仅需要发送少量数据的情况的通信方式。
下面介绍一下485通信的部分基本知识1.485通信的传输距离远,一般可以达到1200米。
2.485通信具有较强的抗干扰能力。
3.485通信使用差分信号进行传输,信号稳定,传输速率也比较快。
4.485通信可以支持多个设备同时进行通信,但是在同一时间内只有一个设备可发送数据。
5.在采用485通信时,一定要注意通讯端口的设置,如波特率、数据位、停止位等。
程序实现原理该程序使用了51单片机作为主控制器实现了基本的485通信,具体实现如下:1.通信模式的设置在程序开始时,需要设置通信模式。
如果通信模式为点对点通信,则可以直接使用UART通信模块进行通信;如果是多点通信,则需要使用485通信芯片。
2.通讯端口的配置在进行485通讯时,需要进行通讯端口的配置,包括波特率、数据位、停止位等参数的设定。
在485通信模式下,只有一个设备可为主设备,其他设备均为被设备。
在发送数据时,主设备的TXD口要与外部总线的D+口相连,而D-口不连接,从设备的TXD口要与D-口相连,而D+口不连接。
在接收数据时,主设备的RXD口要与D+口相连,而D-口不连接,从设备的RXD口要与D-口相连,而D+口不连接。
3.数据的发送和接收在发送和接收数据时,需要采用特定的方式进行报文的封装和解析。
51单片机串口485通讯程序

/* 以下为单片机串口485通讯程序,从机程序(当然也适用于主机程序),主机发送可以先用串口帮手软件来调试,经过Keil uVision4实际测试,测试效果如结尾图片所示, 大部分来自网络,只是改了两个地方: len = sizeof(dbuf),if(i >=( __ERRLEN+1)) // 帧超长,错误,返回,就可以实现了,其中的原因自已体会吧*/#ifndef __485_C__#define __485_C__#include <reg51.h>#include <string.h>#include <stdio.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/* 通信命令*/#define __ACTIVE_ 0x01 // 主机询问从机是否存在#define __GETDATA_ 0x02 // 主机发送读设备请求#define __OK_ 0x03 // 从机应答#define __STATUS_ 0x04 // 从机发送设备状态信息#define __MAXSIZE 0x08 // 缓冲区长度#define __ERRLEN 12 // 任何通信帧长度超过12则表示出错//uchar dbuf[__MAXSIZE]; // 该缓冲区用于保存设备状态信息uchar dbuf[__MAXSIZE];//={0,1,2,3,4,5,6,7}; // 该缓冲区用于保存设备状态信息uchar dev; // 该字节用于保存本机设备号sbit M_DE = P1^0; // 驱动器使能,1有效sbit M_RE = P1^1; // 接收器使能,0有效void get_status(); // 调用该函数获得设备状态信息,函数代码未给出void send_data(uchar type, uchar len, uchar *buf); // 发送数据帧bit recv_cmd(uchar *type); // 接收主机命令,主机请求仅包含命令信息void send_byte(uchar da); // 该函数发送一帧数据中的一个字节,由send_data()函数调用void main(){uchar type;uchar len;/* 系统初始化*/P1 = 0xff; // 读取本机设备号//dev = (P1>>2);dev = 0x01;TMOD = 0x20; // 定时器T1使用工作方式2TH1 = 250; // 设置初值TL1 = 250;TR1 = 1; // 开始计时PCON = 0x80; // SMOD = 1SCON = 0x50; // 工作方式1,波特率9600bps,允许接收ES = 0; // 关闭串口中断//IT0 = 0; // 外部中断0使用电平触发模式//EX0 = 1; // 开启外部中断0EA = 1; // 开启中断/* 主程序流程*/while(1) // 主循环{if(recv_cmd(&type) == 0) // 发生帧错误或帧地址与本机地址不符,丢弃当前帧后返回continue;switch(type){case __ACTIVE_: // 主机询问从机是否存在send_data(__OK_, 0, dbuf); // 发送应答信息,这里buf的内容并未用到break;case __GETDA TA_:// len = strlen(dbuf);//在C51中不能这个函数计算unsigned char型,这个函数只能计算char型len = sizeof(dbuf);// len =0x08;send_data(__STA TUS_, len, dbuf); // 发送设备状态信息break;default:break; // 命令类型错误,丢弃当前帧后返回}}}void READSTATUS() interrupt 0 using 1 // 产生外部中断0时表示设备状态发生改变,该函数使用寄存器组1{get_status(); // 获得设备状态信息,并将其存入dbuf指向的存储区,数据最后一字节置0表示数据结束}/* 该函数接收一帧数据并进行检测,无论该帧是否错误,函数均会返回* 函数参数type保存接收到的命令字* 当接收到数据帧错误或其地址位不为0时(非主机发送帧),函数返回0,反之返回1*/bit recv_cmd(uchar *type){bit db = 0; // 当接收到的上一个字节为0xdb时,该位置位bit c0 = 0; // 当接收到的上一个字节为0xc0时,该位置位uchar data_buf[__ERRLEN]; // 保存接收到的帧__ERRLEN=12;uchar tmp;uchar ecc = 0;uchar i;M_DE = 0; // 置发送禁止,接收允许M_RE = 0;/* 接收一帧数据*/i = 0;while(!c0) // 循环直至帧接收完毕{RI = 0;while(!RI);tmp = SBUF;RI = 0;if(db == 1) // 接收到的上一个字节为0xdb{switch(tmp){case 0xdd:data_buf[i] = 0xdb; // 0xdbdd表示0xdbecc = ecc^0xdb;db = 0;break;case 0xdc:data_buf[i] = 0xc0; // 0xdbdc表示0xc0ecc = ecc^0xc0;db = 0;break;default:return 0; // 帧错误,返回}i++;}switch(tmp) // 正常情况{case 0xc0: // 帧结束c0 = 1;break;case 0xdb: // 检测到转义字符db = 1;break;default: // 普通数据data_buf[i] = tmp; // 保存数据ecc = ecc^tmp; // 计算校验字节i++;}//if(i == __ERRLEN) // 帧超长,错误,返回if(i >=( __ERRLEN+1)) // 帧超长,错误,返回return 0;}/* 判断帧是否错误*/if(i<4) // 帧过短,错误,返回return 0;if(ecc != 0) // 校验错误,返回return 0;if(data_buf[0] != dev) // 非访问本机命令,错误,返回return 0;*type = data_buf[1]; // 获得命令字return 1; // 函数成功返回}/* 该函数发送一帧数据帧,参数type为命令字、len为数据长度、buf为要发送的数据内容*/void send_data(uchar type, uchar len, uchar *buf){uchar i;uchar ecc = 0; // 该字节用于保存校验字节M_DE = 1; // 置发送允许,接收禁止M_RE = 1;send_byte(dev); // 发送本机地址ecc = dev;send_byte(type); // 发送命令字ecc = ecc^type;send_byte(len); // 发送长度ecc = ecc^len;for(i=0; i<len; i++) // 发送数据{send_byte(*buf);ecc = ecc^(*buf);buf++;}send_byte(ecc); // 发送校验字节TI = 0; // 发送帧结束标志SBUF = 0xc0;while(!TI);TI = 0;}/* 该函数发送一个数据字节,若该字节为0xdb,则发送0xdbdd,若该字节为0xc0则,发送0xdbdc */void send_byte(uchar da){switch(da){case 0xdb: // 字节为0xdb,发送0xdbdd TI = 0;SBUF = 0xdb;while(!TI);TI = 0;SBUF = 0xdd;while(!TI)TI = 0;break;case 0xc0: // 字节为0xc0,发送0xdbdcTI = 0;SBUF = 0xdb;while(!TI);TI = 0;SBUF = 0xdc;while(!TI)TI = 0;break;default: // 普通数据则直接发送TI = 0;SBUF = da;while(!TI);TI = 0;}}#endif/* 调试结果*/。
485通信程序

本实验实现的功能和12.5节的完全相同,也是通过串行口接收上位机的启、停协议,然后根据协议来控制计数的启动和暂停,单片机每次计数过0向上位机返回过0消息。
本实验的主要代码如下:main.c源文件//main.c#include <reg51.h> //包含头文件#include "fun.h"void Timer0_interrupt() interrupt 1{TH0 = T0_50ms >> 8; //重装初值TL0 = T0_50ms;if ((++ count_in_T0) == 20) //count_in_T0自加到20,计时1s{count_in_T0 = 0;if ( (++ display_num) ==60){ //display_num自加1后判断是否等于60display_num = 0;//上发过0消息send(0xf0);send(0x01);send(0xf1);}}}void USART_interrupt() interrupt 4{char checkXOR;if (RI) //接收中断{RI = 0;reciev[rec_num] = SBUF;rec_num ++;if ((rec_num == 3) && (reciev[0] == 0x0f) )//接收到3字节,并且包头正确{checkXOR = reciev[0] ^ reciev[1];if (checkXOR == reciev[2] ) //如果异或校验正确,判断命令 {switch (reciev[1]){case 0x01:TR0 = 1; //启动rec_num = 0; //指令正确,清空缓冲区break;case 0x02:TR0 = 0; //暂停rec_num = 0; //指令正确,清空缓冲区break;default: //如果指令不正确,缓冲区左移reciev[0] = reciev[1];reciev[1] = reciev[2];rec_num --;break;}}}}if (TI){TI = 0;}}main(){unsigned char shi, ge; //定义十位、个位要输出的数据 ms_delay(100);init_port();init_usart();init_timer();dir = 0; //485接收数据rec_num = 0;display_num = 0;count_in_T0 = 0;//把两个数码管都关闭en2 = 1;en1 = 1;EA = 1; //开总中断while(1){shi = display_num / 10;ge = display_num % 10;display(shi,ge);}}fun.h头文件代码如下://fun.h//定义端口寄存器sfr P0M0 = 0X93;sfr P0M1 = 0X94;sfr P1M0 = 0X91;sfr P1M1 = 0X92;sfr P2M0 = 0X95;sfr P2M1 = 0X96;sfr P3M0 = 0Xb1;sfr P3M1 = 0Xb2;#define fosc 11059200L#define T0_50ms (65536 - (fosc/12/50000)) //50ms定时参数sbit en1 = P2^6;sbit en2 = P2^7;sbit dir = P3^2; //485方向控制unsigned char display_num,count_in_T0; //计数值、进入定时器的次数char reciev[3], rec_num; //保存接收到的数据/*共阴极数码管0~9的字形码"0" 3FH "5" 6DH"1" 06H "6" 7DH"2" 5BH "7" 07H"3" 4FH "8" 7FH"4" 66H "9" 6FH*/const unsigned char seg7[10] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};void init_port(){P0M1 = 0xff;P0M0 = 0xff;P2M1 |= 0xc0;P2M0 |= 0xc0;P3M1 = 0x00; //P3.2准双向口模式P3M0 = 0x00;}void init_usart(){SM0 = 0;SM1 = 1;REN = 1;ES = 1;}void init_timer(){TMOD |= 0X01; //定时器0模式1,16bitTH0 = T0_50ms >> 8; //TH0 = T0_50ms / 256TL0 = T0_50ms; //TL0 = T0_50ms % 256ET0 = 1; //允许T0中断TMOD |= 0X20; //定时器1模式2,8bit自动重装 TH0 = 0xfd; //对应波特率9600TL0 = 0xfd;ET1 = 1; //允许T1中断TR1 = 1;}//定义延时函数void ms_delay(unsigned int t){unsigned int i;for (t; t > 0; t--) //外层循环t次for (i = 110;i > 0; i--) //内层循环110次;}void display(unsigned char c2, unsigned char c1) {P0 = seg7[c2]; //送入十位的段码en2 = 0; //显示DS2ms_delay(10);en2 = 1; //关闭DS2P0 = seg7[c1]; //送入个位的段码en1 = 0; //显示DS1ms_delay(10);en1 = 1; //关闭DS1}void send(char c){dir = 1; //485发送数据SBUF = c;while(!TI); //等待发完dir = 0; //485接收数据}讲解:本实验和12.5节的串行口收发实验基本相同,单片机串行口经由MAX1487芯片收发数据的过程对编程人员来说是完全透明的,我们只用跟平时操作串行口一样的方法来控制就可以了。
485通信程序(51单片机)【范本模板】

#include〈reg52.h〉#include<string。
h〉#define uchar unsigned char#define uint unsigned int/*通信命令*/#define _ACTIVE_ 0x01 // 主机询问从机是否存在#define _GETDATA_ 0x02 //主机发送读设备请求#define _OK_ 0x03 //从机应答#define _STATUS_ 0x04 //从机发送设备状态信息#define _MAXSIZE 0x08 //缓冲区长度#define _ERRLEN 12 //任何通信帧长度超过12则表示出错uchar dbuf[MAXSIZE] ;//该缓冲区用于保存设备状态信息uchar dev; //该字节用于保存本机设备号sbit M_DE = P1^0; //驱动器使能,1有效sbit M_RE = P1^1; //接收器使能,0 有效void get_status();//调用该函数获得设备状态信息,函数全码未给出void send_data(uchar type,uchar len,uchar *buf);//发送数据帧bit recv_cmd(uchar *type); //接收主机命令,主机请求包含命令信息。
void send_byte(uchar da); //该函数发送一帧数据中的一个字节,由send_data()函数调用void main(){uchar type;uchar len;/*系统初始化*/P1 = 0xff ;//读取本机设备号dev = (P1>〉2);TMOD = 0x20;//定时器T1使用方式2TH1 = 250;TL1 = 250;TR1 = 1;//开始计时PCON = 0x80;//SMOD = 1;SCON = 0x50;//工作方式1,波特优选法9600bps,允许接收ES = 0; // 关闭串品中断IT0 = 0; //外部中断0使有电平触发模式EX0 = 1; // 开启外部中断0EA = 0;//开启总中断/*主程序流程*/while(1){if(recv_cmd(&type) ==0) //发送帧错误或帧地址与本机地址不符,丢弃当前帧后返回continue;switch(type){case _ACTIVE_://主机询问从机是否存在send_data(_OK_,0,dbuf);// 发送应答信息,这里的buf 的内容并未用到break;case _GETDA TA_: //主机发送读设备请求len = strlen(dbuf);snd_data(_STA TUS_,len,dbuf) ;// 发送设备信息break;default:break;//命令类型错误,丢弃当前帧返回}}}}void READSTATUS() interrput 0 using 1 //产生外部中断0时表示设备状态发生改变,该函数使用寄存器组1{get_status(); //获得设备状态信息,并将其存入dbuf指向的存储区,数据最后一个字节置0表示数据结束}}/*该函数接收一帧数据度进行检测,无论该帧是否错误,函数均会返回。
rs485协议详解单片机编程

rs485协议详解单片机编程RS485协议详解单片机编程1. 协议双方基本信息甲方:(以下简称“甲方”)地址:联系人:电话:邮箱:乙方:(以下简称“乙方”)地址:联系人:电话:邮箱:2. 各方身份、权利、义务、履行方式、期限、违约责任2.1 甲方身份、权利、义务、履行方式、期限、违约责任甲方为RS485通讯协议的发起方,其权利、义务、履行方式、期限、违约责任如下:权利:1. 确定通讯协议的实现方案;2. 对乙方提供的通讯协议实现方案进行审核并提出修改意见;3. 在付款后,获得乙方提供的符合要求的实现方案。
义务:1. 提供通讯协议的需求文档及其他相关资料;2. 对乙方提供的通讯协议实现方案进行评估并提出需要修改的意见;3. 对于乙方提供的符合要求的实现方案进行支付。
履行方式:1. 双方确认和签署本协议后,甲方向乙方提供通讯协议的需求文档及其他相关资料;2. 乙方拟定通讯协议实现方案并提交给甲方审查;3. 甲方对乙方提供的通讯协议实现方案进行评估并提出需要修改的意见,乙方对意见进行修改并重新提交审查;4. 经过双方的多次确认和修改后,乙方提供符合甲方要求的实现方案,并向甲方提供;5. 甲方对乙方提供的符合要求的实现方案进行支付。
期限:本协议签署后,甲乙双方应在合理时间内完成上述流程。
违约责任:1. 若乙方违约,甲方有权解除本协议,并要求乙方承担相应的赔偿责任;2. 若甲方违约,应承担相应的违约责任。
2.2 乙方身份、权利、义务、履行方式、期限、违约责任乙方为RS485通讯协议的实现方,其权利、义务、履行方式、期限、违约责任如下:权利:1. 按照甲方提供的需求文档及其他相关资料进行通讯协议实现方案的拟定;2. 享有按约定支付的费用。
义务:1. 按照甲方提供的需求文档及其他相关资料提供符合要求的通讯协议实现方案;2. 对于甲方提出的修改意见,及时进行修改并重新提交审查。
履行方式:1. 双方确认和签署本协议后,甲方向乙方提供通讯协议的需求文档及其他相关资料;2. 乙方拟定通讯协议实现方案并提交给甲方审查;3. 甲方对乙方提供的通讯协议实现方案进行评估并提出需要修改的意见,乙方对意见进行修改并重新提交审查;4. 经过双方的多次确认和修改后,乙方提供符合甲方要求的实现方案,并向甲方提供;5. 甲方对乙方提供的符合要求的实现方案进行支付。
485通信程序实例

bdata uchar Repeater_Address _at_ 0x26; //中继器地址
sbit RA_0 = Repeater_Address^0;
sbit PaOData4 = PaOData^4;
sbit PaOData5 = PaOData^5;
sbit PaOData6 = PaOData^6;
sbit PaOData7 = PaOData^7;
s; //收到上位机对下位机的广播信号(时间、日期)
sbit Com1Data_Sent = Status2^5; //串口1已发送一字节
sbit tem_bit = Status2^6; //临时位变量
sbit Com1_Finished = Status2^7; //串口1数据已接收完毕
bdata uchar Status3 _at_ 0x22; //中继器状态标志
sbit Alarm_Over = Status3^0; //掉电时下位机侧传来的报警数据结束
sbit RA_7 = Repeater_Address^7;
bdata uchar Repeater_Status _at_ 0x27; //中继器状态标志位
sbit DHead_Arrived = Repeater_Status^0;
uchar data R_P_Data_Buf1 _at_ 0x33; //Com2读数据缓冲区指针1
uchar data W_P_Data_Buf2 _at_ 0x34; //并口写数据缓冲区指针2
uchar data R_P_Data_Buf2 _at_ 0x35; //并口读数据缓冲区指针2
485双机通信程序设计说明

“485双机通信”程序设计说明1 程序设计思路与方法本案例程序设计主要分为:串行口通信、按键检测和数码管显示3个部分。
两块单片机初始化后均为接收状态,通过按键扫描模块对KEY1,KEY2,KEY3进行按键判断,单片机通过对P3.3和P1.7的电平检测,每检测到端口有低电平产生则相应实现变量display的加减,使P2.3=0将数据传递给P0口通过数码管显示出来,当按下KEY1键触发外部中断0,单片机由接收态转换为发送态,将数据通过485模块传递给另一块单片机显示出来,然后立即返回接收状态,从而实现双机通信。
1.1 宏定义#define S2RI 0x01 //接收中断请求标志位#define S2TI 0x02 //发送中断请求标志位#define NONE_PARITY 0 //无校验#define PARITYBIT NONE_PARITY //定义校验位#define FOSC 11059200L //系统时钟频率#define BAUD 9600 //串口波特率#define TM (65536-(FOSC/4/BAUD)) //定时器初始时间1.2 定义变量bit busy ; //串口忙信号标志(1表示正在发送,0表示空闲)uint8 rev_data ; //串口接收的数据uint8 display ; //数码管显示数据uint8 seg_sel[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00}; //数码管段选数组,显示0-f 1.3 相关函数void Uart2Init(void); //串行口初始化函数void CPUInit(void); //CPU初始化函数,配置相关寄存器和IO口模式void delay(void); //延时函数void ser2_int(void) interrupt 8 using 1 //串口中断处理函数void ex_int0() interrupt 0 //外部中断0处理函数开始If 按键3被按下Then 当前值加一If 按键2被按下Then 当前值减一按键扫描初始化(串口、数码管等)485处于接收态485转换为发送态发送数据(串口中断)485转换回接收态退出按键中断进入按键中断当按键1被按下时,进入中断图1 双机通信流程图2 相关寄存器的配置 2.1 选择485芯片引脚:P_SW2:外围设备功能切换控制寄存器2(不可位寻址)串口2可在2个地方切换,由S2_S 控制位来选择。
基于RS485协议实现单片机与单片机之间的通信

基于RS-485协议实现单片机与单片机之间的通信摘要:介绍以RS-485为通信方式的两个单片机之间的通信,同时给出单片机与单片机之间的通信程序设计。
关键词:RS-485通信单片机串行通信0 引言随着工业化的进展,人们对现场仪表的要求愈来愈高,为了知足操纵室对现场的实时监控,确保现场数据的实时获取,需要用一种方式将现场情形实时反映给操纵室,咱们研究了一种方便简单功、能优越的通信方式:用RS-485实现现场单片机和操纵室单片机的实时通信。
通过操作操纵室单片机就能够实现对现场单片机的操作,节省了大量的时刻和相应的人力。
1、RS-485通信协议RS-485采纳平稳传输方式,连接时需要在传输线上接终接电阻。
RS-485能够采纳二线与四线方式,二线制可实现真正的多点双向通信,采纳四线连接时,即只能有一个主(Master)设备,其余为从设备,不管是四线仍是二线连接方式总线上最多可接32个设备。
RS-485最大传输距离约为1219米,最大传输速度为10Mb/s。
平稳双绞线的长度与传输速度成反比,在100kb/s速度以下,才可能利用规定最长的电缆长度。
只有在很短的距离下才能取得最高速度传输。
一样100米长双绞线最大传输速度仅为1Mb/s。
RS-485需要2个终接电阻,其阻值要求等于传输电缆的特性阻抗,终接电阻接在传输总线的两头。
在短距离传输时可不需终接电阻,即一样在300米以下不需终接电阻。
本设计中采纳的485通信元件是75LBC184,该器件带有内置高能量瞬变噪声爱惜装置,可提供靠得住的低本钱的直连(不带绝缘变压器)数据线接口,不需要任何外部元件。
2、单片机与单片机的通信系统本设计中单片机选用C8051F020,该单片机有100个功能引脚,其中有64个通用I/O端口。
C8051F020内有2个增强型串行口:UARTO和UART1,这两个串行口都能够工作在全双工异步方式或半双工同步方式,而且支持多处置器通信。
75LBC184与单片机连接时只需将R和D端别离与单片机的RXD 和TXD 相连即可。
51单片机实现RS485

default: // 普通数据则直接发送TI = 0;SBUF = da;while(!TI);TI = 0;}}#endifRS-232接口实现计算机和单片机通信程序作者:佚名来源:本站原创点击数:…更新时间:2008年07月10日【字体:大中小】//此程序通过RS-232接口来完成计算机和单片机通信(程序已用p1 8f458试验板上调试通过)//程序的调试可以用"串口调试助手V2.1"辅助完成,此程序可在htt p:// 下载//此程序首先发送测试数据55H,再通过中断实现数据的接收和发送#include "p18f458.h"void InterruptHandlerHigh(void);//初始化程序void initial(){SPBRG=0X19; //选择传输波特率为9600bpsTXSTA=0X04; //选择异步高速方式传输8位数据RCSTA=0X80; //允许同步串行口工作TRISC=0X80; //将RC7,RC6设置为输入,断绝与外接电路的连接 TXSTAbits.TXEN=1; //发送允许RCSTAbits.CREN=1; //接受数据允许PIE1bits.RCIE=1; //接收中断使能INTCON=0XC0; //总中断和外围中断允许}//高优先级中断向量#pragma code InterruptVectorHigh=0x08void InterruptVectorHigh (void){_asmgoto InterruptHandlerHigh //跳到中断程_endasm}//高优先级中断服务程序#pragma code#pragma interrupt InterruptHandlerHighvoid InterruptHandlerHigh (){while(PIR1bits.RCIF==1) //若接收中断标志不为1,则为误操作,返回{TXREG=RCREG; //将接收到的数据放入发送寄存器,并启动发送 }}//主程序main(){initial(); //系统初始化TXREG=0X55; //发送数据55H进行测试for(;;);}------------------------------------------汇编语言版本的RS-232接口实现计算机和单片机通信程序------------;此程序通过RS-232接口来完成计算机和单片机通讯(程序以在p18 f458试验板上调通);本单片机程序由提供;此程序首先发送测试数据55H,再通过中断实现数据的接收和发送;程序的调试可以用"串口调试助手V2.1"辅助完成LIST P=18f458INCLUDE "P18f458.INC"ORG 0x00GOTO MAINORG 0x08GOTO INTSERVEORG 0X30;**************中断服务子程序***************INTSERVEBTFSS PIR1,RCIF ;接收中断标志为1?GOTO ERR_RE ;误操作,返回MOVF RCREG,0 ;否则,将接收到的数据通过W寄存器MOVWF TXREG ;放入发送寄存器,并启动发送ERR_RE NOPRETFIE;****************初始化程序***************INITIAL NOPMOVLW 0X19 ;选择传输波特率为9600bpsMOVWF SPBRGMOVLW 0X04 ;选择异步高速方式传输8位数据MOVWF TXSTAMOVLW 0X80 ;允许同步串行口工作MOVWF RCSTAMOVLW 0X80 ;将RC7,RC6设置为输入,断绝与外接电路的连接MOVWF TRISCBSF TXSTA,TXEN ;发送允许BSF RCSTA,CREN ;接受数据允许BSF PIE1,RCIE ;接收中断使能MOVLW 0XC0 ;总中断和外围中断允许MOVWF INTCONRETURN;**********************主程序********************* MAIN NOPCLRWDTCALL INITIALMOVLW 0X55 ;发送数据55H进行测试MOVWF TXREGLOOPGOTO LOOPEND两片51单片机互相通信的串行通信程序(一个发送程序,一个接收程序)2007-05-27 08:27;系统晶振是 11.0592 MHz;51单片机发送单片机程序;此程序用Proteus仿真通过;此程序在硬件上测试通过;2007-05-27;附有简化电路图;为了使初学者能看懂,程序与图尽可能的简单扼要;实验现象为,发送端的P1口的哪个键被接下,接收端的哪个灯对应着亮;如果把两个单片机的T和R通过无线模块(如基于MCP2120芯片的模块)来扩充,便可做成无线通信ORG0000HAJMPSTARTORG0040HSTART:MOVSP,#60HMOVSCON,#50H;串口方式 1MOVTMOD,#20H;T1 方式2MOVTL1,#0FDH;波特率 9600 的常数MOVTH1,#0FDHSETBTR1movr5,#00hWAIT:movp1,#0ffhmova ,p1movr5,alcalldelay ;读键盘,这里去抖动,还要加几句话mova ,p1nopCJNEA,5,WAIT ;是否有键输入MOVSBUF,a;串口输出键盘输入的值NOPSS: JBCTI,WAIT;是否发送完毕SJMPSSDELAY:;延时子程序PUSH;保存现场PUSH1MOV0,#06HDELAY1: MOV 1,#0HDJNZ1,$DJNZ0,DELAY1POP1;恢复现场POPRETEND;系统晶振是 11.0592 MHz;51单片机接收单片机程序;此程序用Proteus仿真通过;此程序在硬件上测试通过;2007-05-27;附有简化电路图;为了使初学者能看懂,程序与图尽可能的简单扼要;实验现象为,发送端的P1口的哪个键被接下,接收端的哪个灯对应着亮;如果把两个单片机的T和R通过无线模块(如基于MCP2120芯片的模块)来扩充,便可做成无线通信ORG0000HAJMPSTARTORG0040HSTART:MOVSCON,#50H;串口方式 1MOVTMOD,#20H;T1 方式 2MOVTL1,#0FDH;波特率 9600 的常数MOVTH1,#0FDHSETBTR1WAIT:JBCRI,DIS_REC;是否接收到数据sjmpwaitDIS_REC:MOVA,SBUF;读串口接收到的数据movp1,aSJMPwaitend51单片机串行口通信程序设计例子时间:2009-03-06 17:13来源:未知作者:牛牛点击: 768次串行口方式0应用编程 8051单片机串行口方式0为移位寄存器方式,外接一个串入并出的移位寄存器,就能扩展一个并行口。
stc15单片机写485通讯程序

stc15单片机写485通讯程序如何在STC15单片机上编写485通信程序引言:STC15单片机是一种常用的单片机芯片,具有低功耗、高性能等特点,在工业自动化领域得到了广泛应用。
其中,485通信是一种常用的通信方式,具有抗干扰能力强、传输距离远等优势。
本文将详细介绍如何在STC15单片机上编写485通信程序,帮助读者了解实际操作过程。
一、了解485通信协议在开始编写485通信程序之前,我们首先要了解485通信协议。
485通信协议是一种串口通信协议,它定义了通信设备之间的数据传输规则。
它使用两根线实现全双工的通信,其中A、B两线分别用于发送和接收数据。
在编写485通信程序时,我们需要掌握标准的485通信协议,包括帧结构、波特率、数据格式等内容。
二、准备开发环境在编写485通信程序之前,我们需要准备好相应的开发环境。
首先,我们需要一台电脑,并安装好STC15系列单片机的开发软件,例如Keil C51。
然后,我们需要准备一块STC15单片机开发板,以及一台支持485通信的外部设备,例如电机控制器、传感器等。
三、了解STC15单片机的485通信功能STC15单片机具有内置的硬件串口模块,可用于实现485通信功能。
我们需要了解STC15单片机的串口模块的工作原理和使用方法。
具体来说,我们需要了解串口的引脚定义、波特率设置、数据格式配置等内容。
四、编写485通信程序接下来,我们可以开始编写485通信程序了。
在Keil C51开发环境中,我们可以利用C语言来编写程序。
首先,我们需要定义相应的引脚,将STC15单片机的串口引脚与外部设备的485通信引脚连接起来。
然后,我们需要进行相应的配置,例如设置波特率、数据位数、停止位等。
最后,我们可以编写数据发送和接收的代码,实现数据的传输和处理。
在编写485通信程序时,需要注意以下几个关键点:1. 引脚定义:需要根据具体的开发板和外部设备,定义好STC15单片机的串口引脚。
手把手教你学51单片机之十八RS485通信与Modbus协议

在工业控制、电力通讯、智能仪表等领域,通常情况下是采用串口通信的方式进行数据交换。
最初采用的方式是 RS232 接口,由于工业现场比较复杂,各种电气设备会在环境中产生比较多的电磁干扰,会导致信号传输错误。
除此之外,RS232 接口只能实现点对点通信,不具备联网功能,最大传输距离也只能达到几十米,不能满足远距离通信要求。
而 RS485 则解决了这些问题,数据信号采用差分传输方式,可以有效的解决共模干扰问题,最大距离可以到1200 米,并且允许多个收发设备接到同一条总线上。
随着工业应用通信越来越多, 1979 年施耐德电气制定了一个用于工业现场的总线协议 Modbus 协议,现在工业中使用RS485 通信场合很多都采用 Modbus 协议,本节课我们要讲解一下 RS485 通信和Modbus 协议。
单单使用一块KST-51 开发板是不能够进行RS485 实验的,应很多同学的要求,把这节课作为扩展课程讲一下,如果要做本课相关实验,需要自行购买USB 转 485 通信模块。
18.1 RS485通信实际上在 RS485 之前 RS232 就已经诞生,但是RS232 有几处不足的地方:1、接口的信号电平值较高,达到十几V ,容易损坏接口电路的芯片,而且和TTL 电平不兼容,因此和单片机电路接起来的话必须加转换电路。
2、传输速率有局限,不可以过高,一般到几十Kb/s 就到极限了。
3、接口使用信号线和GND 与其他设备形成共地模式的通信,这种共地模式传输容易产生干扰,并且抗干扰性能也比较弱。
4、传输距离有限,最多只能通信几十米。
5、通信的时候只能两点之间进行通信,不能够实现多机联网通信。
针对 RS232 接口的不足,就不断出现了一些新的接口标准,RS485 就是其中之一,他具备以下的特点:1、我们在讲A/D 的时候,讲过差分信号输入的概念,同时也介绍了差分输入的好处,最大的优势是可以抑制共模干扰。
尤其工业现场的环境比较复杂,干扰比较多,所以通信如果采用的是差分方式,就可以有效的抑制共模干扰。
51单片机_步进机_直流电机,RS485通信

本程序实现RS485多机通信步进机控制直流电机控制LED等控制开发环境keil4/***************************************************************************//******** main.c ***************//**************************************************************************/#include<reg52.h>#include<stdio.h>#include<stdlib.h>#include"CRC16.h"#define uint unsigned int#define uchar unsigned charsbit SENDMODE=P3^2; //收发控制sbit PWM=P2^4; //控制直流电机PWMsbit LED1=P2^5;sbit LED0=P2^6;uchar Rxbuf[12]; //数据接收缓冲区uchar PWMvalue=0;//控制直流电机转动速度uchar stmotorvalue=1;//控制步进机转动角度static unsigned int stmotor=0;static uchar Rxfinish=0; //接收完毕标志位void delay(uint n); //1ms延时函数static const char stepperForeward[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//eigth pat Forewardstatic const char stepperRollback[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};//eigth pat Rollbackstatic const char stepperStop[8] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//eigth pat Pausechar stCtlFlag=2;//步进机direction contorlvoid inti() //波特率设计为9600{TMOD=0x21;TL1=250;TH1=250;TR1=1;PCON=0x80;SCON=0x50;EA=1;ES=1;TI=0;RI=0;TR0=1;ET0=1;TH0=(65535-100)/256;TL0=(65535-100)%256;SENDMODE=0;//485设计为接收模式LED0=1;LED1=1;}/*******************************************//*******************************************//****************************/void transmit(uint length,uchar *ptr) //发送函数目的当小车转弯时通知430单片机记录当前的方位,开始计算走过的路程{uint x=0;TI=0;SENDMODE=1;//把P3^2口拉高开始数据通信回复终端for(x=0;x<length;x++) //逐步把数据放到发送缓冲区{SBUF=ptr[x];while(!TI); //等待数据发送完成TI=0;}SENDMODE=0; //恢复接收模式sendOK=1;//发送完毕后把发送完毕标志位置1}void bzero(int length,uchar *ptr){int x;for(x=0;x<length;x++){*ptr++='\0';}}void UART0()interrupt 4{static unsigned char Rxnum=0;static unsigned char OK=0;if(RI==1){RI=0;LED0=1;if(OK==0){if(SBUF==0xff){Rxnum=0;OK=1;}}Rxbuf[Rxnum]=SBUF;Rxnum++;if(Rxnum==Rxbuf[1]||Rxbuf[Rxnum-1]==0xfe){if(Rxbuf[0]==0xff){Rxfinish=1;//一帧接收没错ES=0;//关中断}else{Rxfinish=0;//一帧接收出错}OK=0;Rxnum=0;}if(Rxnum>12){OK=0;Rxnum=0;}}}void time0()interrupt 1{static uchar count0=0;static int count1=0;static uchar stnum=0;TH0=(65535-100)/256;TL0=(65535-100)%256;count0++;if(count0<=PWMvalue){PWM=1;}else{PWM=0;if(count0>=10){count0=0;}}count1++;if(count1==10) //步进机控制{P2&=0xf0;count1=0;if(stCtlFlag==0){P2|=stepperForeward[stnum];}else if(stCtlFlag==1){P2|=stepperRollback[stnum];}else{P2|=stepperStop[stnum] ;}stnum++;if(stnum>=8){stnum=0;if(stmotor>=stmotorvalue*60){stCtlFlag=2;}else stmotor++;}}}void macontrol(int pwm,uchar ctldr,uchar stmotor)//电机控制函数{PWMvalue=pwm;stCtlFlag=ctldr;stmotorvalue=stmotor;}void main(){static uint CRC16value=0;static uchar temp=0;inti();while(1){if(Rxfinish!=0){Rxfinish=0;if((Rxbuf[1]-4)>0){CRC16value=crc16(&Rxbuf[1],Rxbuf[1]-4);//CRC16value=crc16(&Rxbuf[1],Rxbuf[1]-4);transmit(2,&CRC16value);if((CRC16value/256==Rxbuf[Rxbuf[1]-3])&&(CRC16value%256==Rxbuf[Rxbuf[1]-2])&&Rxb uf[2]==0x01&&Rxbuf[Rxbuf[1]-1]==0xfe&&Rxbuf[0]==0xff){LED0=(bit)(Rxbuf[3]&0x01);LED1=(bit)(Rxbuf[4]&0x01);stmotor=0;macontrol(Rxbuf[7],Rxbuf[5],Rxbuf[6]);temp=Rxbuf[7];}else PWMvalue=temp;}bzero(sizeof(Rxbuf),Rxbuf);ES=1; //开中断}else PWMvalue=temp;}}/*****************************************************************************/ /*******CRC16.h *****//***************************************************************************/ #ifndef __CRC16_H#define __CRC16_Hcode unsigned char const auchCRCHi[] = {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40/* CRC低位字节值表*/code unsigned char const auchCRCLo[] = {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;/***************************************************************************/ //计算CRC16程序/***************************************************************************/ unsigned short int crc16(unsigned char *puchMsg, unsigned short int usDataLen){unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化*/unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化*/unsigned long uIndex ; /* CRC循环中的索引*/while (usDataLen--) /* 传输消息缓冲区*/{uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;uchCRCLo = auchCRCLo[uIndex] ;if(uchCRCHi==0xff||uchCRCHi==0xfe||uchCRCHi==0xfd||uchCRCHi==0xfc) uchCRCHi=0xfb;if(uchCRCLo==0xff||uchCRCLo==0xfe||uchCRCLo==0xfd||uchCRCLo==0xfc) uchCRCLo=0xfb;return (uchCRCHi << 8 | uchCRCLo) ;}#endif。
单片机RS485通信接口、控制线、原理图及程序教学实例

单片机RS485通信接口、控制线、原理图及程序教学实例[前言]RS232 标准是诞生于RS485 之前的,但是RS232 有几处不足的地方:接口的信号电平值较高,达到十几V,使用不当容易损坏接口芯片,电平标准也与TTL 电平不兼容。
传输速率有局限,不可以过高,一般到一两百千比特每秒(Kb/s)就到极限了。
接口使用信号线和GND 与其它设备形成共地模式的通信,这种共地模式传输容易产生干扰,并且抗干扰性能也比较弱。
传输距离有限,最多只能通信几十米。
通信的时候只能两点之间进行通信,不能够实现多机联网通信。
针对RS232 接口的不足,就不断出现了一些新的接口标准,RS485 就是其中之一。
RS232 标准是诞生于RS485 之前的,但是RS232 有几处不足的地方:接口的信号电平值较高,达到十几V,使用不当容易损坏接口芯片,电平标准也与TTL 电平不兼容。
传输速率有局限,不可以过高,一般到一两百千比特每秒(Kb/s)就到极限了。
接口使用信号线和GND 与其它设备形成共地模式的通信,这种共地模式传输容易产生干扰,并且抗干扰性能也比较弱。
传输距离有限,最多只能通信几十米。
通信的时候只能两点之间进行通信,不能够实现多机联网通信。
针对RS232 接口的不足,就不断出现了一些新的接口标准,RS485 就是其中之一,它具备以下的特点:采用差分信号。
我们在讲A/D 的时候,讲过差分信号输入的概念,同时也介绍了差分输入的好处,最大的优势是可以抑制共模干扰。
尤其当工业现场环境比较复杂,干扰比较多时,采用差分方式可以有效的提高通信可靠性。
RS485 采用两根通信线,通常用A 和B 或者D+和D-来表示。
逻辑1以两线之间的电压差为+(0.2~6)V 表示,逻辑0以两线间的电压差为-(0.2~6)V 来表示,是一种典型的差分通信。
RS485 通信速率快,最大传输速度可以达到10Mb/s 以上。
RS485 内部的物理结构,采用的是平衡驱动器和差分接收器的组合,抗干扰能力也大大增。
我的51单片机之 MAX485的 C语言与汇编的编程

//与自制软件 ComTest 通信,设好通信口,按下软件中相应按钮,数码管显示相应值
//made by luqichao
//************************************************************************
#include <reg51.h>
;
{ 0 , 1, 2 , 3 , 4 , 5, 6, 7, 8, 9 }
MAIN:
MOV SCON,#50H; 串口工作于方式 1,充许接收
MOV PCON,#0H;
波特率不倍增
MOV TMOD,#20H; 定时器计数器 1 工作于方式 2;
MOV TH1,#0FDH;
MOV TL1,#0FDH; 波特率为 9600;
LEDCODE EQU P1 ComData EQU 40H; LED1 EQU P0.6; LED2 EQU P0.7; M485 EQU P0.5;
//作为收发数据的使能短,1 为发数据 0 为收数据
;字形码:0--f 及小数点
AscLed:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;
四、汇编程序: ;************************************************************************** ;与自制软件 ComTest 通信,设好通信口,按下软件中相应按钮,数码管显示相应值 ;made by luqichao ;************************************************************************** ORG 0000H AJMP MAIN ORG 001BH AJMP T1P ORG 0023H AJMP COMM ORG 0030H
485通讯协议怎么写

485通讯协议怎么写竭诚为您提供优质文档/双击可除485通讯协议怎么写篇一:485通讯协议设置通讯协议Rcm-t2控制仪采用标准modbus-Rtu通讯协议,协议采用主从方式,只有主站发出查询时,从站才能相应主站;从站只相应对其单独发出的指令,对于广播信息,从站只接收,而不向主站相应命令。
modbus通讯协议传输方式Rcm-t2控制仪,串口通讯参数:1位起始位,8位数据位,无校验,1位停止位,波特率:9600,采用Rtu通讯方式。
Rcm-t2控制仪地址列表篇二:Rs485通讯协议介绍第九章串行口Rs485通讯协议9.1通讯概述本公司系列变频器向用户提供工业控制中通用的Rs485通讯接口。
通讯协议采用modbus标准通讯协议,该变频器可以作为从机与具有相同通讯接口并采用相同通讯协议的上位机(如plc控制器、pc机)通讯,实现对变频器的集中监控,另外用户也可以使用一台变频器作为主机,通过Rs485接口连接数台本公司的变频器作为从机。
以实现变频器的多机联动。
通过该通讯口也可以接远控键盘。
实现用户对变频器的远程操作。
本变频器的modbus通讯协议支持两种传送方式:Rtu方式和ascii 方式,用户可以根据情况选择其中的一种方式通讯。
下文是该变频器通讯协议的详细说明。
9.2通讯协议说明9.2.1通讯组网方式(1)变频器作为从机组网方式:单主机多从机图9-1从机组网方式示意图单主机单从机(2)多机联动组网方式:-107-图9-2多机联动组网示意图9.2.2通信协议方式该变频器在Rs485网络中既可以作为主机使用,也可以作为从机使用,作为主机使用时,可以控制其它本公司变频器,实现多级联动,作为从机时,pc机或plc可以作为主机控制变频器工作。
具体通讯方式如下:(1)变频器为从机,主从式点对点通信。
主机使用广播地址发送命令时,从机不应答。
(2)变频器作为主机,使用广播地址发送命令到从机,从机不应答。
(3)用户可以通过用键盘或串行通信方式设置变频器的本机地址、波特率、数据格式。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
485通讯协议程序怎么写(51单片机的485通信程序案例)
RS-485总线接口是一种常用的串口,具有网络连接方便、抗干扰性能好、传输距离远等优点。
RS-485收发器采用平衡发送和差分接收,因此具有抑制共模干扰的能力,加上收发器具有高的灵敏度,能检测到低达200mv的电压,可靠通信的传输距离可达数千米。
使用RS-485总线组网,只需一对双绞线就可实现多系统联网构成分布式系统、设备简单、价格低廉、通信距离长。
51单片机的485通信程序
#ifndef __485_C__ #define __485_C__
#include 《reg51.h》
#include 《string.h》
#define unsigned char uchar
#define unsigned int uint
/* 通信命令*/
#define __ACTIVE_ 0x01 // 主机询问从机是否存在
#define __GETDATA_ 0x02 // 主机发送读设备请求
#define __OK_ 0x03 // 从机应答
#define __STATUS_ 0x04 // 从机发送设备状态信息
#define __MAXSIZE 0x08 // 缓冲区长度
#define __ERRLEN 12 // 任何通信帧长度超过12则表示出错
uchar dbuf[__MAXSIZE]; // 该缓冲区用于保存设备状态信息
uchar dev; // 该字节用于保存本机设备号
sbit M_DE = P1。