RS485主从结构通信代码,用于组网内部通信
单片机源程序如下:
#ifndef _485MON_H // 防止485Mon.h被重复引用
#define _485MON_H
#include #include #include #define uchar unsigned char #define uint unsigned int #define ACTIVE 0x11 #define GETDATA 0x22 #define READY 0x33 #define SENDDATA 0x44 #define RECFRMMAXLEN 16 // 接收帧的最大长度,超过此值认为帧超长错误 #define STATUSMAXLEN 10 // 设备状态信息最大长度 uchar DevNo; // 设备号 xdata uchar StatusBuf[STATUSMAXLEN]; //为简化起见,假设了10位固定的采集数据 #define DATA0 0x10 #define DATA1 0x20 #define DATA2 0x30 #define DATA3 0x40 #define DATA4 0x50 #define DATA5 0x60 #define DATA6 0x70 #define DATA7 0x80 #define DATA8 0x90 #define DATA9 0xA0 sbit DE = P1^6; //驱动器使能,1有效 sbit RE = P1^7; //接收器使能,0有效 void init(); // 系统初始化 void Get_Stat(); // 简化的数据采集函数 bit Recv_Data(uchar *type); // 接收数据帧函数 void Send(uchar m); // 发送单字节数据 void Send_Data(uchar type,uchar len,uchar *buf); // 发送数据帧函数 void Clr_StatusBuf(); // 清除设备状态信息缓冲区函数 /****************************************/ /* Copyright (c) 2005, 通信工程学院 */ /* All rights reserved. */ /****************************************/ #include "485Mon.h" void main(void) { uchar type; /* 初始化 */ init(); while (1) { if (Recv_Data(&type)==0) // 接收帧错误或者地址不符合,丢弃 continue; switch (type) { case ACTIVE: // 主机询问从机是否在位 Send_Data(READY,0,StatusBuf); // 发送READY指令 break; case GETDATA: // 主机读设备请求 Clr_StatusBuf(); Get_Stat(); // 数据采集函数 Send_Data(SENDDATA,strlen(StatusBuf),StatusBuf); break; default: break; // 指令类型错误,丢弃当前帧 } } } /* 初始化 */ void init(void) { P1 = 0xff; DevNo = (P1&0x00111111); // 读取本机设备号 TMOD = 0x20; SCON = 0x50; TH1 = 0xfd; TL1 = 0xfd; TR1 = 1; PCON = 0x00; // SMOD=0 EA = 0; } /* 接收数据帧函数,实际上接收的是主机的指令 */ bit Recv_Data(uchar *type) { uchar tmp,rCount,i; uchar r_buf[RECFRMMAXLEN]; // 保存接收到的帧 uchar Flag_RecvOver; // 一帧接收结束标志 uchar Flag_StartRec; // 一帧开始接收标志 uchar CheckSum; // 校验和 uchar DataLen; // 数据字节长度变量 /* 禁止发送,允许接收 */ DE = 0; RE = 0; /* 接收一帧数据 */ rCount = 0; Flag_StartRec = 0; Flag_RecvOver = 0; while (!Flag_RecvOver) { RI = 0; while (!RI); tmp = SBUF; RI=0; /* 判断是否收到字符',其数值为0x24 */ if ((!Flag_StartRec) && (tmp == 0x24)) { Flag_StartRec = 1; } if (Flag_StartRec) { r_buf[rCount] = tmp; rCount ++; /* 判断是否收到字符'*',其数值为0x2A,根据接收的指令设置相应标志位 */ if (tmp == 0x2A) Flag_RecvOver = 1; } if (rCount == RECFRMMAXLEN) // 帧超长错误,返回0 return 0; } /* 计算校验和字节 */ CheckSum = 0; DataLen = r_buf[3]; for (i=0;i++;i<3+DataLen)
上一篇:单片机+XPT2046+MQ135室内空气净化系统
下一篇:12864万年历+温度计+闹钟+温度检测
推荐阅读最新更新时间:2024-11-17 03:19
设计资源 培训 开发板 精华推荐
- ESP32 M6Stack 开发板
- ST25-TAG-BAG-E包含基于ST25TA02K和ST25TA64K的八种不同产品,两种分别具有2Kbit和64Kbit EEPROM的NFC Forum Type 4标签IC
- MIC261201YJL EV,MIC261201 DC-DC 稳压器评估板在 4.5V 至 28V 的电源范围内运行
- 使用 MagnaChip Semiconductor 的 MAP9010QNRH 的参考设计
- LT8330IS6 4V 至 36V 输入、12V SEPIC 转换器的典型应用电路
- 【训练营】仿生电子狗儿
- LT6656BCS6-2.5、2.5V ADC 电压基准和桥式励磁电源的典型应用
- 使用 Richtek Technology Corporation 的 RT7232 的参考设计
- REF193 精密微功耗、低压差电压基准的典型应用
- 1.8V DC 至 DC 单路输出电源,适用于计算机/外围设备