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

📄 protocol.c

📁 单相多功能代码,计量芯片采用ADE7737做为计量,SPI通讯,仅供参考,不得用于商业
💻 C
📖 第 1 页 / 共 2 页
字号:
        {
            min1=Bcd2HexChar(SystemTime[SPACE_OF_HOUR])*60+Bcd2HexChar(SystemTime[SPACE_OF_MINUTE]);
            min2=Bcd2HexChar(FrameBuffer[FRM_DATA+2])*60+Bcd2HexChar(FrameBuffer[FRM_DATA+1]);
            if (abs(min1 -min2) > 5)
            {
                return RET_NO_RESPONSION;
            }
SET_SYS_TIME:
            // 写入对时时间
            memcpy(SystemTime, &FrameBuffer[FRM_DATA], 3);
            memcpy(SystemTime+4, &FrameBuffer[FRM_DATA+3], 3);
            // 对时
            _disable_interrupt();
            BasicTimerTick=0;
            _enable_interrupt();
            SetSystemTime(); 
            GetSystemTime();
            // 保存校时信息
            SavePgmInfo(ADDR_OF_BCCT_IDX);
            flg=0x01;
            AptoticDataWrite(ADDR_OF_SUCCESSSETTIME_FLAG,&flg,1);
        }
    }
#endif
    return RET_NO_RESPONSION;
}

/*************************************************
 * 广播设置表号
 *************************************************/
static unsigned char SlvsProcWriteMeterNum(void)
{
#if 0
    AptoticDataWrite(ADDR_OF_METER_NUM,&FrameBuffer[FRM_DATA],FRM_ADDR_LEN);
    FrameBuffer[FRM_DATALEN]=0;
#endif
    return(RET_SEND_RIGHT_RESPONSION);
}

/*************************************************
 * 最大需量清零
 *************************************************/
static unsigned char SlvsProcClrReqPwrData(void)
{
#if 0
    unsigned char i;

    LCD_LIGHT_OUT&=~(LCD_LIGHT);
    ClearReqData(BASE_CUR);
    ClearReqData(BASE_CURS);
    for(i=0;i<120;i++)
    {
        ClearReqData(YEAR_BASE+i*BASE_MON_OFFSET);
    }
    LCD_LIGHT_OUT|=(LCD_LIGHT);
    SavePgmInfo(BASE_CLRRT_IDX);
#endif
    return(RET_NO_RESPONSION);
}

/*************************************************
 * 电表清零
 *************************************************/
static unsigned char SlvsProcClrMeterData(void)
{
#if 0
    unsigned char temp[130],i;
    const unsigned long _data_addr[]=
    {
        BASE_LV,// 清失压失流记录
        BASE_LI,
        ADDR_OF_LV_LOG_01,
        ADDR_OF_LV_LOG_06,
        ADDR_OF_LI_LOG_01,
        ADDR_OF_LI_LOG_06,
        BASE_NOREGV_A_TIMES,// 清电压不合格发生时间
        ADDR_OF_PROG_TIMES,// 清编程次数和编程时间、需量清零时间、广播校时时间
        ADDR_OF_CP_TIMES,// 清停电时间和来电时间
        ADDR_OF_OUCB_TIMES,// 清开关上盖报警信息
        ADDR_OF_ODCB_TIMES,// 清开关下盖报警信息
        ADDR_OF_METER_RUNTIME,//清电表运行时间和电池使用时间
    };
    const unsigned char _data_len[]=
    {
        ADDR_OF_LV_LOG_01-BASE_LV,
        ADDR_OF_LI_LOG_01-BASE_LI,
        BASE_LVLOG_OFFSET*5,
        BASE_LVLOG_OFFSET*5,
        BASE_LILOG_OFFSET*5,
        BASE_LILOG_OFFSET*5,
        ADDR_OF_PROG_TIMES-BASE_NOREGV_A_TIMES,
        ADDR_OF_CP_TIMES-ADDR_OF_PROG_TIMES,
        ADDR_OF_OUCB_TIMES-ADDR_OF_CP_TIMES,
        ADDR_OF_ODCB_TIMES-ADDR_OF_OUCB_TIMES,
        BASE_LDST-ADDR_OF_ODCB_TIMES,
        ADDR_OF_DATAFLASH_FLAG-ADDR_OF_METER_RUNTIME
    };
    
    if(SlvsClrStatus&STA_CLR_METER)
    {
        //if(CheckSlvsPwd(&FrameBuffer[FRM_DATA+1])==OK)
        {
            LCD_LIGHT_OUT&=~(LCD_LIGHT);
            MemSetTo0(&temp[0],130);
            // 清电量
            //SlvsProcClrPwrData();
            // 清需量
            //SlvsProcClrReqPwrData();
            for(i=0;i<12;i++)
            {
                VariationalDataWrite(_data_addr[i],temp,_data_len[i]);
            }
            LCD_LIGHT_OUT|=(LCD_LIGHT);
            // 清清零状态
            SlvsClrStatus=0;
        }
    }
    else
    {
        //if(CheckSlvsPwd(&FrameBuffer[FRM_DATA+1])==OK)
        {
            SlvsClrStatus=STA_CLR_METER;
            TimerCounter[TIMER_PROC_CLR]=10;
            TimerProc[TIMER_PROC_CLR]=ResetClearStatusWord;
        }
    }  
#endif
    return RET_NO_RESPONSION;
}

/*************************************************
 * 即时电能冻结
 *************************************************/
static unsigned char SlvsProcSavePowerData(void)
{
#if 0
    unsigned long temp,addr;
    unsigned char i,idx;

    ReadHexIndex(ADDR_OF_FREEZE_IDX,&idx);
    addr=BASE_FREEZE+idx*BASE_FREEZE_OFFSET+4;
    for(i=0;i<20;i++)
    {
        LoadSpecPwrDataCurSum((unsigned char *)&temp,i);
        VariationalDataWrite(addr, (unsigned char *)&temp,4);
        addr+=4;
    }
    SavePgmInfo(ADDR_OF_FREEZE_IDX);
#endif
    return RET_SEND_RIGHT_RESPONSION;
}

// 单机通信控制码
const unsigned char slvs_cmds_single_[]=
{
    FRM_CTRW_READ_SLVS_DATA,
    FRM_CTRW_WRITE_SLVS_DATA,
    FRM_CTRW_WRITE_PASSWORD,
    FRM_CTRW_CLR_PWRDATA,
    FRM_CTRW_CLR_METER_DATA,
    FRM_CTRW_CLR_PASSWORD,
    FRM_CTRW_CLR_CONSTANT,
    FRM_CTRW_CLR_E2PROM_A,
    FRM_CTRW_CLR_E2PROM_V,
    FRM_CTRW_DISP_INFO,
    FRM_CTRW_CLR_REQ_PWRDATA,
    FRM_CTRW_SAVE_ZT_DATA,
    ERROR
};

// 单机通信处理
const COMM_PROC_PTR slvs_proc_single_[]=
{
    SlvsProcReadData,
    SlvsProcWriteData,
    SlvsProcWritePassword,
    SlvsProcClrPwrData,
    SlvsProcClrMeterData,
    SlvsProcClrPassword,
    SlvsProcClrConstant,
    SlvsProcClrFram,
    SlvsProcClrDataflash,
    SlvsProcDispInfo,
    SlvsProcClrReqPwrData,
    SlvsProcSavePowerData,
};

// broadcast commands
const unsigned char slvs_cmds_croadcast_[]=
{
    FRM_CTRW_READ_SLVS_DATA,
    FRM_CTRW_WRITE_SLVS_DATA,
    FRM_CTRW_CLR_PWRDATA,
    FRM_CTRW_CLR_METER_DATA,
    FRM_CTRW_CLR_E2PROM_A,
    FRM_CTRW_CLR_E2PROM_V,
    FRM_CTRW_REVISE_TIME,
    FRM_CTRW_WRITE_MNUM,
    FRM_CTRW_DISP_INFO,
    FRM_CTRW_CLR_REQ_PWRDATA,
    FRM_CTRW_SAVE_ZT_DATA,
    ERROR
};

// 广播通信处理
const COMM_PROC_PTR slvs_proc_croadcast_[]=
{
    SlvsProcReadData,
    SlvsProcWriteData,
    SlvsProcClrPwrData,
    SlvsProcClrMeterData,
    SlvsProcClrFram,
    SlvsProcClrDataflash,
    SlvsProcReviseTime,
    SlvsProcWriteMeterNum,
    SlvsProcDispInfo,
    SlvsProcClrReqPwrData,
    SlvsProcSavePowerData
};

/*************************************************
 * 单机通信处理
 *************************************************/
unsigned char ComSingleMachine(void)
{
    unsigned char cmditem;

    // 如果不是读数据,则检查编程键是否按下
    if(_frm_buf[FRM_COMMAND]!=FRM_CTRW_READ_SLVS_DATA)
    {
        // 编程键检查
        if(ProgramEnableDetect()!=OK)
        {
            // 错误无返回
            return RET_NO_RESPONSION;
        }
    }

    // 查找控制码
    cmditem=FindCmdItem(slvs_cmds_single_,_frm_buf[FRM_COMMAND]);
    if(cmditem!=ERROR)
    {
        return(slvs_proc_single_[cmditem]());
    }
    return(RET_NO_RESPONSION);
}

/*************************************************
 * 广播通信处理
 *************************************************/
unsigned char ComBroadcast(void)
{
    unsigned char cmditem;

    // 如果不是读数据,则检查编程键是否按下
    if((_frm_buf[FRM_COMMAND]!=FRM_CTRW_READ_SLVS_DATA)&&(_frm_buf[FRM_COMMAND]!=FRM_CTRW_REVISE_TIME))
    {
        // 编程键检查
        if(ProgramEnableDetect()!=OK)
        {
            // 错误无返回
            return RET_NO_RESPONSION;
        }
    }

    // 查找控制码
    cmditem=FindCmdItem(slvs_cmds_croadcast_,_frm_buf[FRM_COMMAND]);
    if(cmditem!=ERROR)
    {
        return(slvs_proc_croadcast_[cmditem]());
    }
    return(RET_NO_RESPONSION);
}

/* ensure address
*/
unsigned char CompSlvsAddr(void)
{
    unsigned char ucaTemp[FRM_ADDR_LEN];

    // 读电表表号
    FramRead(ADDR_OF_METER_NUM, ucaTemp, FRM_ADDR_LEN);

    // 比较是否为单机通信
    if(IsEqual(&_frm_buf[FRM_ADDR],ucaTemp,FRM_ADDR_LEN)==OK)  
    {
        return COM_ATTRIBUTE_SINGLE;
    }

    // 比较是否为广播通信
    if(IsEqualSpecialData(&_frm_buf[FRM_ADDR],0x99,FRM_ADDR_LEN)==OK) 
    {
        return COM_ATTRIBUTE_BROADCAST;
    }

    // 校验地址出错
    return ERROR;
}

/* prase frame
*/
void parse_frame(void)
{
    unsigned char ucAddressFlag,ret;

    // 比对表地址
    ucAddressFlag=CompSlvsAddr();
    // 获取标识符
    DI0_H=_frm_buf[DI0]>>4;
    DI0_L=_frm_buf[DI0]&0x0F;

    // 处理数据桢
    switch(ucAddressFlag)
    {
        case COM_ATTRIBUTE_SINGLE:
            ret=ComSingleMachine();
            break;

        case COM_ATTRIBUTE_BROADCAST:
            ret=ComBroadcast();
            break;

        default:
            ret=RET_NO_RESPONSION;
            break;
    }

    if(ret&RET_SEND_RIGHT_RESPONSION)
    {
        _frm_buf[FRM_COMMAND]|=0x80;
    }
    else if(RET_SEND_ERROR_RESPONSION)
    {
        _frm_buf[FRM_COMMAND]=0xCC;
        _frm_buf[FRM_DATALEN]=1;
    }

    if(!(ret&RET_NO_RESPONSION))
    {
        //LcdLightOn(5);
        //TxFrameInfo();
    }
}


⌨️ 快捷键说明

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