rs485dri.c
来自「这是一个MODBUS协议的串口接收和发送程序」· C语言 代码 · 共 202 行
C
202 行
#include "reg52.h"
#include "rs485dri.h"
bit TiState=0; //发送寄存器空标志
uchar Counter=0,FristChar=0;
uchar EndFlagLEN;
uchar xdata *InComBuf;
uchar InP,OutP;
//----------------------------------------------//
// 串行数据发送程序 //
//----------------------------------------------//
void ComSendCh(unsigned char ch)
{
while(TiState); //等待发送标志空
SBUF=ch; //写数据到发送寄存器
TiState=1;
while(TiState);
}
//----------------------------------------------//
// 串行中断服务程序 //
//----------------------------------------------//
void serialget(void) interrupt 4 using 2
{
unsigned char GetChar;
EA=0;
if(RI)
{ //接收中断
RI=0; //清除中断标志
GetChar=SBUF;
if(CommandOK<COMMAND_NUM)
{
if(Com1mscounter==0) //定时清串口缓冲区
{FristChar=0;} //清串口缓冲区
switch(FristChar)
{
case 0: //得到数据起始命令
if(GetChar==0x55) //数据起始标志0x55 0xaa
{FristChar=1;}
//Com1mscounter=0x50;
Com1mscounter=0x700; //设定最大指令接受时间
break;
case 1: //数据起始标志
if(GetChar==0xaa)
{
FristChar=3;
InComBuf=(uchar xdata *)WITHOUT_COMINBUF_AREA+InP*COMMAND_LEN;
}
else
{FristChar=0;}
break;
case 3: //得到地址
Counter=0;
InComBuf[Counter]=GetChar;
Counter++;
if(GetChar==ShowInfo.Address) //地址=本模块地址
{
FristChar=4; //转入处理本模块数据
}
else if(GetChar==0) //地址=0,无条件执行且不用返回参数
{
FristChar=4; //转入处理本模块数据
}
else if(GetChar==0xfe) //地址=0xfe是后门程序。
{
FristChar=4; //转入处理本模块数据
}
else
{
FristChar=101; //转入处理非本模块数据
}
break;
//是本模块数据
case 4: //得到功能号及数据长度值
InComBuf[Counter]=GetChar;
Counter++;
if(GetChar==3) //功能3
{
EndFlagLEN=8; //功能3的数据长度为8
FristChar=10;
}
else if(GetChar==6) //功能6
{
EndFlagLEN=8; //功能6的数据总长度为8
FristChar=10;
}
else if(GetChar==16) //功能16
{
FristChar=5; //功能16的数据总长度
}
else //其他功能,等待时间到结束
{
FristChar=0; //不认识的命令,响应结束
}
break;
case 5: //得到16号功能写入寄存器的位置
InComBuf[Counter]=GetChar;
Counter++;
if(Counter>=7)
{
EndFlagLEN=GetChar+9;
FristChar=10;
}
break;
case 10: //正常接受数据并进行结束判定
InComBuf[Counter]=GetChar;
Counter++;
if(Counter>=EndFlagLEN) //数据接收完毕,转入接收校验和2位
{
CommandOK++; //数据接收成功
FristChar=0;
InP++;
if(InP>=COMMAND_NUM)
{InP=0;}
}
break;
//是过路数据,监视
case 101: //得到功能号及数据长度值
Counter++;
if(GetChar==3) //功能3
{
EndFlagLEN=8; //功能3的数据总长度为8
FristChar=110;
}
else if(GetChar==6) //功能6
{
EndFlagLEN=8; //功能6的数据总长度为8
FristChar=110;
}
else if(GetChar==16) //功能16
{
FristChar=102; //转去得到6号功能数据长度
}
else //其他功能,等待时间到结束
{
FristChar=0; //不认识的命令,等待一帧指令+响应结束
}
break;
case 102: //得到16号功能的数据长度值
Counter++;
if(Counter>=7)
{
EndFlagLEN=GetChar+9; //总数据量=起始地址,功能号,寄存器起始地址,寄存器数量,
// 要写入的字节数量,要设置的字符...n,CRC校验)9+个字节
FristChar=110;
}
break;
case 110: //正常接受数据并进行结束判定
Counter++;
if(Counter>=EndFlagLEN) //数据结尾判断
{
FristChar=0;
}
break;
}
}
}
if(TI)
{ //发送寄存器空中断
//TiState=0; //设发送寄存器空标志
TI=0;
TiState=0;
}
EA=1;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?