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

📄 link.c

📁 profibus-R485网关程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	dpram485.station_num = uc_station_num;		//站总数

	dpram_addr_temp = DPRAM_DATA_ADDR;				//初始化地址临时变量
	p_link_data_buf_temp = p_link_data_buf->p_prm_tol_ptr+6;		//第一个站的参数化首地址
	for(ii=1; ii<=uc_station_num; ii++)
	{
		slave_data_str[ii].station_addr = *p_link_data_buf_temp;		//第一个字节是站地址
		slave_data_str[ii].prm_len = *(p_link_data_buf_temp+1);			//第二个字节是参数化长度
		rout_num = 0;														//初始化通道数
		slave_data_str[ii].in_len = 0;					//初始化本站的输入输入长度
		slave_data_str[ii].out_len = 0;
        slave_data_str[ii].diag_len = 0;
		prm_ptr_count_temp = 0;
                	p_link_data_buf_temp+=2;						//初始化指针位置计数器
		station_type_cal_temp = *p_link_data_buf_temp;	//保存本站的站类型(第三字节)

//////////////////////////////////////////////////////////////////
//如有必要,此处可以加区域数据检查,限制区域不超过4个区(目前系统尚不支持大于四个区
//也可加参数化标志位,证明已经进行参数化,如果不经参数化直接调用其它三个区的更新函数则为非法
//以上的判断结果可通过LINK的诊断返回
//////////////////////////////////////////////////////////////////
		do
		{
			for(jj=0; jj<8; jj++)					//低字节掩码是确定存在的
			{
				if((*(p_link_data_buf_temp+1)) & (0x01<<jj))		//由掩码推算出通道数
				{
					rout_num++;
				}
			}
			if((station_type_cal_temp&STATION_ROUT_NUM_BIT)>0x20)					//通道数大于8,表示有高字节掩码
			{
				for(jj=0; jj<8; jj++)
				{
					if((*(p_link_data_buf_temp+2)) & (0x01<<jj))		//如果有高通道掩码,第5个字节为高通道掩码
					{
						rout_num++;
					}
				}
				p_link_data_buf_temp++;																		//多了一个字节,指针加1
				prm_ptr_count_temp++;																			//记住指针的位置
			}

			switch(station_type_cal_temp&STATION_WORD_LEN_BIT)		//算出本区的数据长度
			{
				case 0x00:
					station_data_len = (rout_num+7)/8;
					break;
				case 0x02:
					station_data_len = rout_num;
					break;
				case 0x04:
					station_data_len = rout_num*2;
					break;
				case 0x06:
					station_data_len = rout_num*4;
					break;
				default:
					station_data_len = rout_num*4;
					break;
			}
			switch(station_type_cal_temp&INOUT_BIT)				//求出区的数据输入输出类型
			{
				case IO_IN:
					slave_data_str[ii].in_len += station_data_len;
					break;
				case IO_OUT:
					slave_data_str[ii].out_len += station_data_len;
					break;
				default:
					break;
			}
			slave_data_str[ii].diag_len += (rout_num+7)/8;		//诊断位数被确定为跟通道数一样
			p_link_data_buf_temp+= 2;													//指针指向下一个区(默认每个区为四字节,有高字节掩码者上面已加1)
			prm_ptr_count_temp += 2;
                        rout_num =0 ;
                        station_type_cal_temp2 = station_type_cal_temp;												//记住指针位置
			station_type_cal_temp = *p_link_data_buf_temp;	 			//继续下一个区
		}while((station_type_cal_temp2&REGION_FLAG_BIT) == EXIST_NEXT_REGION);			//如果后面还有数据块,一直循环下去
//下面四句求出每个站的四个指针
	                             slave_data_str[ii].diag_len++;    //再加上系统诊断的长度
		slave_data_str[ii].prm_ptr = slave_data_str[ii-1].prm_ptr+slave_data_str[ii-1].prm_len+2;
		slave_data_str[ii].in_ptr = slave_data_str[ii-1].in_ptr+slave_data_str[ii-1].in_len;
		slave_data_str[ii].out_ptr = slave_data_str[ii-1].out_ptr+slave_data_str[ii-1].out_len;
		slave_data_str[ii].diag_ptr = slave_data_str[ii-1].diag_ptr+slave_data_str[ii-1].diag_len;

//下面一段是根据算出的地址和长度表来构造本站在双口RAM的传输列表
		dpram485.trans_list[ii].station_addr = slave_data_str[ii].station_addr;
		dpram_addr_temp+= slave_data_str[ii-1].prm_len+slave_data_str[ii-1].in_len+slave_data_str[ii-1].out_len+slave_data_str[ii-1].diag_len;
		dpram485.trans_list[ii].base_addr = dpram_addr_temp;
		dpram485.trans_list[ii].prm_len = slave_data_str[ii].prm_len;
		dpram485.trans_list[ii].in_len = slave_data_str[ii].in_len;
		dpram485.trans_list[ii].out_len = slave_data_str[ii].out_len;
		dpram485.trans_list[ii].diag_len = slave_data_str[ii].diag_len;
		p_link_data_buf_temp+= slave_data_str[ii].prm_len  - prm_ptr_count_temp;
	}
}


void system_state_deal(uchar *p_link_data_buf)
{
//    uchar uc_link485_life_flag;
	switch(uc_system_status_flag)
	{
 /*	case RESET_STATE:

 		write_command(RESET_COM); 		 //写RESET命令

		uc_system_status_flag = STOP_STATE;

 		break;*/

 	case RESET_STATE:
                write_command(RESET_COM); 		 //写RESET命令
		uc_system_status_flag = WAIT_PRM_STATE;
                uc_handshake_error_count = 0x0;

 		break;
	case WAIT_PRM_STATE:
              if((dpram485.mcu_com_sig==VALID) && (dpram485.pc_com_sig ==INVALID) && (dpram485.mcu_com==RESET_COM))
 		{

		update_prm_data(p_link_data_buf);
                dpram485.mcu_com_sig=INVALID;
               	uc_system_status_flag = PARAM_STATE;
                uc_handshake_error_count = 0x0;
                write_command(PRM_COM);
		}
		else
		{
			uc_handshake_error_count++;

             	}
 		if(uc_handshake_error_count >= 0xaa)
 		{
 			uc_system_status_flag = RESET_STATE;
 			delay(100);
 		}
 		 break;
	case PARAM_STATE:

 		if((dpram485.mcu_com_sig==VALID) && (dpram485.pc_com_sig ==INVALID) && (dpram485.mcu_com==PRM_COM))
 		{
		uc_system_status_flag = WORK_STATE;
                uc_handshake_error_count = 0x0;
		}
		else
		{
			uc_handshake_error_count++;
		}
 		if(uc_handshake_error_count >= 0xaa)
 		{
 			uc_system_status_flag = RESET_STATE;
 			delay(100);
 		}
	     break;

    default:
    		uc_system_status_flag = RESET_STATE;
                break;
        }

}

void clear_dpram(void)
{
	unsigned int  data ii;
	dpram485.station_num=1;
	uc_handshake_error_count = 0x0;
	for (ii=0;ii<124;ii++)
	{
		dpram485.mcu_s_sig_list[ii]=FREE;
		dpram485.pc_s_sig_list[ii]=FREE;
	}
	for (ii=0;ii<124;ii++)
	{
	dpram485.trans_list[ii].station_addr=0;
		dpram485.trans_list[ii].base_addr=0;
		dpram485.trans_list[ii].prm_len=0;
		dpram485.trans_list[ii].out_len=0;
		dpram485.trans_list[ii].in_len=0;
		dpram485.trans_list[ii].diag_len=0;
	}
	for (ii=0;ii<0xb90;ii++)
	{
		dpram485.datum[ii]=0;
	}
}

uchar link485_life_juge(void)
{
   	if(uc_link485_life_flag_old == dpram485.uc_link485_life_counter)
	{
		uc_life_error_counter++;
		if(uc_life_error_counter>30)	//LINK485心跳信号连续30次无变化,延时一段时间再判断
		{
			delay(1000);
			if(uc_link485_life_flag_old == dpram485.uc_link485_life_counter)	//如果还没变化,确认对方已死
			{
				return FALSE_485;
			}
			else
			{
				uc_life_error_counter = 0;		//认为还没死,错误计数器清0
                uc_link485_life_flag_old = dpram485.uc_link485_life_counter;	//保存新的存活计数器值
			}
		}
	}
	else
	{
		uc_life_error_counter = 0;				//错误计数器清0
		uc_link485_life_flag_old = dpram485.uc_link485_life_counter;	//保存新的存活计数器值
	}
	return TRUE_485;
}


void dpram_interface_prog_init()			//双口RAM接口程序的初始化函数
{
	clear_dpram();
	uc_link485_life_flag_old = dpram485.uc_link485_life_counter;
//	uc_link485_life_flag = FALSE_485;
	uc_life_error_counter =0;          //心跳信号错误计数器,达到一定数值就确认对方已经出错
	dpram485.uc_link_life_counter = 0;    //link存活标志
//        uc_command_succeful_flag = FALSE_485;
	//write_command(STOP_COM);
    uc_system_status_flag=RESET_STATE;
    uc_link485_life_flag= TRUE_485;
    uc_out_command_old = 0;
    dpram485.mcu_com_sig=INVALID;
}


void write_command(uchar uc_link_command)
{

	dpram485.pc_com = uc_link_command;	//命令
	dpram485.pc_com_sig=VALID;	//
	dpram485.mcu_com_sig=INVALID;

}

uchar juge_command()
{
	if(((dpram485.mcu_com_sig==VALID) && (dpram485.pc_com_sig ==INVALID)) && (dpram485.pc_com == dpram485.mcu_com))
	{
		dpram485.mcu_com_sig=INVALID;
		return TRUE_485;
	}
	return FALSE_485;

}


void delay(uint delay_count)
{
 while(delay_count!=0)
 {
        delay_count--;
 }
}

⌨️ 快捷键说明

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