⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbus.c

📁 单片机数据通讯典型应用(光盘内容)
💻 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 + -