?? jbdlp.c
字號(hào):
/***********************************************************
*
* 文件名: jbDlp.c
* 功 能: 下載過(guò)程主循環(huán)及中斷服務(wù)
*
**********************************************************/
//#pragma SRC
//#pragma DEBUG
#include <jbDlp.h>
/**********************************************************
*
* 函數(shù)名: DlpProgram()
* 功 能: 下載過(guò)程主循環(huán).
*
*********************************************************/
void DlpProgram(void)
{
bErrorCode=ERR_NO;
bStatusWord=S_DLP_INIT;
while(TRUE){
if(bStatusWord==S_DLP_INIT)
DlpInit();
else if(bStatusWord==S_DLP_UPCALL)
DlpUpCall();
else if(bStatusWord==S_DLP_DOWNCALL)
DlpDownCall();
else if(bStatusWord==S_DLP_UARTWAIT)
DlpUartWait();
else if(bStatusWord==S_DLP_COMM)
DlpComm();
else if(bStatusWord==S_DLP_EXIT)
DlpExit();
else if(bStatusWord==TO_INIT){
if(((bFailTimes>2)&&(bFailTimes<10))||(bDlpReason==4)){
if(CheckProgramSum()){
bDlpReason=TO_INIT; //
return;
}
bDlpReason=4;
bStatusWord=S_DLP_DOWNCALL;
}
else if((bFailTimes!=0)&&(bDlpReason==2))
bStatusWord=S_DLP_INIT;
else{
bDlpReason=TO_INIT; //
return;
}
}
else
break;
}
// 下載過(guò)程主循環(huán)
}
// End function: DlpProgram()
/******************************************************
*
* 函 數(shù): DlpInit()
* 說(shuō) 明: 下載硬件初始化過(guò)程.
*
*****************************************************/
void DlpInit(void)
{
byte bdata *Point;
byte i;
for(Point=0x20;Point<=0x2f;Point++) // 清除所有位標(biāo)志區(qū)
*Point=0;
if(bDlpReason!=5){ // 進(jìn)行變量初始化
TMOD=0x21;
TH0=L5MS_H;
TL0=L5MS_L;
SCON=0x40;
PCON=0x80;
cbDelay5MS=30; // 延時(shí)150MS,等待12887穩(wěn)定
fDelay5MS=0;
IP=0x00; // 所有中斷平級(jí),無(wú)優(yōu)先級(jí)
IT0=0;EX0=0; // 外部中斷0,低電平觸發(fā),暫關(guān)閉
IT1=1;EX1=0; // 外部中斷1,下降沿觸發(fā),暫關(guān)閉
TR0=1;ET0=1; // 定時(shí)器0啟動(dòng),允許中斷
TR1=0;ET1=0; // 定時(shí)器1停止,中斷關(guān)閉
TR2=0;ET2=0; // 定時(shí)器2停止,中斷關(guān)閉
REN=0;ES=0; // 串行口中斷關(guān)閉
while(!fDelay5MS) IDLE;
cbDelay5MS=80;
fDelay5MS=FALSE;
DlpPage(6); // 12887 initial
XBYTE[RTC_CONTROLA]=0x27;
XBYTE[RTC_CONTROLB]=0x1a;
DlpPage(5);
DlpDispInit(); // 顯示初始化
DlpDispClr();
DlpResetModem(); // CML644A初始化,并置于低功耗狀態(tài)
}
EX0=1; // 開(kāi)啟秒定時(shí)中斷
DlpReadData(1,PARA_47,1);
if(aDataBuf[0]==0x99)
fWorkMode=1;
// 依bDlpReason的值,設(shè)置bStatusWord狀態(tài):
EA=1;
iAddress=0;
cbFangDao=200;
for(i=0;i<20;i++)
aLargeBuf[i]=0;
DlpDispLP();
if(bDlpReason==2) // 撥號(hào)上呼申請(qǐng)程序
bStatusWord=S_DLP_UPCALL;
else if(bDlpReason==3) // 直接進(jìn)入接收下載等待
bStatusWord=S_DLP_UARTWAIT;
else if(bDlpReason==4) // 多次重試呼失敗,等待管理機(jī)呼入
bStatusWord=S_DLP_DOWNCALL;
else if(bDlpReason==5){ // 接收程序數(shù)據(jù)過(guò)程
cbFangDao=0;
bStatusWord=S_DLP_COMM;
}
}
// End function: DlpInit()
/***********************************************************
*
* 函數(shù)名: DlpExit()
* 功 能: 無(wú)錯(cuò)時(shí)將Page4中數(shù)據(jù)寫(xiě)入FLASH,完成后顯示OK;
* 否則顯示出錯(cuò)代碼,并發(fā)出出錯(cuò)提示音
*
**********************************************************/
void DlpExit(void)
{
uint i;
uint iCheckSum0,iCheckSum1;
byte j,bTemp;
byte xdata *Point;
byte code *Point0;
while(TRUE){
if(bErrorCode!=ERR_NO){
if((bErrorCode>0x03)&&(bErrorCode<0x09))
DlpTxCmd(END);
DlpDispErrorCode(bErrorCode);
break;
}
DlpSpeaker(40);
while(!fDelay5MS) IDLE;
DlpOpen(POWER_ON);
// 先計(jì)算頁(yè)面4數(shù)據(jù)緩沖區(qū)檢驗(yàn)和:
DlpPage(4);
iCheckSum0=0;
for(i=0x2000,j=0;i!=0;i+=0x100){
Point=i+j;
iCheckSum0+=*Point;
j++;
}
// 寫(xiě)數(shù)據(jù)到FLASH過(guò)程:
Point=0x2000;
for(i=0;i<0x01c0;i++){
for(j=0;j<128;j++){ // 取出128字節(jié)
DlpPage(4);
bTemp=*Point;
DlpPage(5);
Point++;
aDataBuf[j]=bTemp;
}
DlpWriteData(0,Point-128,128);
iAddress--;
j=iAddress;
if((j&0x0f)==0x0f)
iAddress-=6;
j=iAddress;
if((j&0xf0)==0xf0)
iAddress-=0x60;
DlpDispLP();
}
// 寫(xiě)入FLASH完成后檢驗(yàn):
DlpPage(0);
iCheckSum1=0;
for(i=0x2000,j=0;i!=0;i+=0x100){
Point0=i+j;
iCheckSum1+=*Point0;
j++;
}
DlpPage(5);
if(iCheckSum0!=iCheckSum1){
bErrorCode=ERR_23;
DlpDispErrorCode(bErrorCode);
break;
}
aDataBuf[0]=(byte)(iCheckSum1>>8);
aDataBuf[1]=(byte)(iCheckSum1&0x00ff);
DlpWriteData(1,PROGRAM_CHECKSUM_ADDR,2);
DlpDelay5MS(50);
bDlpReason=TO_INIT;
bFailTimes=0;
DlpDispOK(3);
break;
}
DlpClose(MLD);
DlpOpen(RLY);
DlpResetModem();
//DlpWriteModem(SET_UP,0);
DlpClose(POWER_ON);
cbFangDao=200;
if((bErrorCode!=ERR_NO)&&(bDlpReason==2))
bFailTimes++;
if(bErrorCode==ERR_34)
bFailTimes=4;
bStatusWord=TO_INIT;
}
// End function: DlpExit()
/***************************************************************
*
* 函數(shù)名: DlpSecond() 12887的IRQ產(chǎn)生的秒中斷
* DlpTime0() CPU內(nèi)部定時(shí)器1中斷
* DlpUart() CPU串行口中斷
* DlpTime1() CPU內(nèi)部定時(shí)器1中斷
* DlpTime2() CPU內(nèi)部定時(shí)器2中斷
* 功 能: 中斷服務(wù)函數(shù)
*
**************************************************************/
void DlpSecond(void) using 1
{
byte bTemp,bPage;
bPage=P1&0x07;
DlpPageInt(5); // 切換到頁(yè)面5
if((cbDelaySecond!=0)&&(--cbDelaySecond==0))
fDelaySecond=1;
DlpPageInt(6);
bTemp=XBYTE[RTC_CONTROLC]; // 讀控制寄存器C,取消中斷低電平
DlpPageInt(bPage); // 恢復(fù)進(jìn)中斷時(shí)的頁(yè)面狀態(tài)
}
// End function: DlpSecond()
void DlpTime0(void) using 1
{
byte i,j;
byte bTemp,bPage;
byte xdata *Point0;
byte xdata *Point1;
TH0=L5MS_H;
TL0=L5MS_L;
bPage=P1&0x07;
if(cbFangDao<150){ // 防盜音發(fā)送過(guò)程
if(++cbFangDao<9)
OutBuf&=0x7f;
else if(cbFangDao<129)
OutBuf|=0x80;
else
cbFangDao=0;
}
else
OutBuf|=0x80;
DlpPageInt(6);
XBYTE[OUT_CE]=OutBuf; // 片選有效
if((cbDelay5MS!=0)&&(--cbDelay5MS==0))
{
fDelay5MS=1; // 設(shè)置時(shí)間到標(biāo)志,并關(guān)閉12887發(fā)聲
DlpPageInt(6);
XBYTE[RTC_CONTROLA]=0x25;
XBYTE[RTC_CONTROLB]=0x12;
}
DlpPageInt(5); // 切換到頁(yè)面5
// 等待管理機(jī)呼入下載程序時(shí):
if(bStatusWord==S_DLP_DOWNCALL)
{
DlpDetectOnOffHook(); // 檢測(cè)摘掛機(jī)
DlpDetectRing(); // 檢測(cè)振鈴
}
if(fWriteFlashRequest) // 下載程序時(shí),寫(xiě)入FALSH過(guò)程
{
fWriteFlashRequest=0;
TR0=0;
P1_3=0;
_nop_();
_nop_();
_nop_();
// 先取出目標(biāo)地址的128字節(jié)數(shù)據(jù)
Point1=tWriteFlashAddr&0xff80;
Point0=&aWriteFlashBuf;
for(i=0;i<128;i++)
{
DlpPageInt(bWriteFlashPage);
bTemp=*Point1;
DlpPageInt(5);
*Point0=bTemp;
++Point0;
++Point1;
}
// 找到相對(duì)寫(xiě)入地址,更新緩沖區(qū)中欲修該部分?jǐn)?shù)據(jù)
Point1=&sWriteFlashBuf;
Point0=&aWriteFlashBuf+(tWriteFlashAddr&0x007f);
for(i=0;i<bWriteFlashLen;i++,Point0++,Point1++)
*Point0=*Point1;
// 將整理好的緩沖區(qū)數(shù)據(jù)寫(xiě)入FLASH存儲(chǔ)器中
Point1=tWriteFlashAddr&0xff80;
Point0=&aWriteFlashBuf;
DlpPageInt(0);
XBYTE[0x5555]=0xaa; // 打開(kāi)FLASH寫(xiě)保護(hù)
XBYTE[0x2aaa]=0x55;
XBYTE[0x5555]=0xa0;
for(i=0;i<128;i++)
{
DlpPageInt(5);
bTemp=*Point0;
DlpPageInt(bWriteFlashPage);
*Point1=bTemp;
Point0++;
Point1++;
}
DlpPageInt(5);
// 延時(shí)10MS
i=10;j=50;
do
{
do
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}while(--j!=0);
j=50;
}while(--i!=0);
P1_3=1;
_nop_();
_nop_();
_nop_();
TR0=1;
} // End if(fWriteFlashRequest)
DlpPageInt(bPage); // 恢復(fù)進(jìn)中斷時(shí)的頁(yè)面狀態(tài)
}
// End function: DlpTime0()
/******************************************************
*
* 函 數(shù): DlpUart()
* 說(shuō) 明: 串口中斷服務(wù)程序.
*
*****************************************************/
void DlpUart(void) using 1
{
if(TI){
TI=0;
fTxDataReady=1;
}
else{
RI=0;
fRxDataReady=1;
bRecSBUF=SBUF;
}
}
// End function: DlpUart()
// 下面為兩備用中斷函數(shù):
void DlpInt1(void) {}
void DlpTime1(void) {}
void DlpTime2(void) {}
// 主程序使用的頁(yè)面切換函數(shù):
void DlpPage(byte bPage)
{
EA=0;
P1=(P1&0xf8)|bPage;
EA=1;
}
// 中斷使用的頁(yè)面切換函數(shù):
void DlpPageInt(byte bPage) using 1
{
P1=(P1&0xf8)|bPage;
}
// End function : DlpSetPageInt()
/*************************************************************
*
* 函數(shù)名: DlpDetectOnOffHook()
* 說(shuō) 明: 下載程序部分檢測(cè)掛摘機(jī)
* 出 口: cbLineState>(128+L0):線路處于掛機(jī)狀態(tài)
* cbLineState<(128-L4):線路處于摘機(jī)狀態(tài)
*
************************************************************/
void DlpDetectOnOffHook(void) using 1
{
byte bTemp;
DlpPageInt(6);
bTemp=XBYTE[IN_CE]&0x03; // 讀輸入口
DlpPageInt(5);
if(bTemp==0x00); // 不定狀態(tài),忽略
else if(bTemp==0x03)
{
if(cbLineState<128) // OH1、OH2=11 Hook Off
cbLineState=128;
else if(cbLineState>(128+L0)); // 線路掛機(jī)
else
++cbLineState;
}
else
{
if(cbLineState>128)
cbLineState=128;
else if(cbLineState<(128-L4)); // 線路摘機(jī)
else
--cbLineState;
}
}
// End function: DlpDetectOnOffHook()
/*************************************************************
*
* 函 數(shù) 名: DlpDetectRing()
* 說(shuō) 明: 檢測(cè)振鈴
* 變量說(shuō)明: cbRingTimes: 振鈴次數(shù);
* cbRingLow: OH1低計(jì)時(shí),單位5MS,下同;
* ciRingHigh: OH1高計(jì)時(shí),雙字節(jié)寬度;
* cbRingPulseNum: 振鈴脈沖個(gè)數(shù) ;
*
*************************************************************/
void DlpDetectRing(void) using 1
{
byte bTemp;
DlpPageInt(6);
bTemp=XBYTE[IN_CE]&0x01;
DlpPageInt(5);
if(bTemp==0x01)
{ // 檢測(cè)振鈴,OH1=High ,摘機(jī)狀態(tài)
cbRingLow=0;
if(++ciRingHigh<9);
else if(ciRingHigh<100)
{
if(cbRingPulseNum<5) // ciRingHigh==9,及40~45MS時(shí)間到
cbRingPulseNum=0;
}
else if(ciRingHigh<910)
{
if(cbRingPulseNum>=5)
{ // ciRingLow==100,及400MS時(shí)間到
++cbRingTimes;
cbRingPulseNum=0;
}
}
else
{
ciRingHigh=910; // HOOK ON
cbRingTimes=0;
cbRingPulseNum=0;
}
}
else
{ // OH1=LOW 掛機(jī)狀態(tài)。
ciRingHigh=0;
if(++cbRingLow==2)
{
if(cbRingPulseNum<5)
++cbRingPulseNum;
}
else if(cbRingLow<9);
else
{
cbRingLow=9;
if(cbRingPulseNum<5)
cbRingPulseNum=0;
}
}
}
// End function: DlpDetectRing()
/***********************************************************
*
* 函數(shù)名:DlpReadData()
* 功 能:從FLASH存儲(chǔ)器中讀出指定參數(shù)
* 存入aDataBuf[].
* 入 口: bLen<=255;
*
**********************************************************/
void DlpReadData(byte bPage,uint sAddr, byte bLen)
{
byte i,bTemp;
byte xdata *tPoint;
tPoint=&aDataBuf;
for(i=0;i<bLen;i++,sAddr++,tPoint++)
{
DlpPage(bPage);
bTemp=XBYTE[sAddr];
DlpPage(5);
*tPoint=bTemp;
}
}
// End function: DlpReadData()
/**********************************************************************
*
* 函數(shù)名: DlpWriteData()
* 功 能: 將DataBuf中指定長(zhǎng)度的數(shù)據(jù)寫(xiě)入FLASH存儲(chǔ)器中
* 寫(xiě)入過(guò)程在DlpTime0中斷中進(jìn)行
* 入口參數(shù): bPage:欲寫(xiě)入的頁(yè)面
* tAddr:欲寫(xiě)入的目標(biāo)地址
* bLen: 欲寫(xiě)入數(shù)據(jù)的長(zhǎng)度(1-256)
* 全局變量: fWriteFlashRequest: 寫(xiě)入FLASH請(qǐng)求標(biāo)志
* bWriteFlashPage: 欲寫(xiě)入的頁(yè)面
* tWriteFlashAddr: 欲寫(xiě)入的目標(biāo)地址
* sWriteFlashBuf[256]:欲寫(xiě)入FLASH數(shù)據(jù)緩沖區(qū)
* bWriteFlashLen: 欲寫(xiě)入數(shù)據(jù)的長(zhǎng)度(1-256)
* 注 意: 在有嚴(yán)格時(shí)間要求的過(guò)程中不能調(diào)用本函數(shù),執(zhí)行時(shí)間約20MS
*
**********************************************************************/
// 暫按128字節(jié)頁(yè)面(SST29EE010/SST29EE020)設(shè)計(jì):
void DlpWriteData(byte bPage,uint tAddr, byte bLen)
{
byte i;
byte code *Point1;
byte xdata *Point0;
DlpPage(4); // 拷貝寫(xiě)FLASH過(guò)程到Page4
for(Point1=0,Point0=0;Point1<0x0300;Point1++,Point0++)
*Point0=*Point1;
DlpPage(5);
bWriteFlashPage=bPage; // 設(shè)置頁(yè)面
tWriteFlashAddr=tAddr; // 設(shè)置目標(biāo)地址
for(i=0;i<bLen;i++)
sWriteFlashBuf[i]=aDataBuf[i];
bWriteFlashLen=bLen; // 設(shè)置長(zhǎng)度
fWriteFlashRequest=1; // 開(kāi)始請(qǐng)求寫(xiě)入
while(fWriteFlashRequest) IDLE; // 等待寫(xiě)入完成
}
// End function: DlpWriteData()
//
// End file: jbDlp.c
//
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -