标题:
51单片机MODBUS框架程序
[打印本页]
作者:
lipengxu
时间:
2018-12-16 00:07
标题:
51单片机MODBUS框架程序
新鲜出炉的MODBUS框架程序,有不足的地方望大家指出
0.png
(6.75 KB, 下载次数: 26)
下载附件
2018-12-16 01:21 上传
单片机源程序如下:
#include <all.h>
unsigned char xdata Modbus_Read_Buffer[256] = 0; //数据接收缓冲区
unsigned char xdata Modbus_Write_Buffer[256] = 0; //数据发送缓冲区
unsigned int Modbus_Read_Value = 0; //接收字节计数
unsigned int Modbus_Write_Value = 0; //发送字节计数
unsigned char Modbus_Read_Complete = 0; //帧接收完成标志位
unsigned int Modbus_CRC_Cecode(unsigned char *puchMsg, unsigned int usDataLen); //CRC校验
void Modbus_Init(); //帧检测定时器
void Modbus_data_Decode();
void Modbus_Init()//利用定时器2来计算数据帧 定时1MS
{
AUXR |= 0x04;//定时器2用作定时,不分频
IE2 |= 0x04;//允许定时器2中断
T2L = 0xCD; //设置定时初值
T2H = 0xD4; //设置定时初值
EA = 1; //开总中断
AUXR |= 0x10;
}
unsigned int Modbus_CRC_Cecode(unsigned char *puchMsg, unsigned int usDataLen)
{
unsigned int i,j,CRC_Reg,Check;
CRC_Reg = 0xFFFF;
for(i=0;i<usDataLen;i++)
{
CRC_Reg = CRC_Reg ^ (unsigned int)*(puchMsg + i);
for(j=0;j<8;j++)
{
Check = CRC_Reg & 0x0001;
CRC_Reg >>= 1;
if(Check==0x0001)
{
CRC_Reg ^= 0xA001;
}
}
}
return CRC_Reg;
}
void Modbus_data_Decode()
{
unsigned int CRC_Data,i;
unsigned char CRC_H, CRC_L;
if(Modbus_Read_Complete)
{
EA = 0;
Modbus_Read_Complete = 0;
CRC_Data = Modbus_CRC_Cecode(Modbus_Read_Buffer,Modbus_Read_Value-2);
CRC_H = CRC_Data >> 8;
CRC_L = CRC_Data & 0x00ff;
if((CRC_H == Modbus_Read_Buffer[Modbus_Read_Value-1]) && (CRC_L == Modbus_Read_Buffer[Modbus_Read_Value-2]))
{
//这里可以开始分析数据 程序进入这里就证明CRC检验已经通过了
Modbus_Write_Value = 0; //清除发送直接计数 ,调试用
for(i = 0; i < (Modbus_Read_Value-2); i++) //调试用主要把接收的数据发送出去
{
Modbus_Write_Buffer[i] = Modbus_Read_Buffer[i]; //调试用
Modbus_Write_Value++; //调试用
}
}
Modbus_Write_Buffer[Modbus_Write_Value] = CRC_L; //调试用
Modbus_Write_Value++; //调试用
Modbus_Write_Buffer[Modbus_Write_Value] = CRC_H; //调试用
Modbus_Read_Value = 0; //接收直接数清零
EA = 1;
for(i = 0; i <= Modbus_Write_Value; i++) //调试用
{
SBUF = Modbus_Write_Buffer[i]; //调试用
while(!TI); //调试用
}
Modbus_Write_Value = 0; //调试用
}
}
/* 串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 */
void UartRxMonitor(unsigned char ms)
{
static unsigned char cntbkp = 0;
static unsigned char idletmr = 0;
if (Modbus_Read_Value > 0) //接收计数器大于零时,监控总线空闲时间
{
if (cntbkp != Modbus_Read_Value) //接收计数器改变,即刚接收到数据时,清零空闲计时
{
cntbkp = Modbus_Read_Value;
idletmr = 0;
}
else //接收计数器未改变,即总线空闲时,累积空闲时间
{
if (idletmr < 2) //空闲计时小于30ms时,持续累加
{
idletmr += ms;
if (idletmr >= 2) //空闲时间达到2ms时,即判定为一帧接收完毕
{
Modbus_Read_Complete = 1; //设置帧接收完成标志
}
}
}
}
else
{
cntbkp = 0;
}
}
void Timer2_Routine() interrupt 12
{
UartRxMonitor(1);
}
复制代码
所有资料51hei提供下载:
MODBUS调试.zip
(44.77 KB, 下载次数: 83)
2018-12-16 00:07 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1