📄 link.c
字号:
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®ION_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 + -