?? scominterrupt.c
字號:
/*#######################################################################################//
文件名: ScomInterrupt.c
功能: 串行口232接收中斷服務函數定義
單位: 浙江工商大學-信電學院
創建日期:2004-09-24
創建人: Houseivan
修改人: Houseivan
修改日期:2005-03-11
########################################################################################*/
#include "Includes.h"
/*檢測是否配置了網絡操作功能*/
#if _SCOM_TASK>0
extern uchar data SlaveAddr; //本地主機地址
extern uchar data MasterAddr; //遠程主機地址
//#######################智能溫濕度監控儀串行通訊協議簡要:##############################//
//#數據幀幀頭:0xEB 0x90 0xEB 0x90 0xEB 0x90
//#有效數據塊:主機地址 Datas(數據或命令) 數據長度 FrameNumHigh FrameNumLow CRCHigh CRCLow#
//#數據幀幀尾:0x7E /*SCOM空閑時保持Mark狀態即邏輯'1'*/
//#######################################################################################//
//#######################################################################################//
//#Name : RecUpFlg
//#Purpose : 接收數據結構控制標志標志
//#InitialValue : 0
//#ValueRange : 0->255
//#Used By : 中斷服務函數
//#Notice : 文件級共享
//#######################################################################################//
extern uchar data RecUpFlg;
//#######################################################################################//
//#Name : UartHead
//#Purpose : 幀頭數據存放單元
//#InitialValue : 0
//#ValueRange : 0->255
//#Used By : 中斷服務函數
//#Notice : 文件級共享
//#######################################################################################//
extern uchar data UartHead;
//#######################################################################################//
//#Name : DataBlockCount
//#Purpose : 數據塊長度計數器
//#InitialValue : 0
//#ValueRange : 0->255
//#Used By : 中斷服務函數
//#Notice : 文件級共享
//#######################################################################################//
extern uchar data DataBlockCount;
//#######################################################################################//
//#Name : UpLeng
//#Purpose : 幀實際數據長度單元
//#InitialValue : 0xff
//#ValueRange : 0->255
//#Used By : 中斷服務函數
//#Notice : 文件級共享
//#######################################################################################//
extern uchar data UpLeng;
//#######################################################################################//
//#Name : UartRecBuf
//#Purpose : 串行通訊數據交換緩沖器
//#InitialValue : 0
//#ValueRange : 0->255
//#Used By : 中斷服務函數
//#Notice : 文件級共享
//#######################################################################################//
extern uchar data UartRecBuf[];
#if(_SCOM_TEST>0)
extern uchar data TestCom;
#endif
extern bit RecReady; //正確的數據接收完成標志
//bit FrameFlg=0; //接收到幀標志
/*
UartHead, DataBlockCount, UpLeng, UartRecBuf[], CrcLeng, ParaBuf, SendBuf, WriteE2prom()
*/
//#######################################################################################//
//#######################################################################################//
//#Function: UartService(void)
//#Description: 串口0中斷處理程序(RS485)
//#Input: 無
//#Output: 無
//#Return: 無
//#Others: 文件級公共函數適用于51內核處理器UartHead:頭標志存放單元
/*#使用到的全局變量: 幀由命令和數據構成、有些命令可能不帶任何數據
RecUpFlg-幀結構標志 ; UartHead-幀頭數據存放單元 ;
UpLeng-幀實際數據長度單元 ; UartRecBuf[MaxSize]-串行通訊數據交換緩沖器
DataBlockCount-數據塊長度計數器;
*/
//#######################################################################################//
//_USART0_VECT
void UartService() interrupt _USART0_VECT //由于51的收發中斷地址相同所以在服務函數里最好不要發送
{
uchar UartReg; //UartReg讀端口暫存變量Count:臨時計數器變量
uchar Count;
if(RI) //檢測是否是因為接收到數據產生中斷
{
CloseScom();
RI=0; //清除中斷標志
UartReg=SBUF; //接收一個字符
if(RecUpFlg<7) //當幀結構標志RecUpFlg<10時收到數據才有可能為幀頭
{
if(UartReg==UartHead) //比較是否為幀頭,如果此時幀結構標志為0則認為是頭否則忽略
{ //eb 90 eb 90 eb 90 ... 7e
RecUpFlg++; //接收數據各部分標志字節<0x10表示頭=0x10表示主機地址0x20表示數據
Count=(RecUpFlg&0x0f);
if(Count==0x06) //檢測是否收到六個字節的頭
{
RecUpFlg=0x10; //設定幀數據標志為接收主機地址
}
if (UartHead==0x90) //收到0x90就準備接收0xeb
UartHead=0xeb;
else
UartHead=0x90;
}
else //不等表示該數據不是頭數據而是控制數據
{
RecUpFlg=RecUpFlg&0xf0; //把低位清0
UartHead=0xeb; //恢復通訊模式到初始化模式
}
}
else //0x10之后接收的數據全部為合法數據
{
//檢測接收通訊有效數據
switch(RecUpFlg&0xf0) //根據計數器值來判斷當前幀的數據類型
{
case 0x10: //RecUpFlg=0x10接收主機地址并初始化好接收緩沖器UartRecBuf
UartRecBuf[0]=UartReg; //UartRecBuf將獲取有效數據的第一個字節
RecUpFlg=0x20; //下一個字節開始為有效數據RecUpFlg=0x20即切換到case 0x20
break;
case 0x20: //RecUpFlg=0x10接收主機地址并初始化好接收緩沖器UartRecBuf
UartRecBuf[1]=UartReg; //UartRecBuf將獲取有效數據的第一個字節
DataBlockCount=2; //DataBlockCount有效數據計數器初始化為1
UpLeng=0xff; //數據長度初始化為255
RecUpFlg=0x30; //下一個字節開始為有效數據RecUpFlg=0x20即切換到case 0x20
break;
case 0x30: //接收真正的通訊數據到緩沖器UartRecBuf[]
UartRecBuf[DataBlockCount]=UartReg;
DataBlockCount++; //對有效數據進行計數
UpLeng=UpLeng-1;
switch(UpLeng) //根據UpLeng的值確定數據是否收完
{
case 0: //當UpLeng為0時表示數據幀接收完畢可以對當前幀響應
if( ( ( UartRecBuf[0]==MasterAddr )&&( UartRecBuf[1]==SlaveAddr ) )
||( ( UartRecBuf[0]==_DEFAULT_PC_IP )&&( UartRecBuf[1]==_DEFAULT_MCU_IP ) ) )
{
//if(CRCverify(UartRecBuf,UartRecBuf[3]+_F_RECV_ADD)==0)
RecReady=1;
//SendByte(0x30);
}
else
{
RecReady=0;
RecUpFlg=0;
UartHead=0xeb;
}
break;
case 0xfd: //根據協議規定定位到數長字節并將其復制到UpLeng=UartReg;
UpLeng=UartReg; //收到的第三個有效數據為實際數據長度Len=253+3+UartReg=UartReg
break;
default:
break;
} //switch(UpLeng)
break; //case 0x30
default:
break;
} //switch(RecUpFlg&0xf0)
} //if(RecUpFlg<10)
OpenScom();
}
}
//#######################################################################################//
//#######################################################################################//
#endif //#ifdef _SCOM_EN
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -