📄 protocol.c
字号:
#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 + -