IOH_RS485智能家居RS485总线协议使用及源代码剖析

天锦 发表于 码农也得有格调 分类,标签:

 

 1.下载协议源代码.

IOH_RS485总线协议程序为"IOH_RS485_BUS.C"文件以及与其对应的配置文件"IOH_RS485_BUS.H",此外,总线协议还要获得到MCU的物理地址,所以还需要"Read_MCU_Info.C"文件中的Get_MCU_MAC(void)函数对此操作进行支持.所以总共需要下载一下4个文件:

    IOH_RS485_BUS.C

    IOH_RS485_BUS.H

    Read_MCU_Info.C

    Read_MCU_Info.H

下载之后我们先看一下Read_MCU_Info.C中的Get_MCU_MAC(void)函数:

char MAC[8]=0;
char* Get_MCU_MAC(void)
{
    if(MAC[0]==0)        //如果MAC数组为0时即为首次获得MAC地址,需进行对数组赋值.
    {
        int i;
        char *p;   
        p=0xF1;
        MAC[0]=0x01;     //数组第一位为MCU厂商识别号,STC用0x01
        for(i=0;i<7;i++) //循环7次从RAM中读取设备ID号
        {
            MAC[1+i]=*p;
            p++;
        }
    }
    return MAC[];        //返回数组首地址
}

我使用的是STC公司的单片机,因为STC的单片机都有独一无二的芯片ID,从MCU的RAM的0xF1开始连续7字节是设备的ID,可以直接用来充当设备的物理地址,为防止与总线上其他厂商的MCU串号(虽然可能性很小,但还是要防范嘛!),在7字节的ID号前加上了0x01作为MCU厂商的识别号,共8字节以数组形式存放在内存中,组成了MCU在网内的MAC物理地址,函数返回的是数组在RAM中存放的地址.

回过头来再看总线协议,既然要用到Get_MCU_MAC(void)函数,那就必然要引入Read_MCU_Info.H配置文件

#include<Read_MCU_Info.H>
#include<STC12C5A60S2.H>        //STC单片机的头文件
#include<IOSetting.H>           //硬件连接在IOSetting.H中配置

变量声明

/*************Extern变量**************/
bit  Flag_Not_Auto_Register = 0,        //禁止总线设备自动注册到网关
     Flag_Register_Device = 0,          //请求设备注册到网关
     Flag_Register_UnRegister = 0,        
     Flag_RS485_Device_ACK = 0,           //总线设备响应寻呼
     Flag_Change_Device_State = 0,        //改变设备状态
     Flag_Refresh_Device_State = 0,       //刷新设备状态
     Flag_Back_Device_State = 0,          //主机返回设备状态
     Flag_Get_Host_Address = 0,           //从机得到主机地址
     Flag_RS485_BUS_Data_Recive_Over = 0, //总线收到一个数据包
     Flag_RS485_BUS_Busy = 0,             //总线忙标志位
 
char Val_Host_Address[8];                 //收到的8字节地址
struct Device_Information DeviceInfo;     //设备信息变量

/************协议内部变量**************/ 
int RS485_TimeOut=0;
bit RS485_BUS_Public_Command=0,
 Received_Command_Host_Address=0;
char *MAC_P,RS485_BUS_Addr_Num=0,RS485_BUS_Data_Num=0,
  RS485_BUS_RX_BUF[53],RS485_MAC_Compare_Result=0xAA;

检测总线忙的函数,返回一个逻辑变量1为总线忙,0为总线空闲

bit Cheek_RS485_BUS(void)  //检测RS485总线是否忙
{
 bit temp = 1 ;
 RS485_TimeOut=0;
 if(RXD)
 {
  while(!((!RXD)||(RS485_TimeOut==2)));
  if(RS485_TimeOut==2)
  {
   temp = 0;
  }
 }
 return temp; 
}

释放总线函数

void RS485_BUS_Free(void) 
{
 int i;
 MAX485_ENABLE=1;  //使能MAX485芯片
 TB8=1;     //发送地址码
 ES=0;
 for(i=0;i<8;i++)  //共7位公共地址0x00
 {
  SBUF=0x00;
  while(!TI);
  TI=0;
 }
 TB8=0;     //发送请求指令
 SBUF=Command_Free_RS485_Busy;
 while(!TI);
 TI=0;
 ES=1;
 MAX485_ENABLE=0; //从机发送完成,开始接收
}

请求主机广播主机地址函数,返回值为逻辑型,1为成功.0为失败,获得到的地址保存在Val_Host_Address[8] 中.

bit RS485_BUS_Request_Host_Address(void)
{
 int i;
 bit r=0;
 Wait_RS485_Idle();
 Flag_Get_Host_Address=0;//置标志位为0
 MAX485_ENABLE=1;  //使能MAX485芯片
 TB8=1;     //发送地址码
 for(i=0;i<8;i++)  //共7位公共地址0x00
 {
  SBUF=0x00;
  while(!TI);
  TI=0;
 }
 TB8=0;     //发送请求指令
 SBUF=Command_Publish_Host_Addr;
 while(!TI);
 TI=0;
 MAX485_ENABLE=0; //从机发送完成,开始接收
 RS485_TimeOut=0; //等待接收完成,接收过程在串口中断中进行
 while(!(Flag_Get_Host_Address||(RS485_TimeOut==20)));  //1秒超时等待
 if(Flag_Get_Host_Address)
 {
  r=1;
 } 
 return r;
}

未完待续...

 

0 篇评论

发表我的评论