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

📄 rs232.c

📁 利用FIFO数据结构,在8051单片机上实现全双工通讯,实现MODBUS通讯协议
💻 C
📖 第 1 页 / 共 2 页
字号:
                    rc_buf[loop01] = getchar();
                    loop01 ++;
                }
                //检查是否站地址,记录数据开始标志
                if(begin_flag1 == 0)
                {
                    rc_buf[loop01] = getchar();
                    if( rc_buf[loop01] == address() )//站地址判断
                    {
                        rc_buf[0] = rc_buf[loop01];
                        loop01 = 1;
                        begin_flag1 = 1;//指示已找到数据头

                    }
                }//end of if(begin_flag1 == 0)
                
                if(loop01 == 2)
                {
                    function_code1 = rc_buf[1];
                }
            }//end of if(!rc_buf_empty())
            
            if(loop01 == 7 )
            {
            	if( ( function_code1 == 0x03 ) || (function_code1 == 0x16 ) || ( function_code1 == 0x17 )
            	    || (function_code1 == 0x7f ) )
				data_num1 = 8;       //读指令
				
            	else if(function_code1 == 0x10 )
            	{
					data_num1 = rc_buf[6] + 9;    //写指令
					if( data_num1 > 40 )          
					end_flag1 = 1;
				}
				
             }//end of if(loop01 == 7 )
             
            if( loop01 >= 7 && loop01 >= data_num1 )
            {
            	end_flag1 = 1;//数据接收完,结束
            }//end of if()
        }//end of while( ( loop01 < 50 ) && ( !rc_buf_empty() ) && ( !end_flag1 ) )
    }
    //数据校验
    if( end_flag1 )
    {
        crc_temp.add16 = CRC_16(rc_buf,data_num1 - 2);

        if( (crc_temp.add8[0] == rc_buf[loop01-1] ) && ( crc_temp.add8[1] == rc_buf[loop01-2] ) )
        {
            data_ok1 = 1;
            
        }
        else
        {
            data_ok1 = 0;
            //接收到一祯错误数据
            //命令处理完,初始化变量和寄存器
            loop01  = 0;
            begin_flag1 = 0;
            end_flag1   = 0;
            data_num1   = 0;
            function_code1   = 0;
            begin_address.add16 = 0;//要求读取的寄存器起始地址
            register_num.add16  = 0;//要求读取的寄存器个数
            //初始化变量和寄存器完成
        }
    }
    //命令识别和处理
    
    if( data_ok1 )
    {
    	
        if(function_code1 == 0x03)
        {
        	
        	pComData = &rwdata;//将指针指向电参量存储区
        	
        	pOffset = 0;
        	
        	begin_address.add8[0] = rc_buf[2];
        	begin_address.add8[1] = rc_buf[3];
        	
        	register_num.add8[0] = rc_buf[4];
        	register_num.add8[1] = rc_buf[5];
        	
        	if( !bWorkModel )
			{
				tran_buf_size = sizeof( rwdata );//95 + 12
				
				rwdata.working.com_head.local_add    = address();
				
				rwdata.working.com_head.funtion_code = function_code1;
				
				rwdata.working.com_head.reg_num      = tran_buf_size - 5;
				
				crc_temp.add16                       = CRC_16( pComData , tran_buf_size - 2 );
				
				rwdata.working.com_crc.data8[0]      = crc_temp.add8[1];//交换高低字节
				
				rwdata.working.com_crc.data8[1]      = crc_temp.add8[0];
				
			}
			else
			{
				tran_buf_size = sizeof( struct adjust_datar );//41
				
				pComData      = pComData + sizeof( struct adjust_dataw );//
				
				rwdata.adjusting.read_data.com_head.local_add    = address();
				
				rwdata.adjusting.read_data.com_head.funtion_code = function_code1;
				
				rwdata.adjusting.read_data.com_head.reg_num      = tran_buf_size - 5;
				
				crc_temp.add16                                   = CRC_16( pComData , tran_buf_size - 2 );
				
				rwdata.adjusting.read_data.com_crc.data8[0]      = crc_temp.add8[1];//交换高低字节
				
				rwdata.adjusting.read_data.com_crc.data8[1]      = crc_temp.add8[0];
				
			}
        	
        	send_data();//send data
        	
        }//end of if(function_code1 == 0x03)

        else if(function_code1 == 0x10)//收到读取的数据,将数据区更新
        {
			if( bWorkModel )
			{//只有在校准模式下写指令才起作用
				
				begin_address.add8[0] = rc_buf[2];
        		begin_address.add8[1] = rc_buf[3];
        		
        		register_num.add8[0] = rc_buf[4];
        		register_num.add8[1] = rc_buf[5];
        	
				pOffset = 0;
			
				for(i = 0; i < 3 ; i++)
				{
					crc_temp.add8[0] = rc_buf[7 + 0 + i*2 ];
					
					crc_temp.add8[1] = rc_buf[7 + 1 + i*2 ];
					
					if( crc_temp.add16 < 0x1000 )//4096
					{
						rwdata.adjusting.write_data.voltage[i].data16 = crc_temp.add16;
					}
				}//end of for(i)
				
				for(i = 0; i < 3 ; i++)
				{
					crc_temp.add8[0] = rc_buf[7 + 0 + i*2 + 6];
					
					crc_temp.add8[1] = rc_buf[7 + 1 + i*2 + 6];
					
					if( crc_temp.add16 < 0x1000 )//4096
					{
						rwdata.adjusting.write_data.current[i].data16 = crc_temp.add16;
					}
					
				}//end of for(i)
				
				for(i = 0; i < 3 ; i++)
				{
					crc_temp.add8[0] = rc_buf[7 + 0 + i*2 + 12];
					
					crc_temp.add8[1] = rc_buf[7 + 1 + i*2 + 12];
					
					if( crc_temp.add16 < 0x1000 )//4096
					{
						rwdata.adjusting.write_data.watt[i].data16 = crc_temp.add16;
					}
					
				}//end of for(i)
				
				for(i = 0; i < 3 ; i++)
				{
					crc_temp.add8[0] = rc_buf[7 + 0 + i*2 + 18];
					
					crc_temp.add8[1] = rc_buf[7 + 1 + i*2 + 18];
					
					if( crc_temp.add16 < 0x1000 )//4096
					{
						rwdata.adjusting.write_data.var[i].data16 = crc_temp.add16;
					}
					
				}//end of for(i)
				
				for(i = 0; i < 3 ; i++)
				{
					crc_temp.add8[0] = rc_buf[7 + 0 + i*2 + 24];
					
					crc_temp.add8[1] = rc_buf[7 + 1 + i*2 + 24];
					
					if( crc_temp.add16 < 0x1000 )//4096
					{
						rwdata.adjusting.write_data.va[i].data16 = crc_temp.add16;
					}
					
				}//end of for(i)
				
				////////////////////////////////////////////
				write_to7758();
				save_set_to_e2prom();//
				////////////////////////////////////////////
				
				rc_buf[0] = address();
				rc_buf[1] = function_code1;
				rc_buf[2] = begin_address.add8[0];
				rc_buf[3] = begin_address.add8[1];
				rc_buf[4] = register_num.add8[0];
				rc_buf[5] = register_num.add8[1];
				crc_temp.add16 = CRC_16(rc_buf,6);
				rc_buf[6] = crc_temp.add8[0];
				rc_buf[7] = crc_temp.add8[1];
				
				pComData = rc_buf;
				tran_buf_size = 8;
				
				send_data();
				
			}//end of if()

			//bit_write_order = 0;
        }//end of else if(function_code1 == 0x10)
        
        else if(function_code1 == 0x16)//保存电参量校准参数
        {
        	save_set_to_e2prom();
        	
        	//将收到的数据发回给上位机
        	pComData = rc_buf;  
			tran_buf_size = 8;
			pOffset = 0;
				
			send_data();
        }//end of else if()
        
        else if(function_code1 == 0x17)//清除历史电参量
        {
        	clean_energy();
        	
        	//将收到的数据发回给上位机
        	pOffset = 0;
        	pComData = rc_buf;  
			tran_buf_size = 8;
				
			send_data();
        }//end of else if()
        
        
        else if( function_code1 == 0x7f )//地址探测指令,收到后什么也不做,只将原数据帧返回给上位机
        {
        	pComData = rc_buf;  
			tran_buf_size = 8;
			pOffset = 0;
			send_data();
			
        }//end of else if( function_code1 == 0x7f )

        data_ok1 = 0;
        //命令处理完,初始化变量和寄存器
        loop01  = 0;
        begin_flag1 = 0;
        end_flag1   = 0;
        data_num1   = 0;
        function_code1   = 0;
        begin_address.add16 = 0;//要求读取的寄存器起始地址
        register_num.add16  = 0;//要求读取的寄存器个数
        //初始化变量和寄存器完成
    }//end of if(data_ok1)
}

/***************************************************************************************************
               CRC校验码计算程序
注:在此改为BCH校验码计算(各数据相异或,结果存入低字节,高字节补零)               
****************************************************************************************************/
/*
unsigned int BCH_16(unsigned char * p,unsigned char len)
{
	unsigned char  i = 0;
	
	unsigned char nResult_temp = 0;

	unsigned int  nResult = 0;
	
	nResult_temp = *(p + i);
	
	i = 1;
	
	while( i < len)
	{
		nResult_temp = nResult_temp ^ *(p + i);
		
		i++;
	}//end of while( i < len)
	
	nResult = (int)nResult_temp & 0x00ff;
	
	return nResult;
}
*/


unsigned int CRC_16(unsigned char * p,unsigned char len)
{
	
  unsigned char  i = 0;
  unsigned char j = 0;
	unsigned char c;

	unsigned int  nResult=0xFFFF;
	unsigned int  b=0xA001;
	//unsigned int  nCount=0;
	
	EA = 0;

	for( i = 0; i < len; i++ )
	{
		c=p[i];
		nResult=nResult^c;
		for( j=0; j<8; j++ )
		{
			if( nResult & 0x0001 )
			{
				nResult = nResult >> 1;
				nResult = nResult ^ b;
			}
			else
			{
				nResult = nResult >> 1;
			}
		}
	}
	
	EA = 1;
	
	return nResult;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -