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

📄 zb.c

📁 基于电力载波芯片3106开发的,在载波和485之间互相转换
💻 C
字号:
#define ZB_GLOBALS



#include "includes.h"



/****************************变量定义*****************************/
static data  INT8U  ZB_BitCnt;            /*位计数*/
static data  INT8U  ZB_ByteCnt;           /*字节计数*/

static data  INT8U  ZB_GetSyncFlag;       /*接受同步头标志*/
static data  INT8U  ZB_GetDatFlag;        /*接受数据内容标志*/
static data  INT8U  ZB_GetSuccessFlag;    /*接收一字节数据成功标志*/

static data  INT8U  ZB_HeadDatLen;        /*同步头长度*/

static data  INT16U ZB_HeadDat;           /*同步头数据*/
static data  INT8U  ZB_SendByte;          /*要发送的字节数据*/							
static data  INT8U  ZB_RcvByte;           /*接收到的字节数据*/ 

             Com    ZB_Com;	              /*通讯使用结构*/



/****************************本地函数定义*************************/
static void ZB_Tx (void);
static void ZB_Rx (void);



/****************************全局函数*****************************/
ZB_EXT void ZB_ParaInit (void)
/*===============================================
    函数名:    ZB_ParaInit
    功能  :    载波功能参数初始化
    输入  :    无
    输出  :    无
===============================================*/
{
    ZB_BitCnt         = 0;
    ZB_ByteCnt        = 0;

    ZB_GetSyncFlag    = 1;/*接收头标志*/
    ZB_GetDatFlag     = 0;
    ZB_GetSuccessFlag = 0;

    ZB_HeadDatLen     = 0;

    ZB_HeadDat        = 0;
    ZB_SendByte       = 0;
    ZB_RcvByte        = 0;

    ZB_MaxLen         = 0;
}




ZB_EXT void ZB_Course (void)
/*===============================================
    函数名  :    ZB_Course
    功能    :    载波主流程
    输入    :    无
    输出    :    无
===============================================*/
{

    if (ZB_SendFlag){
        ZB_SendFlag = 0;
		
        PLM_RST = 0xa2;

        PLM_RS  = 1;/*转发送*/

    }
}



/****************************本地函数*****************************/
void  ZB_Int (void) interrupt 7
/*===============================================
    函数名  :    ZB_Int
	功能    :    载波同步中断
	输入    :    无
	输出    :    无
===============================================*/
{
    if (1 == PLM_RS){
        ZB_Tx();
    }else{
        ZB_Rx();
    }
}



static void ZB_Tx (void)
/*===============================================
    函数名  :    ZB_Tx
    功能    :    载波发送数据
    输入    :    无
    输出    :    无
===============================================*/
{
	if (0 == ZB_BitCnt){ /*取数据*/

        switch (ZB_Com.TxPhase){

            case 0:	
						
                ZB_SendByte = 0xff;
                ZB_HeadDatLen ++;
                if (6 == ZB_HeadDatLen){
                    ZB_HeadDatLen = 0;
                    ZB_Com.TxPhase = 1;
                }
                break;


            case 1:
                LED_ZB = 0;          /*开载波发送指示灯*/

                ZB_SendByte = 0x09;
                ZB_Com.TxPhase = 2;
                break;


            case 2:                  /*前3部分都是发送同步头,和数据无关*/

                ZB_SendByte = 0xaf;
                ZB_Com.TxPhase = 3;
                break;


            case 3:                  /*发整条帧*/

                ZB_SendByte = COM_DatBuf[ZB_ByteCnt++];
                if (ZB_ByteCnt == ZB_MaxLen){
                    ZB_ByteCnt     = 0;
                    ZB_MaxLen      = 0;
                    ZB_Com.TxPhase = 4;
                }
                break;


            case 4:                  /*多发一字节,保证发送完整*/

                ZB_SendByte    = 0;
                ZB_Com.TxPhase = 0;
                ZB_Com.TxEnd   = 1;
                break;


            default:
                break;

        }
    }

    PLM_RS  = 1;                     /*启动发送*/
    PLM_RST = 0xa2;                  /*防止发送时间过长,进入复位*/

    if (ZB_BitCnt <8){               /*从高位到低位发送数据*/
        if ((ZB_SendByte<<ZB_BitCnt) & 0x80){
            ZB_RS = 1;
        }else{
            ZB_RS = 0;
        }

        ZB_BitCnt ++;
        if (8 == ZB_BitCnt){         /*一个字节数据发送完成*/
            ZB_BitCnt = 0;

            if (1 == ZB_Com.TxEnd){  /*数据发送完成*/
                ZB_Com.TxEnd = 0;

                LED_ZB       = 1;    /*关载波发送指示灯*/

                PLM_RS       = 0;    /*转接收*/
            }
        }
    }
}



static void ZB_Rx (void)
/*===============================================
    函数名  :    ZB_Rx
    功能    :    载波接收数据
    输入    :    无
    输出    :    无
===============================================*/
{
    if (1 == ZB_GetSyncFlag){      /*接收头标志*/

        ZB_HeadDat <<= 1;
        if (1 == ZB_RS){           /*判断P3.7,载波数据收发位*/
            ZB_HeadDat |= 1;
        }

        if (0x09af == ZB_HeadDat){ /*同步头接收成功*/

            LED_ZB = 0;            /*开载波接收指示灯*/

            ZB_GetSyncFlag = 0;
            ZB_GetDatFlag  = 1;     
        }
    }else if (1 == ZB_GetDatFlag){ /*开始接收数据部分*/
        ZB_RcvByte <<= 1;

        if (1 == ZB_RS){
            ZB_RcvByte |= 1;
        }

        ZB_BitCnt ++;
        if (ZB_BitCnt == 8){
            ZB_BitCnt = 0;
            ZB_GetSuccessFlag = 1;
        }
    }

    if (ZB_GetSuccessFlag){        /*接收一个字节成功*/
        ZB_GetSuccessFlag = 0;

        switch (ZB_Com.RxPhase){

            case 0:/*第一起始符*/
                if (0xfe == ZB_RcvByte){
                    ZB_Com.RxPhase = 0;
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                }else if (0x68 == ZB_RcvByte){
                    ZB_Com.RxPhase           = 2;
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                }else if ((0x14 == ZB_RcvByte)||(0x24 == ZB_RcvByte)||(0x16 == ZB_RcvByte)||(0x10 == ZB_RcvByte)){
                    ZB_Com.RxPhase           = 1;
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                }else{
                    ZB_Com.RxErr             = 1;
                }
                break;

            case 1:/*浩迪规约第二起始符*/
                if ((0x11 == ZB_RcvByte)||(0xee == ZB_RcvByte)){
                    ZB_Com.RxPhase           = 2;
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                }else{
                    ZB_Com.RxErr             = 1;
                }
                break;

            case 2:/*地址域*/
                COM_DatBuf[ZB_MaxLen ++]     = ZB_RcvByte;
                ZB_Com.AdrLenCnt ++;
                if (6 == ZB_Com.AdrLenCnt){
                    ZB_Com.AdrLenCnt         = 0;
                    ZB_Com.RxPhase           = 3;
                }else if (ZB_Com.AdrLenCnt > 6){/*为了防止不可预知的错误*/
                    ZB_Com.RxErr             = 1;
                }
                break;

            case 3:/*数据起始符*/
                if (0x68 == ZB_RcvByte){
                    ZB_Com.RxPhase           = 4;
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                }else if (0xaa == ZB_RcvByte){
                    ZB_Com.RxPhase           = 4;
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                }else{
                    ZB_Com.RxErr             = 1;
                }
                break;

            case 4:/*控制码*/
                COM_DatBuf[ZB_MaxLen ++]     = ZB_RcvByte;
                ZB_Com.RxPhase               = 5;
                break;

            case 5:/*数据长度*/
                if (30 > ZB_RcvByte){/*最长数据为20个字节*/
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                    ZB_Com.RxDatLen          = ZB_RcvByte;
                    ZB_Com.RxPhase           = 6;
                }else{
                    ZB_Com.RxErr             = 1;
                }
                break;

            case 6:/*数据域*/
                COM_DatBuf[ZB_MaxLen ++]     = ZB_RcvByte;
                ZB_Com.DatLenCnt ++;
                if (ZB_Com.DatLenCnt == ZB_Com.RxDatLen){
                    ZB_Com.RxPhase           = 7;
                    ZB_Com.DatLenCnt         = 0;
                    ZB_Com.RxDatLen          = 0;
                }else if (ZB_Com.DatLenCnt > ZB_Com.RxDatLen){/*为了防止不可预知的错误*/
                    ZB_Com.RxErr             = 1;
                }
                break;

            case 7:/*校验码*/
                COM_DatBuf[ZB_MaxLen ++]     = ZB_RcvByte;
                ZB_Com.RxPhase               = 8;
                break;

            case 8:/*结束符*/
                if (0x16 == ZB_RcvByte){
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                    ZB_Com.RxPhase           = 0;

                    UART0_SendFlag           = 1;
                    UART0_MaxLen             = ZB_MaxLen;
                    ZB_MaxLen                = 0;

                    ZB_GetSyncFlag           = 1;
                    ZB_GetDatFlag            = 0;

                    LED_ZB                   = 1;
    			}else if (0xff == ZB_RcvByte){
                    COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
                    ZB_Com.RxPhase           = 9;
                }else{
                    ZB_Com.RxErr             = 1;
                }
                break;

            case 9:/*浩迪CRC校验*/
                COM_DatBuf[ZB_MaxLen ++]     = ZB_RcvByte;
    	        ZB_Com.CrcLenCnt ++;
                if (ZB_Com.CrcLenCnt == 2){
                    ZB_Com.RxPhase           = 0;
                    ZB_Com.CrcLenCnt         = 0;

                    UART0_SendFlag           = 1;
                    UART0_MaxLen             = ZB_MaxLen;
                    ZB_MaxLen                = 0;

                    ZB_GetSyncFlag           = 1;
                    ZB_GetDatFlag            = 0;

                    LED_ZB                   = 1;
                }else if (ZB_Com.CrcLenCnt > 2){/*为了防止不可预知的错误*/
                    ZB_Com.RxErr             = 1;
                }
                break;

            default:
                break;
        }

        if (ZB_Com.RxErr){/*如果帧接收有错误*/
            ZB_Com.RxErr      = 0;
            ZB_Com.RxPhase    = 0;
            ZB_Com.RxDatLen   = 0;
            ZB_Com.DatLenCnt  = 0;
            ZB_Com.CrcLenCnt  = 0;
            ZB_Com.AdrLenCnt  = 0;

            ZB_GetSyncFlag    = 1;
            ZB_GetDatFlag     = 0;

            ZB_MaxLen         = 0;

            LED_ZB            = 1;
        }
    }
}



⌨️ 快捷键说明

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