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

📄 link.c

📁 profibus TO RS485 profibus TO RS485
💻 C
📖 第 1 页 / 共 2 页
字号:

#include	<reg52.h>
#include	"link.h"
#include	"profibus.h"

struct DPRAM485 xdata dpram485 _at_ 0x8000;		//定义双口RAM中的结构体
struct	SLA_DATA_CONSTRUCT	slave_data_str[125];	//模块的数据结构体,最多可以支持124个站(有一个是主站)
uchar 	uc_station_num;  //站总数
uchar	uc_out_command_old;	//用于保存上一次的命令

uchar	data 	uc_link485_life_flag_old;		//用于保存sys_master上一次的存活标志值
uchar	data	uc_link485_life_flag;			//与上一次的值比较,以确定LINK485是否还在正常工作

//uchar	data 	uc_link_life_flag_old;			//用于保存LINK_Profibus上一次的存活标志值
//uchar	data	uc_link_life_flag;			//提供给sys_master用于判断自己是否正常工作

uchar	data	uc_system_status_flag;			//系统状态标志,标志系统目前处于何种状态
uchar	data	uc_handshake_error_count;		//握手错误计数器,用于判断握手是否超时
uchar   data    uc_life_error_counter;			//心跳信号错误计数器,达到一定数值就确认对方已经出错
uchar 	data	uc_prm_com_old;				//用于保存老的参数化命令
uchar   data    uc_sys_command_old;			//用于保存老的系统命令.

uchar   data    uc_command_succeful_flag;		//命令采用同步方式处理,此标志用于判断是否成功
uchar  	*p_out_command;					//指向输出型命令
uchar	*p_in_command;					//指向输入型命令
//struct LINK_DATA_BUF xdata *p_link_data_buf ;


void update_data(struct LINK_DATA_BUF *p_link_data_buf)
{
	uchar *p_dpram;		//用于向双口RAM中某一字节写入一个值

	dpram485.uc_link_life_counter ++;	//声明自己还在正常运行
    p_dpram= (uchar xdata *)0x8507;
    *p_dpram= uc_link485_life_flag;		//由于LINK的板上没有LED,把对方的存活标志通过双口RAM传递过去
    *(p_dpram+1) = uc_system_status_flag;	//然后是系统状态标志
    switch(p_link_data_buf->interface_flag&0x03)	//根据接口命令决定进行什么操作
  	{
    	case PARAM_COM:			//参数化命令,要求先发STOP命令,再发参数化命令,再发OPERATE命令
    //     p_out_command = p_link_data_buf->p_out_tol_ptr;	//
    //   	p_in_command = p_link_data_buf->p_in_tol_ptr;
    	// p_link_data_buf->p_in_tol_ptr;	//重新赋输入输出命令的地址
		*p_link_data_buf->p_diag_tol_ptr = 0X1;   //置诊断信息
        dpram485.datum[7]=0x1;
		//uc_system_status_flag=RESET_STATE;
		system_state_deal(p_link_data_buf);
		if (uc_system_status_flag==WORK_STATE)
		{
		p_link_data_buf->interface_flag=EXA_COM;
		}
		else
		 {
		 	p_link_data_buf->interface_flag=PARAM_COM;
		 	}
    	break;

    	case EXA_COM:			//数据交换命令,按顺序更新数据

      		uc_link485_life_flag=link485_life_juge();	//判断link的存活标志
    		if (uc_link485_life_flag== TRUE_485)
    		{
    		 *p_link_data_buf->p_diag_tol_ptr = 0X0;
             dpram485.datum[7]=0x0;
             update_in_data();
      		update_out_data();
      		update_sys_command();
      		update_diag_data();
      		}
      	    else
      	    {
    		uc_system_status_flag = RESET_STATE;	//否则命令错误,重启
      	    	p_link_data_buf->interface_flag=PARAM_COM;
      	    	*p_link_data_buf->p_diag_tol_ptr = 0X1;
                dpram485.datum[7]=0x1;
      	    	}
      		break;

    	default:
      	    	p_link_data_buf->interface_flag=PARAM_COM;
      	    	*p_link_data_buf->p_diag_tol_ptr = 0X1;
                dpram485.datum[7]=0x1;
    		uc_system_status_flag = RESET_STATE;	//否则命令错误,重启
     	 	break;
  	}
  	 /*if (uc_system_status_flag == WORK_STATE)		//更新LINK的诊断标志
        {
                *p_link_data_buf->p_diag_tol_ptr = 0X0;
                dpram485.datum[7]=0x0;
        }
     else
        {
                *p_link_data_buf->p_diag_tol_ptr = 0X1;
                dpram485.datum[7]=0x1;
        }*/
     return;

}

void update_sys_command()	//命令处理
{

//	p_out_command = p_link_data_buf->p_out_tol_ptr;	//
  //     	p_in_command = p_link_data_buf->p_in_tol_ptr;
  	if(p_out_command != 0)		//如果有新的命令
	{
		if (uc_out_command_old != *p_out_command)
			{
      		uc_out_command_old = *p_out_command;
                if(uc_out_command_old==RESET_COM||uc_out_command_old==PRM_COM)
                {
                *p_in_command=0;
                }
                else
                {
                write_command(*p_out_command);
                }
            *p_in_command=uc_out_command_old;
            //*p_out_command = 0;		//写完后把命令清0,以方便判断是否有新命令
            dpram485.mcu_com_sig=INVALID;
	       	}
   }
  else
   {
   	uc_out_command_old = *p_out_command;
   	*p_in_command=uc_out_command_old;    //返回给主站卡
    *p_out_command = 0;		//写完后把命令清0,以方便判断是否有新命令

    }

}


void update_prm_data(struct LINK_DATA_BUF *p_link_data_buf)						//更新参数化区
{
	uint data ii,jj;

	cal_dpram_addr(p_link_data_buf);				//重新计算双口RAM的传输列表

	for(ii=1; ii<=uc_station_num; ii++)
	{
		dpram485.pc_s_sig_list[ii] = BUSY;			//参数化数据不管从站有没有故障都照写
		for(jj=0; jj<slave_data_str[ii].prm_len; jj++)		//按照传输列表重新构造双口RAM的数据结构
		{
			*((uchar xdata*)(dpram485.trans_list[ii].base_addr+DPRAM_BASE_ADDR+jj)) = *(slave_data_str[ii].prm_ptr+jj);
		}
		dpram485.pc_s_sig_list[ii] = FREE;
	}
}


void update_in_data(void)							//更新输入数据区
{
	uchar data ii,jj;
	for(ii=1; ii<=uc_station_num; ii++)
	{
		dpram485.pc_s_sig_list[ii] = BUSY;
		if(dpram485.mcu_s_sig_list[ii] == FREE)				//发现对方忙则丢弃一帧
		{
			for(jj=0; jj<slave_data_str[ii].in_len; jj++)
			{
				*(slave_data_str[ii].in_ptr+jj) = *((uchar xdata*)(DPRAM_BASE_ADDR+dpram485.trans_list[ii].base_addr+dpram485.trans_list[ii].prm_len+jj));
			}
		}
		dpram485.pc_s_sig_list[ii] = FREE;
	}
}



void update_out_data(void)					//更新输出数据区
{
	uchar data ii,jj;
	for(ii=1; ii<=uc_station_num; ii++)
	{
		dpram485.pc_s_sig_list[ii] = BUSY;
		if(dpram485.mcu_s_sig_list[ii] == FREE)				//如果双口RAM忙则丢弃一帧
		{
			for(jj=0; jj<slave_data_str[ii].out_len; jj++)
			{
				*(uchar xdata*)(DPRAM_BASE_ADDR+dpram485.trans_list[ii].base_addr+dpram485.trans_list[ii].prm_len+dpram485.trans_list[ii].in_len+jj) = *(slave_data_str[ii].out_ptr+jj);
			}
		}
		dpram485.pc_s_sig_list[ii] = FREE;
	}
}


void update_diag_data(void)
{
	uchar data ii,jj;
	for(ii=1; ii<=uc_station_num; ii++)
	{
		dpram485.pc_s_sig_list[ii] = BUSY;
		if(dpram485.mcu_s_sig_list[ii] == FREE)				//如果双口RAM忙则丢弃一帧
		{
			for(jj=0; jj<slave_data_str[ii].diag_len; jj++)
			{
				*(slave_data_str[ii].diag_ptr+jj) = *(uchar xdata*)(DPRAM_BASE_ADDR+dpram485.trans_list[ii].base_addr+dpram485.trans_list[ii].prm_len+dpram485.trans_list[ii].in_len+dpram485.trans_list[ii].out_len+jj);
			}
		}
		dpram485.pc_s_sig_list[ii] = FREE;
	}

	*(slave_data_str[0].diag_ptr+0) = *(uchar*)(DPRAM_DATA_ADDR+6);		//取LINK485本身的三个诊断信息
	*(slave_data_str[0].diag_ptr+1) = *(uchar*)(DPRAM_DATA_ADDR+7);
	*(slave_data_str[0].diag_ptr+2) = *(uchar*)(DPRAM_DATA_ADDR+8);
}


void cal_dpram_addr(struct LINK_DATA_BUF *p_link_data_buf)
{
	uchar data 	ii,jj;
	uchar	station_type_cal_temp;					//暂时存放每个从站的站类型(方便计算)
	uchar	*p_link_data_buf_temp;					//暂时存放每个从站的参数化区的首地址
	uchar	station_mark_flag;							//暂时存放每个站的掩码字节
	uchar	station_diag_len;								//暂时存放诊断长度
	uchar	station_data_len;								//暂时存放通道数据的长度
	uchar	prm_ptr_count_temp;							//用于保存每个站参数化区指针的位置信息
	uint	dpram_addr_temp;								//用于暂时保存双口RAM地址
	uchar	rout_num;												//通道数
        uchar   station_type_cal_temp2;
    uchar   *p_master_data;

 //         p_link_data_buf->p_prm_tol_ptr = (uchar xdata*)0x9f1;
 	p_out_command=p_link_data_buf->p_out_tol_ptr;
 	p_in_command=p_link_data_buf->p_in_tol_ptr;
 	slave_data_str[0].prm_len = 6;													//0号站即为主站,的参数化区共6字节
	slave_data_str[0].in_len = 0;
	slave_data_str[0].out_len = 0;
	slave_data_str[0].diag_len = 3;	//三个保留的诊断信息位
	slave_data_str[0].prm_ptr = p_link_data_buf->p_prm_tol_ptr;
	slave_data_str[0].in_ptr = p_link_data_buf->p_in_tol_ptr+1;
	slave_data_str[0].out_ptr = p_link_data_buf->p_out_tol_ptr+1;
	slave_data_str[0].diag_ptr = p_link_data_buf->p_diag_tol_ptr+1;

////////////////////////////////////////////////////////////////
//下面是主站的传输列表
////////////////////////////////////////////////////////////////
    uc_station_num = *(p_link_data_buf->p_prm_tol_ptr);					//站的总数,全局通用
                              if (uc_station_num >125)
    {
          uc_station_num =125;
    }
	dpram485.trans_list[0].base_addr = DPRAM_DATA_ADDR;
	dpram485.trans_list[0].prm_len = slave_data_str[0].prm_len;
	dpram485.trans_list[0].in_len = slave_data_str[0].in_len;
	dpram485.trans_list[0].out_len = slave_data_str[0].out_len;
	dpram485.trans_list[0].diag_len = slave_data_str[0].diag_len;
    dpram485.trans_list[0].station_addr = 0;		//主站的站地址

////////////////////////////////////////////////////////////////
//下面是主站的参数化信息
////////////////////////////////////////////////////////////////
    p_master_data = (uchar xdata*)(DPRAM_DATA_ADDR+DPRAM_BASE_ADDR);
    *p_master_data  = 0;
	*(p_master_data+1)  = *(p_link_data_buf->p_prm_tol_ptr+1);						//主站的类型
	*(p_master_data+2) = *(p_link_data_buf->p_prm_tol_ptr+2);
    *(p_master_data+3) = *(p_link_data_buf->p_prm_tol_ptr+3);
    *(p_master_data+4) = *(p_link_data_buf->p_prm_tol_ptr+4);
    *(p_master_data+5) = *(p_link_data_buf->p_prm_tol_ptr+5);
//        *(p_master_data+5) = *(p_link_data_buf->p_prm_tol_ptr+6);				//系统波特率
//	*((uint xdata*)(DPRAM_DATA_ADDR+2)) = *(p_link_data_buf->p_prm_tol_ptr+3);				//最小帧间延时
//	*((uint xdata*)(DPRAM_DATA_ADDR+4)) = *(p_link_data_buf->p_prm_tol_ptr+5);				//最小字节间延时

⌨️ 快捷键说明

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