STM32L151+HART协议

2019-12-10 18:18发布

HART协议贴的人少,现在发一个。只用了部分命令。
#include         "use.h"
#include        "Ver.H"
#include        <string.h>
#include  <ctype.h>
#include         <HART_COM.h>
#include        "include.h"
/*
FF FF FF FF FF 06 01 03 10 00 DC 00 00 00 00 ED 8F C2 43 00 00 00 00 00 00 A0 40 34
FF FF FF FF FF 06 01 03 10 00 DC 00 00 00 00 ED 8F C2 43 00 00 00 00 00 00 A0 40 34 、

HART命令0:读标识码
返回扩展的设备类型代码,版本和设备标识码。
请求:无
响应:
字节0:        254
字节1:        制造商ID(Enum)
字节2:        设备类型(Enum)
字节3:        请求的最小前导符数(主->从)
字节4:        通用命令文档版本号
字节5:        设备规范版本号
字节6:        设备软件版本号
字节7:        (前五个bit)设备硬件版本号
                                                                (后三个bit)物理信号类型(Enum)
字节8:        设备标志
字节9-11:     设备ID号

*/
void HART_GET_RD_0_TO_MAST(unsigned char adr,unsigned char com){
        const char COMM0[]={
                254,adr0,2,MAX_0xff,HART_VER,6,7,0xf1,adr1,adr2,adr3,0   //预留出最后一个字节放菜单地址!
        };
        unsigned char buf[100],b[30],cnt,b_cnt;
        //****************************************************************
        //装配工作参数 浮点数
        memcpy(b,COMM0,sizeof(COMM0));
        b_cnt =sizeof(COMM0);
        b[b_cnt-1] =adr;                                                                                                                                        //最后的字节放菜单地址!
        cnt        =HART_Format_HEAD(buf,adr,com,b_cnt,0);                         //0=响应码!
        memcpy(buf+cnt,b,b_cnt);
        HART_Send_OUT(buf,cnt+b_cnt);       
}
//**********************************************************************************
//装配工作参数  返回16个字节,4个浮点数
unsigned char Init_WORK_Data_B(unsigned char *buf){
        float  b;

        b=LedMenu.B;
        buf[0]='m';
        Get_MinFloat_MCU(buf+1,(unsigned char *)&b);
        return 5;        //返回5个字节
}
//**********************************************************************************
//装配工作参数  返回8个字节,2个浮点数
unsigned char Init_WORK_Data_Ao(unsigned char *buf){
        float  b;

        b=LedMenu.AD;
        Get_MinFloat_MCU(buf,(unsigned char *)&b);
        b=LedMenu.C;
        Get_MinFloat_MCU(buf+4,(unsigned char *)&b);

        return 8;        //返回8个字节
}

/**********************************************************************************
//从应答工作数据
4个字节:
1-4:浮点数的数据
***********************************************************************************/
void HART_GET_WORK_B_TO_MAST(unsigned char adr,unsigned char com){
        unsigned char buf[100],cnt,b[20],b_cnt;

        //****************************************************************
        //装配工作参数 浮点数
        b_cnt =Init_WORK_Data_B(b);
        cnt        =HART_Format_HEAD(buf,adr,com,b_cnt,0);
        memcpy(buf+cnt,b,b_cnt);
        HART_Send_OUT(buf,cnt+b_cnt);
}
/**********************************************************************************
//从应答工作数据
4个字节:
1-4:浮点数的数据
***********************************************************************************/
void HART_GET_WORK_Ao_TO_MAST(unsigned char adr,unsigned char com){
        unsigned char buf[100],cnt,b[20],b_cnt;

        //****************************************************************
        //装配工作参数 浮点数
        b_cnt =Init_WORK_Data_Ao(b);
        cnt        =HART_Format_HEAD(buf,adr,com,b_cnt,0); //0=响应码!
        memcpy(buf+cnt,b,b_cnt);
        HART_Send_OUT(buf,cnt+b_cnt);
}
/***************************************************************************************
HART命名13:读标签Tag,描述符Description和日期Date
读设备的Tag,Description and Date。
请求:无
响应:
      字节0-5:    标签Tag,ASCII
字节6-17:  描述符,ASCII
字节18-20:日期,分别是日、月、年-1900
****************************************************************************************/
unsigned char Init_MAST_Data(char *buf){
        memcpy(buf,MAST_Tag,8);
        Get_ASCII_6bit(buf);
        memcpy(buf+6,MAST_Description,16);
        Get_ASCII_6bit(buf+6);
        buf[18]=MAST_Day;
        buf[19]=MAST_Mon;
        buf[20]=MAST_Use_Year;
        return 21;
}
//***************************************************************************************
//返回=0;不相等!==1是相等
unsigned char JB_TAG_Name(char *buf){
        char s[10],t[50];
       
        memset(s,0,sizeof(s));
        memset(t,0,sizeof(t));
        memcpy(t,buf,6);                                //命令只有6个字节TAG
        Decode_ASCII_6bit(t,s);
        if(strcmp(s,MAST_Tag)) return 0;
        return 1;  // 相等返回1!
}
//***************************************************************************************
void HART_GET_RD_13_TO_MAST(unsigned char adr,unsigned char com){
        unsigned char buf[100],cnt,b[50],b_cnt;
        //****************************************************************
        //装配工作参数 浮点数
        b_cnt =Init_MAST_Data((char *)b);
        cnt        =HART_Format_HEAD(buf,adr,com,b_cnt,0); //0=响应码!
        memcpy(buf+cnt,b,b_cnt);
        HART_Send_OUT(buf,cnt+b_cnt);
}

/**********************************************************************************
读设备含有的消息。
请求:无
响应:
字节0-23:  设备消息,ASCII

设备的值字节;  
P----- 0-3 设备的值字节(单位代码字节 );
t----- 5-8
S--    改成P3菜单中的t1
K---9 改成P3菜单中的to                       
FO-----  15-18设备的值字节(单位代码字节 );      
FS-----  20-23H-

HART命令12:读消息(Message)
读设备含有的消息。
请求:无
响应:
字节0-23:  设备消息,ASCII

***********************************************************************************/
void HART_GET_RD_12_TO_MAST(unsigned char adr,unsigned char com){
        unsigned char buf[100],cnt,b[50],b_cnt;

        b_cnt=sprintf((char *)b,"P:%d T%4.2f K%4.2f Fo%4.2f Fs%4.2f     ",Mp1.P,Mp1.t0,Mp1.bo,Mp1.Fo,Mp1.Fs);
        if(b_cnt>31) b[32]=0;
        Get_ASCII_6bit((char *)b);
        b_cnt=24;
        cnt        =HART_Format_HEAD(buf,adr,com,b_cnt,0);
        memcpy(buf+cnt,b,b_cnt);
        HART_Send_OUT(buf,cnt+b_cnt);       
}
//*****************************************************
//得到菜单数据;返回=0 无数据;=1是整数;=2是浮点数!
unsigned char Hart_get_Mp1(unsigned char id,unsigned char *pInt,float *pFloat){
        unsigned char j=0;
        unsigned char *xP;
        float  *xF;
        MP1        mp1;

        if(id>=MaxK) return 0;
        //*********************************************************************************
        memcpy((unsigned char *)&mp1,(unsigned char *)&Mp1,sizeof(MP1));
        mp1.C=LedMenu.C;
        mp1.AD=LedMenu.AD;
        xP=GetAdr(id,(unsigned char *)&mp1);
        if (MenuAsc[id].Type <=Int4){        //整数处理
                *pInt=*xP;
                j=1;
        }else{                                                 //浮点数处理
                xF=(float *)xP;
                *pFloat=*xF;
                j=2;
        }
        return j;
}
//*********************************************************************888
//判别序号可写  return 0 = 可以写入
const unsigned char IDK_MENU[]={
        2,3,5,6,8,9,14,17,18,19,20,21,25,26,27,28,29,30
};

unsigned char JB_Id_En_Wr(unsigned char id){
        unsigned char i;
       
        for(i=0;i<sizeof(IDK_MENU);i++){
                if(id==IDK_MENU[i]) return 1;
        }
        return 0;
}
//*****************************************************
//得到菜单数据;返回=0 无数据;=1是整数;=2是浮点数!
unsigned char Hart_wr_Mp1(unsigned char id,float f1){
        unsigned char j=0;
        unsigned char *xP;
        float  *xF;

        if(id>=MaxK) return 0;
        //*********************************************************************************
        //添加写入控制2016-7-11
        if(JB_Id_En_Wr(id))  return 0;
        //*********************************************************************************
        xP=GetAdr(id,(unsigned char *)&Mp1);
        if (MenuAsc[id].Type <=Int4){        //整数处理
                if(f1<MenuAsc[id].Min) f1=MenuAsc[id].Min;
                if(f1>MenuAsc[id].Max) f1=MenuAsc[id].Max;
                *xP=(unsigned char)f1;
                j=1;
        }else{                                                 //浮点数处理
                xF=(float *)xP;
                if(f1<MenuAsc[id].Min) f1=MenuAsc[id].Min;
                if(f1>MenuAsc[id].Max) f1=MenuAsc[id].Max;
                *xF=f1;
                j=2;
        }
        return j;
}
/*****************************************************************************************
命令60:读模拟输出AO和量程的百分比
读模拟输出值和所选模拟输出的量程百分比。这个模拟输出总是匹配设备相关的物理模拟输出,
包括报警条件和设置值。量程的百分比没有限制在0-100%之间,但是不能超过传感器的高低限。
请求:
      字节0:        模拟输出号代码
响应:
      字节0:        模拟输出号代码
      字节1:        模拟输出单位代码
      字节2-5:    模拟输出值
      字节6-9:    模拟输出量程百分比      发送短消息
******************************************************************************************/
void HART_GET_RD_60_TO_MAST(unsigned char adr,unsigned char com,unsigned char id){
        unsigned char buf[100],cnt,b[100],b_cnt,i,dat;
        float f1;
        //****************************************************************
        //装配工作参数 浮点数
        memset(b,0,sizeof(b));
        i=Hart_get_Mp1(id,&dat,&f1);
        if(i==0)                b_cnt=0;//无数据!
        if(i==1){
                b[0]=id;
                b[1]=id+'=';
                f1=dat;
                Get_MinFloat_MCU(b+2,(unsigned char *)&f1);
                b_cnt=10;
        }
        if(i==2){
                b[0]=id;
                b[1]='=';
                Get_MinFloat_MCU(b+2,(unsigned char *)&f1);
                b_cnt=10;
        }
        cnt        =HART_Format_HEAD(buf,adr,com,b_cnt,0);
        memcpy(buf+cnt,b,b_cnt);
        HART_Send_OUT(buf,cnt+b_cnt);       
}
/**********************************************************************************
命令64:写模拟输出附加阻尼值
为所选模拟输出写附加阻尼值。附加的阻尼值表示一个时间常数。
请求:
      字节0:        模拟输出号代码
      字节1-4:    模拟输出附加阻尼值,单位秒
响应:
      字节0:        模拟输出号代码
      字节1-4:    模拟输出附加阻尼值,单位秒

*************************************************************************************/
void        HART_GET_WR_64_TO_MAST(unsigned char adr,unsigned char com,unsigned char *p){
        unsigned char buf[100],cnt,id,i,b[50],b_cnt;
        float f1;
        //****************************************************************
        memset(b,0,sizeof(b));
        id=p[0];
        f1=Get_MaxFloat_MCU(&p[1]); //得到数据
        i=Hart_wr_Mp1(id,f1);
        if(i==0){
                b_cnt=0;
        }else{
                b[0]=id;
                Get_MinFloat_MCU(b+1,(unsigned char *)&f1);
                b_cnt=5;
                WriteToEexx(0);
        }
        //************************************************************
        cnt        =HART_Format_HEAD(buf,adr,com,b_cnt,0);
        memcpy(buf+cnt,b,b_cnt);
        HART_Send_OUT(buf,cnt+b_cnt);       
}
/**********************************************************************************
//从应答工作数据
4个字节:
1-4:浮点数的数据
***********************************************************************************/
void HART_RESET_TO_MAST(unsigned char adr,unsigned char com){
        unsigned char buf[100],cnt;

        //****************************************************************
        cnt        =HART_Format_HEAD(buf,adr,com,0,0);  //应答吗=00 OK  数据长度=0
        HART_Send_OUT(buf,cnt);
        //******************************************************************
        //等待发送完毕,复位!
        tDelay(2000);
        //reset
        NVIC_SystemReset();
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。