?? jbdcomm.c
字號:
/***********************************************************
*
* 文件名: jbDComm.c
* 功 能: 存放有關下載通信的函數
*
**********************************************************/
//#pragma SRC
//#pragma DEBUG
#include <jbdcomm.h>
/********************************************************************
*
* 函數名:DlpUartWait()
* 功 能:串口等待接收下載程序命令過程
* 入 口: 當應用程序部分壞時,按K234鍵開機可進入本過程.
*
*******************************************************************/
void DlpUartWait(void)
{
SCON=0x40; // 串口工作模式1,8位UART
TH1=L9600; // 串口9600BPS定時常數
TL1=L9600;
TR1=1;
ES=1;
REN=1; // 打開串口中斷
TI=0;
RI=0;
fRxDataReady=0;
fTxDataReady=0;
DlpDispClr(); // 清除顯示器
DlpDispLP();
DlpDispSymbol(LARGE_COMM); // 顯示"通信"標志提示
while(TRUE){
fFirstCmd=1;
if(!DlpRxCmd())
continue;
fFirstCmd=0;
if(bRecSBUF!=0x81)
continue;
DlpDispSymbol(LARGE_FLASH);
if(!DlpQueryVersion())
break;
DlpDispCmd(bRecSBUF);
bStatusWord=S_DLP_COMM;
return;
} // End while(TRUE)
bStatusWord=S_DLP_EXIT;
return;
}
// End function: DlpUartWait()
/**********************************************************
*
* 函 數: DlpDownCall()
* 說 明: 自檢應用程序錯,重試呼次數到后進入等待管理機呼入
* 下載程序過程.
*
**********************************************************/
void DlpDownCall(void)
{
byte i,bBuf;
iAddress=0;
DlpDispErrorCode(ERR_25);
DlpDispLP();
DlpOpen(RLY);
while(1){
IDLE;
cbRingTimes=0;
cbRingPulseNum=0;
while(TRUE){
IDLE;
if(cbRingTimes==3)
break;
if(cbLineState<(128-L4)){ // 若檢測到線路摘機
if((cbRingTimes!=0)||(cbRingPulseNum>=5))
break; // 手動摘機
}
}
DlpOpen(MLD);
DlpDelay5MS(2);
DlpClose(RLY);
if(DlpDetectConnectTone(2)){
DlpSpeaker(50);
break;
}
DlpOpen(RLY);
DlpClose(MLD);
} // End first while(TRUE)
cbFangDao=0;
bErrorCode=ERR_NO;
while(TRUE){
if(!DlpConnectModem()){
bErrorCode=ERR_01;
break;
}
for(i=0;i<11;i++)
aLargeBuf[i]=0;
DlpDispSymbol(LARGE_COMM);
DlpDelay5MS(200);
DlpTxCmd(OK);
for(i=0,bBuf=0;i<17;i++){
if(!DlpRxByte())
break;
if(i<16)
bBuf+=bRecSBUF;
}
if(bErrorCode!=ERR_NO)
break;
if(bBuf==bRecSBUF){
bErrorCode=ERR_32; // 系統模式錯誤
break;
}
if(bBuf!=~bRecSBUF){
DlpTxByte(0xcc);
DlpTxByte(0xdd);
bErrorCode=ERR_31;
break;
}
DlpTxCmd(OK);
if(!DlpRxByte())
break;
bBuf=bRecSBUF;
if(!DlpRxByte())
break;
if((bRecSBUF!=0xbb)||((bBuf!=0x88)&&(bBuf!=0x99))){
bErrorCode=ERR_31;
break;
}
DlpTxCmd(OK);
if(!DlpDynamicPassword())
break;
if(!DlpRxCmd())
break;
if(bRecSBUF!=QUERY_VERSION){
bErrorCode=ERR_05;
break;
}
if(!DlpQueryVersion())
break;
bStatusWord=S_DLP_COMM;
return;
}
bStatusWord=S_DLP_EXIT;
return;
}
// End function: DlpDownCall()
/**********************************************************
*
* 函數名:DlpComm()
* 功 能:程序下載數據接收過程.
*
*********************************************************/
void DlpComm(void)
{
EA=1;
DlpDispSymbol(LARGE_COMM);
while(TRUE){
DlpTxCmd(OK); // 應答上一條命令
if(!DlpRxPaNe())
break;
if((bPaBuf!=0x01)||(bNeBuf!=0xc0)){
bErrorCode=ERR_05;
break;
}
iPaNeNum=((uint)bPaBuf<<8)+bNeBuf;
bNeBuf=0;
if(iPaNeNum>255)
bPaBuf=255;
else
bPaBuf=iPaNeNum;
if(!DlpRxData(0x2000))
break;
if(iPaNeNum<=255)
break;
bPaBuf=(byte)(iPaNeNum-255);
if(!DlpRxData(0x2000+255*128))
break;
DlpTxCmd(OK);
if(!DlpRxCmd())
break;
if(bRecSBUF!=END){
bErrorCode=ERR_05;
break;
}
bErrorCode=ERR_NO;
break;
}
bStatusWord=S_DLP_EXIT;
}
// End function: DlpComm()
//
// 下為通信過程中用到的底層函數:
//
/**********************************************************
*
* 函數名:DlpDial()
* 功 能:自檢出錯或手動呼叫管理機的撥號過程
* 出 口:聯絡成功,返回TRUE;
* 出錯或聯絡失敗,返回FALSE。
*
********************************************************/
bool DlpDial(void)
{
byte i,j,bTemp;
byte bRecallTimes=3;
fDialForm=0;
cbFangDao=0;
if(!fWorkMode){
DlpPage(1);
i=XBYTE[PARA_211];
DlpPage(5);
if((i&0x40)!=0)
fDialForm=1;
DlpReadData(1,PARA_202,4);
for(i=4;i<8;i++)
aDataBuf[i]=0xcc;
}
else{
DlpPage(1);
i=XBYTE[PARA_13];
DlpPage(5);
if(i!=0)
fDialForm=1;
DlpReadData(1,PARA_01,8);
}
for(i=0;i<8;i++){
aNumBuf[2*i]=aDataBuf[i]>>4;
aNumBuf[2*i+1]=aDataBuf[i]&0x0f;
}
DlpDispClr();
DlpDispSymbol(LARGE_HOOK);
DlpClose(RLY);
do{
DlpClose(POWER_ON);
DlpDispClr();
DlpDispLP();
DlpDispSymbol(LARGE_PHONE);
DlpClose(MLD);
DlpDelaySecond(3); // 掛機3秒
DlpOpen(MLD);
DlpDispSymbol(LARGE_HOOK);
MD_CLK=0;
DlpDelaySecond(2);
DlpOpen(POWER_ON);
if(fDialForm){
DlpWriteModem(CR1,0x00);
DlpWriteModem(CR0,0x1a);
}
for(i=0;i<16;i++) // 撥號
{
bTemp=aNumBuf[i];
if(bTemp==0x0c)
break;
if(i<11)
aLargeBuf[i]=aDlpLCDSegment[bTemp];
DlpDispSymbol(LARGE_HOOK);
bTemp=aNumBuf[i];
if(bTemp>9)
break;
else if(bTemp==0)
bTemp=0x0a;
if(fDialForm){
DlpWriteModem(TR,bTemp);
DlpWriteModem(CR0,0x1a);
bTemp=DlpModemRead(TR);
DlpWriteModem(TR,(bTemp|0x10));
DlpDelay5MS(21);
bTemp=DlpModemRead(TR);
DlpWriteModem(TR,(bTemp&0xef));
DlpWriteModem(CR0,0x00);
DlpDelay5MS(10);
}
else{ // 脈沖撥號方式
for(j=0;j<bTemp;j++){
DlpClose(MLD);
DlpDelay5MS(13);
DlpOpen(MLD);
DlpDelay5MS(7);
}
DlpDelay5MS(80);
}
cbDelay5MS=5; // 發模擬撥號音
fDelay5MS=FALSE;
DlpPage(6);
XBYTE[0xc00b]=0x1a;
DlpPage(5);
while(!fDelay5MS) IDLE;
}
MD_CLK=1;
DlpWriteModem(CR1,0x00);
if(DlpDetectConnectTone(20)) // 檢測通信聯絡音'D'
return TRUE;
}while(--bRecallTimes!=0);
bFailTimes=6;
return FALSE;
}
// End function: DlpDial()
/*******************************************************************
*
* 函數名:DlpUpCall()
* 功 能:計費器自檢出錯時,主動呼叫管理機要求下載程序.
*
******************************************************************/
void DlpUpCall(void)
{
byte bBuf;
while(TRUE){
IDLE;
if(!DlpDial()){
bErrorCode=ERR_00;
break;
}
if(!DlpConnectModem()){
bErrorCode=ERR_01;
break;
}
DlpDispSymbol(LARGE_COMM);
if(!DlpRxCmd())
break;
if(bRecSBUF!=OK){
bErrorCode=ERR_05;
break;
}
if(!DlpSendTelNum(1))
break;
if(!DlpRxByte())
break;
bBuf=bRecSBUF;
if(!DlpRxByte())
break;
if((bBuf==END)&&(bBuf==~bRecSBUF)){
bErrorCode=ERR_21;
break;
}
if((bBuf==ERR_CS)&&(bBuf==~bRecSBUF)){
bErrorCode=ERR_32;
break;
}
if((bRecSBUF!=0xbb)||((bBuf!=0x88)&&(bBuf!=0x99))){
DlpTxByte(0xcc);
DlpTxByte(0xdd);
bErrorCode=ERR_31;
break;
}
if(!DlpSendTelNum(0))
break;
if(!DlpQueryVersion())
break;
bStatusWord=S_DLP_COMM;
return;
}
bStatusWord=S_DLP_EXIT;
return;
}
// End function: DlpUpCall()
/*******************************************************************
*
* 函數名:DlpDetectConnectTone()
* 功 能:檢測通信聯絡音D...(約300MS)
* 輸 入:bSecond:指定延時等待的時間,秒計數
*
******************************************************************/
bool DlpDetectConnectTone(byte bSecond)
{
byte bTemp;
cbDelaySecond=bSecond;
fDelaySecond=FALSE;
DlpResetModem();
while(TRUE){
IDLE;
if(fDelaySecond)
return FALSE;
DlpPage(6);
bTemp=XBYTE[IN_CE];
DlpPage(5);
if((bTemp&0x04)==0) // 測試DV引腳
continue;
DlpPage(7);
bTemp=XBYTE[DTMF_ENB]; // 讀DTMF值
DlpPage(5);
if((bTemp&0x0f)==0){
DlpDispSymbol(LARGE_FLASH);
return TRUE;
}
}
}
// End function: DlpDetectConnectTone()
/*******************************************************************
*
* 函數名:DlpConnectModem()
* 功 能:計費器MODEM與管理系統MODEM卡的聯絡過程
* 用 途:管理機下傳和計費器上呼時
* 注 意:計費器MODEM處于應答模式,管理系統MODEM處于發起模式
* 發GUARD TONE可能會干擾通信過程
*
******************************************************************/
bool DlpConnectModem(void)
{
byte bTemp;
bool fSelect=0;
EX0=1;
MD_CLK=0;
DlpDelay5MS(4);
if(fSelect){ //300 bps
DlpWriteModem(CR1,0x04);
DlpWriteModem(CR0,0xb2);
DlpWriteModem(TR,0x00);
DlpWriteModem(CR1,0x10);
cbDelaySecond=4;
fDelaySecond=0;
while(1){
if(fDelaySecond)
return 0;
bTemp=DlpModemRead(DR);
if((bTemp&0x08)!=0){
DlpDelay5MS(96);
TH1=L300;
TL1=L300;
break;
}
}
}
else{ //1200 bps
DlpWriteModem(CR1,0x04);
DlpDelaySecond(2);
DlpDelay5MS(32);
DlpWriteModem(CR1,0x04);
DlpWriteModem(TR,0xa1);
DlpWriteModem(CR0,0x1a);
DlpWriteModem(CR1,0x90);
DlpDelaySecond(3);
DlpDelay5MS(60);
DlpWriteModem(CR0,0x18);
DlpDelay5MS(16);
DlpWriteModem(TR,0xc0);
DlpWriteModem(CR1,0x90);
DlpWriteModem(CR0,0x1a);
DlpDelay5MS(80);
cbDelaySecond=2;
fDelaySecond=0;
while(1){
if(fDelaySecond)
return FALSE;
bTemp=DlpModemRead(DR);
if((bTemp&0x08)!=0){
DlpWriteModem(CR1,0x80);
DlpDelay5MS(136);
DlpWriteModem(TR,0x40);
DlpWriteModem(CR1,0x00);
TH1=L1200;
TL1=L1200;
break;
}
}
}
EX1=0;
TI=0;
RI=0;
TR1=1;
REN=1;
ES=1;
bLastCmd=0xff;
fRxDataReady=0;
fTxDataReady=0;
return TRUE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -