📄 mbus.c
字号:
#include"mbus.h"
#include <reg52.h>
/**************************串口通信初始化**************************/
void InitSerialcom( void )
{
SCON = 0xD0 ; //UART为模式3,9位数据,第9位用于奇偶校验,允许接收
TMOD |= 0x20 ; //定时器1为模式2,8位自动重装
PCON &= 0x7F ; //SMOD=0;
TH1 = 0xFA ; //11.0592MHZ晶振下串口波特率为4800bit/s
IE |= 0x90 ; //使能串口中断
TR1 = 1 ; //启动定时器1
TI=1;
//初始化串口接收和发送缓冲区
rxHead = 0;
rxTail = 0;
txHead = 0;
txTail = 0;
}
/************************串口中断服务函数****************************/
void serial () interrupt 4 using 1
{
if ( RI )
{
RI = 0;
tempData = SBUF; //将数据放入C51寄存器时,计算数据中1的个数,
ACC = tempData; //如果个数为偶数,则P=0,否则P=1,用于奇偶校验
if( TB8 == P ) //对数据进行偶校验
{
rxBuf[rxHead] = tempData;
if ( rxHead == rxMax )
{
rxHead = 0;
}
else
{
rxHead++;
}
}
else
{
//如果校验错误,不接收数据
}
}
else if ( TI )
{
TI = 0;
if( txTail != txHead ) //如果缓冲区有数据则发送数据
{
ACC = txBuf[txTail]; //数据放入寄存器A,计算数据的偶校验,
TB8 = P; //将偶校验结果放入串口发送的第9位数据位
SBUF = txBuf[txTail];
}
if( txTail == txMax )
{
txTail = 0;
}
else
{
txTail ++;
}
}
}
/****************从串口缓冲区中读取数据,返回读取数据的个数**************/
unsigned char SerialcomRead( unsigned char *buf, unsigned char len )
{
unsigned char cnt = 0;
//当缓冲区中有数据时,开始读<=len个数的数据
while ( ( rxTail != rxHead ) && ( cnt < len ) )
{
*buf ++ = rxBuf[rxTail];
if( rxTail == rxMax )
{
rxTail = 0;
}
else
{
rxTail ++;
}
cnt ++;
}
return cnt;
}
/************向串口发送缓冲区中写入数据,并发起串口发送数据**************/
unsigned char SerialcomWrite( unsigned char *buf, unsigned char len )
{
unsigned char cnt;
//计算发送缓冲区中可用容量
if( txHead > txTail )
{
cnt = txMax - txHead + txTail + 1;
}
else
{
cnt = txTail - txHead;
}
//如果有足够的缓冲区空间,则将数据写入缓冲区
if( cnt >= len )
{
for ( cnt = len; cnt; cnt -- )
{
txBuf[txHead] = *buf++;
if( txHead == txMax )
{
txHead = 0;
}
else
{
txHead ++;
}
}
SBUF = txBuf[txTail];
return len;
}
else
return cnt;
}
/************发送MBUS数据帧,温度巡回检测系统只传递温度信息*****/
/*****************所以数据域为一个字节*************************/
unsigned char send_mbus_frame(unsigned char *addr,unsigned char type, unsigned char cntr,unsigned char temperature)
{
unsigned char i;
unsigned char res;
m_frame_buffer[0]=0xFE; //封装前导字节
m_frame_buffer[1]=0xFE;
m_frame_buffer[2]=0x68; //封装帧起始符
m_frame_buffer[3]=type; //封转仪表类型
for( i=0;i<7;i++) //封装七个字节的地址
{
m_frame_buffer[4+i]=*addr++;
}
m_frame_buffer[11]=cntr; //封转控制码
m_frame_buffer[12]=1; //数据长度,一个字节
m_frame_buffer[13]=temperature; //温度
m_frame_buffer[14]=0x16; //帧结束符
res =SerialcomWrite(m_frame_buffer,15); //发送MBUS帧
return res;
}
/************接收MBUS数据帧,温度巡回检测系统只传递温度信息*****/
/*****************所以数据域为一个字节*************************/
unsigned char receive_mbus_frame(unsigned char *addr,unsigned char *type, unsigned char *cntr,unsigned char *temperature)
{
unsigned char i=0;
unsigned char res=0;
SerialcomRead(m_frame_buffer,15);//从缓冲区读取MBUS帧
//读到一个完整的MBUS帧
if(m_frame_buffer[0]==0xFE&&m_frame_buffer[1]==0xFE&&m_frame_buffer[15]==0x16)
{
*type=m_frame_buffer[3]; //读取仪表类型
for( i=0;i<7;i++) //读取七个字节的地址
{
*addr=m_frame_buffer[4+i];
*addr++;
}
*cntr= m_frame_buffer[11];//读取控制码
*temperature= m_frame_buffer[13];//读取数据
res==15;
}
else
res=0;
return res;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -