RS232转485PCB文件和程序工程文件

来源:互联网 发布:淘宝男装店知乎 编辑:程序博客网 时间:2024/06/06 16:39
RS232转485PCB文件和程序工程文件

上次看到一位热心网友在Blog留言,求RS232转485原理图一份正好手头有就整理一下发上来了 呵呵

这个是RS232部分电路:



这个是RS485的部分电路:


程序部分

#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)
{
   CheckSum = CheckSum + r_buf[i+1];
}

/* 判断帧是否错误 */
if (rCount<6)       // 帧过短错误,返回0,最短的指令帧为6个字节      
   return 0;
if (r_buf[1]!=DevNo)      // 地址不符合,错误,返回0
   return 0;
if (r_buf[rCount-2]!=CheckSum)   // 校验错误,返回0
    return 0;

*type = r_buf[2];      // 获取指令类型

return 1;        // 成功,返回1
}

/* 发送数据帧函数 */
void Send_Data(uchar type,uchar len,uchar *buf)
{
uchar i,tmp;
uchar CheckSum = 0;

/* 允许发送,禁止接收 */
DE = 1;
RE = 1;

/* 发送帧起始字节 */
tmp = 0x24;
Send(tmp);

Send(DevNo);       // 发送地址字节,也即设备号
CheckSum = CheckSum + DevNo;

Send(type);        // 发送类型字节
CheckSum = CheckSum + type;

Send(len);        // 发送数据长度字节
CheckSum = CheckSum + len;

/* 发送数据 */
for (i=0;i<len;i++)   
{
   Send(*buf);
   CheckSum = CheckSum + *buf;
   buf++;
}

Send(CheckSum);       // 发送校验和字节

/* 发送帧结束字节 */
tmp = 0x2A;
Send(tmp);
}

/* 采集数据函数经过简化处理,取固定的10个字节数据 */
void Get_Stat(void)
{
StatusBuf[0]=DATA0;
StatusBuf[1]=DATA1;
StatusBuf[2]=DATA2;
StatusBuf[3]=DATA3;
StatusBuf[4]=DATA4;
StatusBuf[5]=DATA5;
StatusBuf[6]=DATA6;
StatusBuf[7]=DATA7;
StatusBuf[8]=DATA8;
StatusBuf[9]=DATA9;
}

/* 发送单字节数据 */
void Send(uchar m)
{
TI = 0;
SBUF = m;
    while(!TI);
TI = 0;
}

/* 清除设备状态信息缓冲区函数*/
void Clr_StatusBuf(void)
{
uchar i;
for (i=0;i<STATUSMAXLEN;i++)
   StatusBuf[i] = 0;
}   


#ifndef _485MON_H      // 防止485Mon.h被重复引用

#define _485MON_H

#include <reg52.h>       // 引用标准库的头文件
#include <stdio.h>
#include <string.h>

#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();    // 清除设备状态信息缓冲区函数  

#endif


原创粉丝点击