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

📄 hart_slave.c

📁 本人上载的几个.c文件为自己所写的代码,是关于自动化设备广泛使用的HART协议的主机与从机之间的通信过程(通过串口) hart_slave.c-----HART从机主程序(采用MSP430F149单
💻 C
📖 第 1 页 / 共 2 页
字号:
                    resp_data_14[3] = pv_sensor_unit_code;  //填充主变量传感器单位代码
                    for(i=0;i<4;i++)
                    {
                      resp_data_14[i+4] = pv_sensor_upper_754[i] = *p_pv_sensor_upper++;
                      resp_data_14[i+8] = pv_sensor_lower_754[i] = *p_pv_sensor_lower++;
                      resp_data_14[i+12] = pv_min_span_754[i] = *p_pv_min_span++;
                    }           
                    hart_resp(resp_data_14, resp_num_14,long_addr,cmd_num);
                    break;
                    
          case  15: /*填充相关数据*/
                    resp_data_15[0] = pv_alarm_code;
                    resp_data_15[1] = pv_xfer_code;
                    resp_data_15[2] = pv_range_unit_code;                   
                    for(i=0;i<4;i++)
                    {
                      resp_data_15[i+3] = pv_upper_754[i] = *p_pv_upper++;                   
                      resp_data_15[i+7] = pv_lower_754[i] = *p_pv_lower++;                
                      resp_data_15[i+11] = pv_damping_754[i] = *p_pv_damping++;
                    }
                    resp_data_15[15] = write_protect_code;
                    resp_data_15[16] = label_distributor_code;           
                    hart_resp(resp_data_15, resp_num_15,long_addr,cmd_num);
                    break;
                    
          case  16: hart_resp(final_ass_num, resp_num_16,long_addr,cmd_num);
                    break;
                    
          case  17: for(i=0;i<byte_count;i++)
                      message[i]=cmd_data[i]; //将主机发来的设备信息写入设备
                    hart_resp(message,24,long_addr,cmd_num);
                    break; 
                    
          case  18: /*将主机发来的标签,描述符和日期写入设备*/
                    for(i=0;i<6;i++)
                      tag[i]=cmd_data[i];
                    for(i=6;i<18;i++)
                      descriptor[i-6]=cmd_data[i];
                    for(i=18;i<21;i++)
                      date[i-18]=cmd_data[i];
                    hart_resp(cmd_data,21,long_addr,cmd_num);
                    break;     
                    
          case  19: for(i=0;i<byte_count;i++)
                      final_ass_num[i]=cmd_data[i]; //将最终装配号写入设备
                    hart_resp(final_ass_num,3,long_addr,cmd_num);
                    break;
                    
          case  33: if(strncmp((const char*)cmd_data,(const char*)xmtr_var_code,4)!=0)
                      not_resp++;
                    else
                    { /*将几个数据和数组按命令33响应的数据格式封装*/
                      for(i=0;i<4;i++)
                      {
                        resp_data_33[6*i] = xmtr_var_code[i];
                        resp_data_33[6*i+1] = unit_code_slot[i];
                        for(t=0;t<4;t++)                       
                          resp_data_33[6*i+2+t] = *p_xvd[i]++;                                            
                      }
                      p_xvd[0] = xmtr_var_data_0;
                      p_xvd[1] = xmtr_var_data_1;
                      p_xvd[2] = xmtr_var_data_2;
                      p_xvd[3] = xmtr_var_data_3;        //指针数组复位                      
                      hart_resp(resp_data_33,24,long_addr,cmd_num);
                    }
                    break;
                    
          case  34: hart_resp(pv_damping_754,4,long_addr,cmd_num);
                    for(i=0;i<4;i++)
                      *p_pv_damping++ = pv_damping_754[i] = cmd_data[i];  //将主变量阻尼值写入设备
                    break;   
                    
          case  35: /*将主变量单位代码,主变量上限值和下限值写入设备*/
                    pv_range_unit_code = cmd_data[0];          
                    for(i=0;i<4;i++)
                    {
                      *p_pv_upper++ = pv_upper_754[i] = cmd_data[i+1];
                      *p_pv_lower++ = pv_lower_754[i] = cmd_data[i+5];
                    }
                    hart_resp(cmd_data,9,long_addr,cmd_num);
                    break;
                    
          case  36: pv_upper_value = pv_value;     //将主变量当前值设为主变量上限值
                    for(i=0;i<4;i++)
                      pv_upper_754[i] = *p_pv_upper++; //更新主变量上限值的IEEE754形式
                    hart_resp(no_resp_data,0,long_addr,cmd_num);  
                    break;  
                    
          case  37: /*量程下限的改变将成比例的改变量程上限的值,以使跨度pv_range_span保持不变。
                    当这个改变把量程上限推到了传感器上限时,主变量量程上限饱和且响应代码为14。
                    主变量量程下限把量程上限推到超过传感器上限,将导致得到的跨度要小于主变量
                    最小精度pv_min_span,此时返回响应代码9—应用过程太高*/
                    pv_range_span = pv_upper_value - pv_lower_value;
                    pv_lower_value = pv_value;                   
                    f1 = pv_lower_value + pv_range_span;  //f1为主变量上限的可能值
                    if(f1>pv_sensor_upper)      //超过传感器上限值时
                    {
                      pv_upper_value = pv_sensor_upper;
                      if((pv_sensor_upper-pv_lower_value)<pv_min_span)  //小于主变量最小跨度时
                        status1 = 9;
                      else
                        status1 = 14; 
                    }
                    else
                      pv_upper_value = f1;
                    for(i=0;i<4;i++)
                    {
                      pv_lower_754[i] = *p_pv_lower++;
                      pv_upper_754[i] = *p_pv_upper++;  //更新pv_lower_754和pv_upper_754数组中的内容
                    }
                    hart_resp(no_resp_data,0,long_addr,cmd_num);
                    break;
                    
          case  39: e2prom_code = 2;  //此变量原来初始值为0,烧写操作对其赋值为0,二者医混淆,故改其初始值
                    switch(cmd_data[0])
                    {
                      case 0: e2prom_code = 0;                             
                              break;
                              //待39号命令的响应发送出去后,进行烧写操作
                      case 1: e2prom_code = 1;
                              /*这一行执行恢复操作,将数据从flash传输到RAM,代码由后来编程者添加*/
                              break;
                     default: not_resp++;
                              break;
                    }
                    p_e2prom_code = &e2prom_code;
                    hart_resp(p_e2prom_code,1,long_addr,cmd_num);
                    break;
                    
          case  40: for(i=0;i<4;i++)
                      *p_pv_current++ = pv_current_754[i] = cmd_data[i];
                    if(pv_current !=0)
                    {
                    /*在这里添加将设备主变量电流改为接收到数据的代码*/  
                    }
                    else
                    {
                      /*这里添加代码使设备退出固定主变量电流模式*/  //主机发送0时,设备退出固定主变量电流模式
                    }
                    hart_resp(pv_current_754,4,long_addr,cmd_num); //上面代码添加后,本行函数第一个参数改为实际写入数模转换器的主变量电流数值的IEEE754形式
                    break;
                    
          case  41: /*在这里添加代码,使变送器自检*/
                    break;
                    
          case  42: /*在这里添加代码,使设备复位*/
                    break;
                    
          case  44: pv_range_unit_code = pv_unit_code = cmd_data[0];
                    p = &pv_unit_code;
                    hart_resp(p,1,long_addr,cmd_num);
                    break;
                    
          case 107: for(i=0;i<4;i++)
                      xmtr_var_code[i] = cmd_data[i];   //将分配到Slot0-3的变送器变量代码写入设备
                    hart_resp(xmtr_var_code,4,long_addr,cmd_num);
                    
          default: break;
        }
        if(not_resp==0)
          com_send(send,send_bytes);
        if(e2prom_code==0)  //待39号命令的响应发送出去后,进行烧写操作
        {
          /*这一行执行烧写操作,将数据从RAM传输到flash,代码由后来编程者添加*/
        }
      }        
      received = 0;
      }
  } 
}


/*关于用串口接收主机发来的数据帧,串口只能一个字节一个字节地接收数据,利用定时器定时30ms,当相邻的数据字节接收间隔时间不超过30ms时,便认定
二者是同一数据帧当中的数据,当超过30ms仍然没接收到下一个字节时,便认为数据帧接收已经结束.*/
#pragma vector = UART0RX_VECTOR
__interrupt void UART0 (void)
{       
  receive[rec_ptr++] = RXBUF0; // rec_ptr初始值为0,每接受一个数据便自增1
  TACTL |= TACLR;              //定时器清零
  TACTL |= MC0;                  //Timer A开始计时
}

// Timer A0 interrupt service routine
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void)
{ 
  rec_bytes = rec_ptr;       //接收的字节数
  rec_ptr = 0;               //清零以准备下一次数据帧的接收
  received = 1;              //程序运行到这里表示已接收到一个完整的数据帧,将received置位
  TACTL &= ~MC0;                //Timer A停止计时
}

⌨️ 快捷键说明

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