?? scomservice.c
字號:
/*#######################################################################################//
文件名: ScomService.c
功能: 串行通信服務函數實現
單位: 浙江工商大學-信電學院
創建日期:2004-09-24
創建人: Houseivan
修改人: Houseivan
修改日期:2005-03-11
########################################################################################*/
//##########################智能數據采集系統串行通訊協議簡要:############################//
//#數據幀幀頭:0xEB 0x90 0xEB 0x90 0xEB 0x90
//#有效數據塊:遠程主機地址 本地主機地址 命令 參數和校驗數據總長度 命令參數
//#幀序號(FrameNumHigh FrameNumLow) 校驗碼(CRCHigh CRCLow)#
//#數據幀幀尾:0x7E /*SCOM空閑時保持Mark狀態即邏輯'1'*/
//#######################################################################################//
#include"Includes.h"
/*檢測是否配置了網絡通信功能*/
#if _SCOM_TASK>0
extern uchar code FrameHead[]; //協議幀頭
extern uchar data TempInteger; //溫度值整數和符號字節
extern uchar data TempDecimal; //溫度值小數位字節
extern uchar data HumiInteger; //濕度值整數和符號字節
extern uchar data HumiDecimal; //濕度值小數位字節
extern uchar data UartRecBuf[]; //數據通訊緩沖器
extern uchar data ClkLcmBuf[_MAX_LCM_NUM]; //顯示和時鐘操作緩沖器
extern uchar data DataBlockCount; //接收緩沖中有效數據個數
extern uchar data RecUpFlg; //接收數據用標志變量
extern uchar data UartHead; //接收檢驗幀頭存放變量
extern uchar data SystemState; //當前系統工作狀態指示變量
extern uchar data SlaveAddr; //本地主機地址
extern uchar data MasterAddr; //遠程主機地址
extern uchar data CurRecNum; //記錄計數器 循環隊列形式
extern uchar data LcmMode; //顯示模式選擇
extern bit RecReady; //正確的數據接收完成標志
extern bit WorkMode;
#if(_SCOM_TEST>0)
extern uchar TestCom;
#endif //根據登陸成功與否確定站點工作的模式
#endif
/*檢測是否配置了網絡通信功能*/
#if _SCOM_TASK>0
//#######################################################################################//
//#include "ScomService.h"
//#######################################################################################//
//#Function: void Uart0Init(void)
//#Description: 51串行口初始化
//#Input: 無
//#Output: 無
//#Return: 無
//#Others: 文件級公共函數
//#SBUF-串行口數據寄存器;TMOD,T2MOD,TCON,T2CON設置波特率發生器的工作方式
//#SCON-串行控制寄存器[7..0]=SM0 SM1 SM2 REN TB8 RB8 TI RI
//#PCON-電源控制寄存器[7..0]=SMOD - - - GF1 GF0 PD ID
//#IE -中斷允許控制寄存器[7..0]=EA -ET2 ES ET1 EX1 ET0 EX0
//#######################################################################################//
void Uart0Init(void)
{
/*公共屬性設置寄存器*/
ChooseScomMode1();
#if _RATE_ADJUST_EN>0
#if (_BAUD_TIMER>0) //52模式可以選擇T1或T2作為波特率發生器
T2CON|=0x30; //作為波特率發生器RCLK=TCLK=1
//T2MOD|=;
TH2 =_T2_HIGH;
TL2 =_T2_LOW ;
RCAP2H=_T2_HIGH;
RCAP2L=_T2_LOW ;
TR2 = 1;
#else //51模式只能采用T1做波特率發生器
TCON&=0x0f ; //清除標志位
TMOD|=0x20 ; //mode2 BR=(2^smod)*fsoc/(32*12*(MAX-Ti))
TH1 =_T1_HIGH ;
TL1 =_T1_LOW ;
TR1 = 1;
#endif
#endif
RecReady=0;
DataBlockCount=0;
RecUpFlg=0;
UartHead=0xeb;
AllowRx();
OpenScom();
EA=1;
}
//##################################################
//#Function: SendByte
//#Description:51串行口字節發送函數
//#Input: 無
//#Output: 無
//#Return: 無
//#Others: 文件級公共函數
//##################################################
void SendByte(uchar sdata)
{
AllowTx();
TI=0;
SBUF=sdata;
while(!TI);
TI=0;
AllowRx();
}
//##################################################
//#Function: LoginMaster
//#Description:登陸到系統服務器
//#Input: 無
//#Output: 無
//#Return: 無
//#Others: 文件級公共函數
//##################################################
bit LoginMaster(void)
{
bit rel=0;
CallMaster(_CMD_LOG_IN); //發送幀到PC
/*等待PC響應的登陸成功反饋信息*/
DelayTime(2,1000); //等待反饋
if(ProcessFrameTask()==_CMD_ACK) //登陸成功標志
rel=_NET_MODE;
return rel;
}
//##################################################
//#Function: SendFrame(uchar *UartRecBuf,uchar Len)
//#Description:帶上頭對數據進行校驗計算,按協議打包數據發送幀到PC
//#Input: 數據存儲緩沖首地址,數據長度
//#Output: 無
//#Return: 無
//#Others: 文件級公共函數UartRecBuf[0]:Cmd,UartRecBuf[1]:Len
//##################################################
void SendFrame(uchar *UartBuf,uchar Len)
{
uchar nCount;
uint nCrc;
CloseScom();
nCrc=CRCverify(UartBuf,Len);
for(nCount=0;nCount<_F_HEAD_SIZE;nCount++)
SendByte(FrameHead[nCount]); //發送固定的頭
for(nCount=0;nCount<Len;nCount++)
{
SendByte(UartBuf[nCount]); //發送數據
UartBuf[nCount]=0x00; //然后清空單元
}
SendByte(nCrc/256);
SendByte(nCrc%256);
SendByte(_CMD_END); //發送固定尾
OpenScom();
}
//##################################################
//#Function: CallMaster
//#Description:主動呼叫主機發送命令和數據進行通訊
//#Input: 呼叫類型
//#Output: 無
//#Return: 無
//#Others: 文件級公共函數,它負責將要發送的數據整合到緩沖中
//##################################################
void CallMaster(uchar nCmd)
{
uchar nCount;
#if ((_DETECT_TASK>0)&&(_E2PROM_TASK>0))
uchar i;
#endif
CloseScom(); //禁止中斷保護共享緩沖
nCount=0;
UartRecBuf[nCount++]=SlaveAddr; //發送人
UartRecBuf[nCount++]=MasterAddr;
UartRecBuf[nCount++]=nCmd;
switch(nCmd)
{
case _CMD_WR_TEMP: //LENG == 2
#if _DETECT_TASK>0
UartRecBuf[nCount++]=2+_F_EXTRA_LEN;
UartRecBuf[nCount++]=TempInteger;
UartRecBuf[nCount++]=TempDecimal;
UartRecBuf[nCount++]=_F_SINGLE_NUM;
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_HUMI: //LENG == 2
#if _DETECT_TASK>0
UartRecBuf[nCount++]=2+_F_EXTRA_LEN;
UartRecBuf[nCount++]=HumiInteger;
UartRecBuf[nCount++]=HumiDecimal;
UartRecBuf[nCount++]=_F_SINGLE_NUM;
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_TIME: //LENG == 3
#if _CLOCK_TASK>0
ReadClock(ClkLcmBuf);
UartRecBuf[nCount++]=3+_F_EXTRA_LEN;
UartRecBuf[nCount++]=ClkLcmBuf[_ID_HOUR];
UartRecBuf[nCount++]=ClkLcmBuf[_ID_MINUTE];
UartRecBuf[nCount++]=ClkLcmBuf[_ID_SECOND];
UartRecBuf[nCount++]=_F_SINGLE_NUM;
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_ALARM: //該命令目前保留沒有使用
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
break;
case _CMD_WR_DATE: //LENG == 3
#if _CLOCK_TASK>0
ReadClock(ClkLcmBuf);
UartRecBuf[nCount++]=3+_F_EXTRA_LEN;
UartRecBuf[nCount++]=ClkLcmBuf[_ID_YEAR];
UartRecBuf[nCount++]=ClkLcmBuf[_ID_MONTH];
UartRecBuf[nCount++]=ClkLcmBuf[_ID_DAY];
UartRecBuf[nCount++]=_F_SINGLE_NUM;
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_WEEK: //LENG == 1
#if _CLOCK_TASK>0
ReadClock(ClkLcmBuf);
UartRecBuf[nCount++]=1+_F_EXTRA_LEN;
UartRecBuf[nCount++]=ClkLcmBuf[_ID_WEEKLY];
UartRecBuf[nCount++]=_F_SINGLE_NUM;
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_RECORD: //LENG == 10
#if ((_DETECT_TASK>0)&&(_E2PROM_TASK>0))
UartRecBuf[nCount++]=10+_F_EXTRA_LEN;
if(CurRecNum>_MIN_REC_NUM)
{
ReadOneRecord(ClkLcmBuf,CurRecNum); //從24c02中讀一條記錄
for(i=0;i<10;i++)
UartRecBuf[nCount++]=ClkLcmBuf[i];
UartRecBuf[nCount++]=CurRecNum--;
UartRecBuf[nCount++]=CurRecNum; //It's a single frame
}
else
{
for(i=0;i<10;i++)
UartRecBuf[nCount++]=_EMPTY_DATA;
UartRecBuf[nCount++]=_MIN_REC_NUM;
}
WriteOneChar(_CUR_REC_ADDR,CurRecNum); //同步更新計數器單元
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_RECNUM: //LENG == 10
#if ((_DETECT_TASK>0)&&(_E2PROM_TASK>0))
UartRecBuf[nCount++]=1+_F_EXTRA_LEN;
CurRecNum=ReadOneChar(_CUR_REC_ADDR);
UartRecBuf[nCount++]=CurRecNum;
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_MCUID:
#if _SCOM_TASK>0
UartRecBuf[nCount++]=1+_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
SlaveAddr=ReadOneChar(_LOCAL_ID);
UartRecBuf[nCount++]=SlaveAddr; //ReadOneChar(_LOCAL_ID)
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_PCID:
#if _SCOM_TASK>0
UartRecBuf[nCount++]=1+_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
MasterAddr=ReadOneChar(_REMOTE_ID);
UartRecBuf[nCount++]=MasterAddr; //ReadOneChar(_REMOTE_ID)
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#endif
break;
case _CMD_WR_PCUSER: //保留的命令
#if ((_SCOM_TASK>0)&&(_E2PROM_TASK>0))
UartRecBuf[nCount++]=1+_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
//UartRecBuf[nCount++]=MasterUser;
UartRecBuf[nCount++]=ReadOneChar(_REMOTE_USER);
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
#else
UartRecBuf[nCount++]=_F_EXTRA_LEN; //表示數據長度0一個序號和Crc常數
UartRecBuf[nCount++]=_F_SINGLE_NUM; //It's a single frame
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -