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

📄 protocol.c

📁 单相复费率MSP430硬件时钟参考代码,MSP413设计方案
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "msp430x41x.h"
#include "string.h"
#include "general.h"  
#include "protocol.inc"
#include "protocol.h"

#define OK                     0
#define ERROR                  1
#define PRE_FRAME_FLAG         0xFE
#define FRAME_START_FLAG       0x68
#define FRAME_END_FLAG         0x16
#define ADDRESS_AREA_LEN       LEN_OF_WATCH_NO
//根据底层更改的
#define FRAME_DATA_LEN         48 /* 目前最大的为时区、时段表设置,42字节(含标识符/密码项共6字节) */

#define FRAME_DATA_APPENDVALUE 0x33

#define SYSTEM_PASS_PROGRAM    0x00     //优先级越低越高,编程密码
#define SYSTEM_PASS_CLR        0x01     //清零密码,清零时使用 

unsigned char UartRxByteTime;
unsigned char FrameBuffer[FRAME_BUFFER_LEN];
unsigned char FramePointer;
unsigned short DI1DI0;
unsigned char SlvsWrDataAddrIdx;
unsigned char SlvsWrDataLenIdx;

/* 错误信息字 
    目前仅提供非法数据、数据标识错、密码错的出错返回,其余不大会出错,
    以后再说??? -----有装备自检代码,不需要这里的考虑了
*/
enum
{
    ERROR_DATA = 1,                             //bit0 非法数据
    ERROR_DATAID = 2,                           //bit1 数据标识错
    ERROR_PASSWORD = 4,                         //bit2 密码错
    ERROR_YEAR_TIMEZONE_OVERFLOW = 0x10,        //bit4 年时区数超
    ERROR_DAY_PERIODOFTIME_OVERFLOW = 0x20,     //bit5 日时段数超
    ERROR_CHARGE_TYPE_OVERFLOW = 0x40,          //bit6 费率数超
    ERROR_RECEIVE_FRAME_ERROR_AND_OTHER_ERROR = 0xCC //接收组帧错误或者出错国标不要求返回情况下的标记,填写在返回控制码位置 - zk - 2003-11-2 add
}ERROR_INFORMATION_ENUM;

//接收帧信息,底层驱动在每接收到一个字符后,调用本函数,利用全局结构strFrameInfo来记录接收数据
unsigned char Rx_FrameInfo(void)
{
    unsigned char ucCS;
    FramePointer=0;
    while(FramePointer< FRAME_BUFFER_LEN)
    {
        while(UartBitCount)
            ClrWDT();
        
        FrameBuffer[FramePointer++]=UartRxByte;
        
        switch(UartState)
        {
            case UART_WAIT_START_BYTE1: //第一个0x68H
                if(UartRxByte == UART_START_BYTE)  
                {
                    UartState = UART_WAIT_ADDRESS;
                }
                else
                {
                    FramePointer=0;
                }
                ucCS=0;
                break;
            
            case UART_WAIT_ADDRESS: //地址区
                if(FramePointer == FRM_ADDR+8)  
                {
                    //UartState=UART_WAIT_START_BYTE2;
                    UartState = UART_WAIT_DATA_LENGTH;
                }
                break;
                
            #if 0
            case UART_WAIT_START_BYTE2: //第二个0x68H
                if(UartRxByte == UART_START_BYTE)  UartState = UART_WAIT_CTL_WORD;
                else  goto Rx_FrameInfo_Err;
                break;
                
            case UART_WAIT_CTL_WORD:    //命令字 接收数据buf从此开始存放
                UartState = UART_WAIT_DATA_LENGTH;
                break;
            #endif    
            
            case UART_WAIT_DATA_LENGTH: //数据长度
                    if(UartRxByte != 0)  UartState = UART_WAIT_DATA;
                    else  UartState = UART_WAIT_CS;
                break;
                
            case UART_WAIT_DATA:
                FrameBuffer[FramePointer-1]=UartRxByte-FRAME_DATA_APPENDVALUE;
                if(FramePointer  == FRM_CS)  UartState = UART_WAIT_CS;
                break;
            
            case UART_WAIT_CS:
                if(ucCS == UartRxByte)  UartState = UART_WAIT_STOP_BYTE;
                else  goto Rx_FrameInfo_Err;
                break;
                
            case UART_WAIT_STOP_BYTE:
                if(UART_STOP_BYTE == UartRxByte)
                {
                    UartState = UART_RXD_OK;
                    goto Rx_FrameInfo_End;
                }
                else  goto Rx_FrameInfo_Err;
            
            default:
                goto Rx_FrameInfo_Err;
        }    
        
        ucCS+=UartRxByte;
        
        UartRxReady();
    }
Rx_FrameInfo_Err:
    UartState = UART_WAIT_START_BYTE1;
Rx_FrameInfo_End:
    return UartState;
}

//比对从机地址
unsigned char CompareAddressArea(void)
{
    unsigned char ucaTemp[ADDRESS_AREA_LEN];
    
    E2promRead(PTL_ADDRESS_OF_WATCH_NO, ucaTemp, LEN_OF_WATCH_NO);//读表号    
    
    if(IsEqual(&FrameBuffer[FRM_ADDR],ucaTemp,6))  return COMPARE_FLAG_SINGLE_NO;
    
    if(IsEqualSpecialData(&FrameBuffer[FRM_ADDR],0x99,6)) return COMPARE_FLAG_BROADCAST;
    
    return COMPARE_FLAG_ERROR;
}

void _bcd_short_add1_and_write_e2prom_(unsigned char addr)
{
    E2promRead(addr, (unsigned char*)&DI1DI0, 2);
    DI1DI0 = __bcd_add_short(DI1DI0, 1);
    E2promWrite(addr, (unsigned char*)&DI1DI0, 2);
}

void _slvs_rd_month_pwr_data_(unsigned char item)
{
    DI1DI0=(GetPreviousMonthIndex(item)*40)+ ADDRESS_OF_MONTH_LOG;
    FrameBuffer[FRM_DATALEN]= PROTOCOL_WR_DATALEN;
}

//0x941F,0x981F
static unsigned char _slvs_rd_proc1_(void)
{
    _slvs_rd_month_pwr_data_((FrameBuffer[DI1]&0x0C)>>2);
    return _READE2PROM_;
}

//0xD120,0xD121,0xD122,0xD123,0xD124,0xD125,0xD126,0xD127,0xD128,0xD129,0xD12A,0xD12B
static unsigned char _slvs_rd_proc2_(void)
{
    _slvs_rd_month_pwr_data_((FrameBuffer[DI0] & 0x0F)+1);
    return _READE2PROM_;
}

void _copy_system_time_(unsigned char *data1,unsigned char *data2)
{
    FrameBuffer[FRM_DATALEN]=3+(unsigned char)(DI1DI0);
    memcpy(data1,data2, FrameBuffer[FRM_DATALEN]);
}

//0xC010,0xC011
static unsigned char _slvs_rd_proc3_(void)
{
#ifndef _HARDWARE_RTC
    unsigned char time_bcd[7];
    GetSystemTimeBcd(time_bcd);
#endif
    DI1DI0=~((unsigned short)(FrameBuffer[DI0]|0xFFFE));
#ifdef _HARDWARE_RTC
    _copy_system_time_(&FrameBuffer[FRM_DATA+2],g_time+(unsigned char)(3*DI1DI0));
#else
    _copy_system_time_(&FrameBuffer[FRM_DATA+2],time_bcd+(unsigned char)(3*DI1DI0));
#endif
    return _NOREADE2PROM_;
}

//0xC020
static unsigned char _slvs_rd_proc4_(void)
{
    unsigned char temp;

    temp=GetPowerAttribute();
    FrameBuffer[FRM_DATA+2]=((temp&0x03)+1)|((temp&ATTRIBUTE_OF_PLUS_MINUS)<<1);
    if(BreakOrLowPowerFlag&LOW_PWR_TST)
        FrameBuffer[FRM_DATA+2]|=0x04;
    FrameBuffer[FRM_DATALEN]=1;
    return _NOREADE2PROM_;
}

const unsigned char _slvs_read_p5_len_[] =
{
    1,2,3,4,6,16,27
};

const unsigned char _slvs_read_p5_addr_[] =
{
    //PTL_ADDRESS_OF_SUCCESSSETTIME_FLAG,//0xC014
    //PTL_ADDRESS_OF_DEVICE_STATUS_EXPAND,//0xC025
    ADDRESS_OF_PROGRAM_TIMES,//0xB212
    ADDRESS_OF_DEVICE_CLEAR_TIMES,//0xB213
    ADDRESS_OF_OPEN_COVER_CNT,//0xE210
    //ADDRESS_OF_POWER_TIME_MINUS,//0xB021
    ADDRESS_OF_START_TIME_MINUS+1,//0xB020
    ADDRESS_OF_PROGRAM_TIME+1,//0xB210
    ADDRESS_OF_DISPLAY_CHOOSE_BAK,//0xC115
    //PTL_ADDRESS_OF_LASTSETTIME_TIME,//0xC012
    //PTL_ADDRESS_OF_POWER_STARTVALUE_TIME,//0xC11B
    ADDRESS_OF_DEVICE_CLEAR_TIME+1,//0xB211
    //ADDRESS_OF_LAST_LOW_POWER_TIME,//0xE111
    ADDRESS_OF_SOFTWARE_VERSION,//0xE120
    ADDRESS_OF_OPEN_COVER_TIME,//0xE211
    ADDRESS_OF_STARTING_COUNT,//0xC119
    ADDRESS_OF_LAST_BREAK_POWER_TIME,//0xE110
    //PTL_ADDRESS_OF_PLUSE_COUNT,//0xC11B
    //PTL_ADDRESS_OF_COMM_HOLIDAY,//0xC41F
    //PTL_ADDRESS_OF_WEEKEND,//0xC41E
    //PTL_ADDRESS_OF_WEEKEND,//0xC42E
};

//
static unsigned char _slvs_rd_proc5_(void)
{
    FrameBuffer[FRM_DATALEN]=_slvs_read_p5_len_[SlvsWrDataLenIdx];
    DI1DI0=_slvs_read_p5_addr_[SlvsWrDataAddrIdx];
    return _READE2PROM_;
}

#ifdef _SUPPORT_RELAY
void _relay_current_state_(void)
{
    if(!RelayStateCheck(FrameBuffer[FRM_DATA+2]))
        FrameBuffer[FRM_DATA+2]|=0xC0;
    FrameBuffer[FRM_DATALEN]=1;
}

static unsigned char _slvs_rd_proc7_(void)
{
    E2promRead(ADDRESS_OF_RELAY_STATE,&FrameBuffer[FRM_DATA+2],1);
    _relay_current_state_();
    return _NOREADE2PROM_;
}

//0xE202,0xE204
static unsigned char _slvs_rd_proc8_(void)
{
    FrameBuffer[FRM_DATA+2]=FrameBuffer[DI0];
    RelayCtrl(FrameBuffer[FRM_DATA+2]);
    _relay_current_state_();
    return _NOREADE2PROM_;
}
#endif

static unsigned char _slvs_rd_proc9_(void)
{
    unsigned char temp,temp1;

    temp=PowerPulseCounter%PowerPulseConstant_;
    temp=(unsigned char)Hex2Bcd((unsigned long)temp);
    MemSetTo0(&FrameBuffer[FRM_DATA+2],4);
    temp1=(unsigned char)(GetPowerAttribute())&0x03;
    if(temp1==0)
    	FrameBuffer[FRM_DATA+3]=temp;
    else if(temp1==1)
    	FrameBuffer[FRM_DATA+4]=temp;
    else if(temp1==2)
    	FrameBuffer[FRM_DATA+2]=temp;
    FrameBuffer[FRM_DATA+5]=temp;
    FrameBuffer[FRM_DATALEN]=4;
    return _NOREADE2PROM_;
}

#ifdef _HARDWARE_RTC
static unsigned char _slvs_rd_proc10_(void)
{
    RealtimeOper(0x70,&FrameBuffer[FRM_DATA+2],1);
    return _NOREADE2PROM_;
}
#endif

// 0x901F,0x902F
static unsigned char _slvs_rd_proc11_(void)
{
#if 0
    unsigned long totle;
    unsigned char pulsetemp,i,temp;

    temp=(FrameBuffer[DI0]>>5);
    DI1DI0=temp*20+ADDRESS_OF_TOTAL_POWER_PLUS;
    for(i=0;i<COUNT_OF_CHARGE_RATE+1;i++)
    {
        if(i==0)
        {
            pulsetemp=PowerScalar[temp+8];
        }
        else
        {
            pulsetemp=PowerScalar[temp*4+i-1];
        }
        E2promRead(DI1DI0+i*4, (unsigned char *)&totle, 4);
        pulsetemp=(unsigned char)Hex2Bcd((unsigned long)pulsetemp);
        totle=__bcd_add_long(totle,(unsigned long)pulsetemp);
        memcpy(&FrameBuffer[FRM_DATA+2+i*4],(unsigned char *)&totle,4);
    }
#endif    

    unsigned char temp;

    PowerDataStore();
    temp=(FrameBuffer[DI0]>>5);
    DI1DI0=ADDRESS_OF_TOTAL_POWER_PLUS+temp*20;
    FrameBuffer[FRM_DATALEN]=PROTOCOL_WR_DATALEN;
    return _READE2PROM_;
}

static unsigned char _slvs_rd_proc12_(void)
{
    SaveTimeOfMiuns();
    DI1DI0=ADDRESS_OF_POWER_TIME_MINUS;
    FrameBuffer[FRM_DATALEN]=3;
    return _READE2PROM_;
}

#ifdef TEST_COURSE
static unsigned char _slvs_rd_proc13_(void)
{
    POWER_PULSE_DIR|=POWER_PULSE;
    POWER_PULSE_OUT&=~(POWER_PULSE);
    _NOP();
    _NOP();
    POWER_PULSE_DIR&=~(POWER_PULSE);
    POWER_PULSE_OUT|=POWER_PULSE;
    FrameBuffer[FRM_DATALEN]=0;
    return _NOREADE2PROM_;
}
#endif

typedef unsigned char (*COMM_PROC_PTR)(void);

const unsigned short _slvs_cmds_read_[]=
{
    0x941F,0x981F,
    0,
    0xD120,0xD121,0xD122,0xD123,0xD124,0xD125,0xD126,0xD127,0xD128,0xD129,0xD12A,0xD12B,
    0,
    0xC010,0xC011,
    0,
    0xC020,
    0,
    0xF0F0,//Len=1
    //0xC014,//0xC025
    0xF0F0,//Len=2
    0xB212,0xB213,0xE210,
    //0xC11E,
    0xF0F0,//Len=3
    0xF0F0,//Len=4
    0xB020,0xB210,
    0xC115,0xB211,
    0xF0F0,//Len=6
    0xE120, 0xE211,
    0xF0F0,//Len=16
    0xC119,
    0xF0F0,//Len=35
    0xE110,
    //0xF0F0,//Len=24
    //0xF0F0,//Len=32
    //0xC11B,
    //0xF0F0,//Len=36
    //0xC41F,0xC41E,0xC42E,
#ifdef _SUPPORT_RELAY
    0,
    0xE101,
    0,
    0xE202,0xE204,
#endif
    0,
    0xC11B,
    0,
#ifdef _HARDWARE_RTC
    0xE210,
    0,
#endif
    0x901F,0x902F,
    0,
    0xB021,
#ifdef TEST_COURSE
    0,
    0xE301,
#endif
    0xFFFF
};

const COMM_PROC_PTR _slvs_process_read_ []=
{
    _slvs_rd_proc1_,
    _slvs_rd_proc2_,
    _slvs_rd_proc3_,
    _slvs_rd_proc4_,
    _slvs_rd_proc5_,
#ifdef _SUPPORT_RELAY
    _slvs_rd_proc7_,
    _slvs_rd_proc8_,
#endif
    _slvs_rd_proc9_,
#ifdef _HARDWARE_RTC
    _slvs_rd_proc10_,
#endif
    _slvs_rd_proc11_,
    _slvs_rd_proc12_,
#ifdef TEST_COURSE
    _slvs_rd_proc13_
#endif
};

//0xC115
static unsigned char _slvs_wr_proc1_(void)
{
    unsigned char i,temp1;
    unsigned short disp_temp;
	
    disp_temp=(FrameBuffer[FRM_DATA+6]<<8)|FrameBuffer[FRM_DATA+7];
    MemSetTo0(&FrameBuffer[FRM_DATA+6+4],7);
    FrameBuffer[FRM_DATA+6+4]=FrameBuffer[FRM_DATA+6]>>4;
    
    for(i=0;i<3;i++)
    {
        temp1=(unsigned char)((disp_temp>>(i*4))&0x0F);
        if(temp1)
        {
            FrameBuffer[FRM_DATA+6+4]|=0x40>>i;
            FrameBuffer[FRM_DATA+6+4+4-i]=temp1;
        }
    }
    E2promWrite(ADDRESS_OF_DISPLAY_CHOOSE_BAK, &FrameBuffer[FRM_DATA+6], 11);
    LcdDisplayReload();
    //FrameBuffer[FRM_DATALEN]=11;
    //DI1DI0=ADDRESS_OF_DISPLAY_CHOOSE_BAK;
    return _NOWRITEE2PROM_;
}

//0xC010,0xC011,
static unsigned char _slvs_wr_proc2_(void)
{
    DI1DI0=~((unsigned short)(FrameBuffer[DI0]|0xFFFE));
#ifndef _HARDWARE_RTC
    _DINT();
#endif
    _copy_system_time_(g_time+(unsigned char)(3*DI1DI0),&FrameBuffer[FRM_DATA+6]);
    SetSystemTime();
#ifndef _HARDWARE_RTC
    _EINT();
#endif
    return _NOWRITEE2PROM_;
}

void _save_time_to_e2prom_(unsigned short addr)
{
#ifndef _HARDWARE_RTC
    unsigned char time_bcd[7];
    
    GetSystemTimeBcd(time_bcd);
    memcpy(&FrameBuffer[FRM_DATA+6], time_bcd, RTC_TIME_LEN);
    memcpy(&FrameBuffer[FRM_DATA+9], time_bcd+4, RTC_DATA_LEN);
#else
    memcpy(&FrameBuffer[FRM_DATA+6], g_time, RTC_TIME_LEN);
    memcpy(&FrameBuffer[FRM_DATA+9], g_time+4, RTC_DATA_LEN);
#endif
    E2promWrite(addr, &FrameBuffer[FRM_DATA+6], LEN_OF_POWER_STARTVALUE_TIME); 
}

void _memset0_and_write_e2prom_ (unsigned short addr,unsigned char len)
{
    MemSetTo0(&FrameBuffer[FRM_DATA],len);
    E2promWrite(addr,&FrameBuffer[FRM_DATA],len);
}

//0xC119
static unsigned char _slvs_wr_proc3_(void)
{
    E2promWrite(ADDRESS_OF_STARTING_COUNT, &FrameBuffer[FRM_DATA+6], PROTOCOL_WR_DATALEN);
    
    /* 因为是设定初值,所以,需将当前正向电量设定为给定的值,按总峰平谷 */
    #if 1
    E2promWrite(ADDRESS_OF_TOTAL_POWER_PLUS, &FrameBuffer[FRM_DATA+6], PROTOCOL_WR_DATALEN);
    #else
    E2promWrite(PTL_ADDRESS_OF_TOTAL_POWER_PLUS, pucData, LEN_OF_TOTAL_POWER_PLUS);
    E2promWrite(PTL_ADDRESS_OF_TOTAL_APEX_PLUS, (pucData+4), LEN_OF_TOTAL_APEX_PLUS);
    E2promWrite(PTL_ADDRESS_OF_TOTAL_CALM_PLUS, (pucData+8), LEN_OF_TOTAL_CALM_PLUS);
    E2promWrite(PTL_ADDRESS_OF_TOTAL_VALE_PLUS, (pucData+12), LEN_OF_TOTAL_VALE_PLUS);
    #endif
    /* 需要将反向电量清零 ??? 以后优化的时候,利用片内flash地址空间,
    上电后将其清零,这样只要指针指到那里即可了,可以省却n多的代码 */
    _memset0_and_write_e2prom_(ADDRESS_OF_TOTAL_POWER_MINUS,PROTOCOL_WR_DATALEN);        

⌨️ 快捷键说明

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