⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jbdlp.c

📁 电话PSTN线路上FSK处理软件。。。。。。。。。
💻 C
字号:

/***********************************************************
 *
 *	文件名:	jbDlp.c
 *	功  能:	下载过程主循环及中断服务
 *
 **********************************************************/
//#pragma SRC
//#pragma DEBUG
#include <jbDlp.h>
 
/**********************************************************
 *
 *	函数名:	DlpProgram()
 *	功  能:	下载过程主循环.
 *
 *********************************************************/
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;			
	}
	// 下载过程主循环
}   
// End function: DlpProgram()

/******************************************************
 *
 *	函	数: DlpInit()
 *	说	明: 下载硬件初始化过程.
 *
 *****************************************************/
void DlpInit(void)
{
	byte bdata *Point;
	byte i;
    for(Point=0x20;Point<=0x2f;Point++)		// 清除所有位标志区
        *Point=0;
	if(bDlpReason!=5){						// 进行变量初始化
		TMOD=0x21;
		TH0=L5MS_H;
		TL0=L5MS_L;
		SCON=0x40;
		PCON=0x80;
		cbDelay5MS=30;			// 延时150MS,等待12887稳定
		fDelay5MS=0;
		IP=0x00;				// 所有中断平级,无优先级
	    IT0=0;EX0=0;			// 外部中断0,低电平触发,暂关闭
		IT1=1;EX1=0;			// 外部中断1,下降沿触发,暂关闭
    	TR0=1;ET0=1;			// 定时器0启动,允许中断
    	TR1=0;ET1=0;			// 定时器1停止,中断关闭
		TR2=0;ET2=0;			// 定时器2停止,中断关闭
		REN=0;ES=0;				// 串行口中断关闭
    	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初始化,并置于低功耗状态
	}	
   	EX0=1;						// 开启秒定时中断
	DlpReadData(1,PARA_47,1);
	if(aDataBuf[0]==0x99)
		fWorkMode=1;
	// 依bDlpReason的值,设置bStatusWord状态:
	EA=1;
	iAddress=0;
	cbFangDao=200;
	for(i=0;i<20;i++)
		aLargeBuf[i]=0;
	DlpDispLP();
	if(bDlpReason==2)					// 拨号上呼申请程序
		bStatusWord=S_DLP_UPCALL;		
	else if(bDlpReason==3)				// 直接进入接收下载等待
		bStatusWord=S_DLP_UARTWAIT;		 			
	else if(bDlpReason==4)				// 多次重试呼失败,等待管理机呼入 
		bStatusWord=S_DLP_DOWNCALL;					
	else if(bDlpReason==5){				// 接收程序数据过程
		cbFangDao=0;
		bStatusWord=S_DLP_COMM;					
	}	
}
// End function: DlpInit()

/***********************************************************
 *
 *	函数名:	DlpExit()
 *	功	能:	无错时将Page4中数据写入FLASH,完成后显示OK;
 *			否则显示出错代码,并发出出错提示音
 *
 **********************************************************/
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);
		// 先计算页面4数据缓冲区检验和:		
		DlpPage(4);
		iCheckSum0=0;
		for(i=0x2000,j=0;i!=0;i+=0x100){		
			Point=i+j;
			iCheckSum0+=*Point; 			
 			j++;
		} 	
		// 写数据到FLASH过程:
		Point=0x2000;
		for(i=0;i<0x01c0;i++){
			for(j=0;j<128;j++){		// 取出128字节
				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();
		}	
		// 写入FLASH完成后检验:
		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()

/***************************************************************
 *
 *	函数名:	DlpSecond()		12887的IRQ产生的秒中断
 *			DlpTime0()		CPU内部定时器1中断
 *			DlpUart()		CPU串行口中断
 *			DlpTime1()		CPU内部定时器1中断
 *			DlpTime2()		CPU内部定时器2中断
 *	功  能:	中断服务函数
 *
 **************************************************************/
void DlpSecond(void) using 1
{
	byte bTemp,bPage;
	bPage=P1&0x07;
	DlpPageInt(5);				// 切换到页面5

	if((cbDelaySecond!=0)&&(--cbDelaySecond==0))
		fDelaySecond=1;		

	DlpPageInt(6);
	bTemp=XBYTE[RTC_CONTROLC];	// 读控制寄存器C,取消中断低电平
	DlpPageInt(bPage);			// 恢复进中断时的页面状态
}
// 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){		    // 防盗音发送过程
 		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;			// 设置时间到标志,并关闭12887发声
		DlpPageInt(6);
		XBYTE[RTC_CONTROLA]=0x25;
		XBYTE[RTC_CONTROLB]=0x12;
    }	
	DlpPageInt(5);			    // 切换到页面5
	
	// 等待管理机呼入下载程序时:
	if(bStatusWord==S_DLP_DOWNCALL)
	{
		DlpDetectOnOffHook();	// 检测摘挂机
		DlpDetectRing();		// 检测振铃
	}
	
	if(fWriteFlashRequest)		// 下载程序时,写入FALSH过程
	{	
        fWriteFlashRequest=0;
        TR0=0;
        P1_3=0;
        _nop_();
        _nop_();
        _nop_();
        // 先取出目标地址的128字节数据
        Point1=tWriteFlashAddr&0xff80;
        Point0=&aWriteFlashBuf;
        for(i=0;i<128;i++)			
        {
        	DlpPageInt(bWriteFlashPage);
        	bTemp=*Point1;
        	DlpPageInt(5);
			*Point0=bTemp;
			++Point0; 
			++Point1;
		}
        // 找到相对写入地址,更新缓冲区中欲修该部分数据
        Point1=&sWriteFlashBuf;		
        Point0=&aWriteFlashBuf+(tWriteFlashAddr&0x007f);
   		for(i=0;i<bWriteFlashLen;i++,Point0++,Point1++)
       		*Point0=*Point1;
       	// 将整理好的缓冲区数据写入FLASH存储器中	
        Point1=tWriteFlashAddr&0xff80;		 
        Point0=&aWriteFlashBuf;
        DlpPageInt(0);
        XBYTE[0x5555]=0xaa;			// 打开FLASH写保护
        XBYTE[0x2aaa]=0x55;
        XBYTE[0x5555]=0xa0;
        for(i=0;i<128;i++)
        {
        	DlpPageInt(5);
        	bTemp=*Point0;
        	DlpPageInt(bWriteFlashPage);
        	*Point1=bTemp;
        	Point0++;
        	Point1++;
        }
        DlpPageInt(5);	
        // 延时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);				// 恢复进中断时的页面状态
}
// End function: DlpTime0()

/******************************************************
 *
 *	函	数: DlpUart()
 *	说	明: 串口中断服务程序.
 *
 *****************************************************/
void DlpUart(void) using 1
{
	if(TI){
 		TI=0;
 		fTxDataReady=1;
 	}
 	else{
 		RI=0;
 		fRxDataReady=1;
 		bRecSBUF=SBUF;
 	}
}
// End function: DlpUart()
 
// 下面为两备用中断函数:
void DlpInt1(void) {}
void DlpTime1(void) {}
void DlpTime2(void) {}
 
// 主程序使用的页面切换函数:
void DlpPage(byte bPage)
{
	EA=0;
	P1=(P1&0xf8)|bPage;
	EA=1;
}

// 中断使用的页面切换函数:
void DlpPageInt(byte bPage) using 1
{
	P1=(P1&0xf8)|bPage;
}	
// End function : DlpSetPageInt()

/*************************************************************
 *
 *	函数名:	DlpDetectOnOffHook()
 *	说  明:	下载程序部分检测挂摘机
 *	出	口:	cbLineState>(128+L0):线路处于挂机状态	
 *			cbLineState<(128-L4):线路处于摘机状态
 *
 ************************************************************/
void DlpDetectOnOffHook(void) using 1
{
 	byte bTemp;
 	DlpPageInt(6);
 	bTemp=XBYTE[IN_CE]&0x03;			// 读输入口
 	DlpPageInt(5);
 	if(bTemp==0x00);					// 不定状态,忽略
 	else if(bTemp==0x03)
 	{				
 		if(cbLineState<128)				// OH1、OH2=11 Hook Off
 			cbLineState=128;
 		else if(cbLineState>(128+L0));	// 线路挂机
 		else 
 		    ++cbLineState;
 	}	
 	else
 	{
 		if(cbLineState>128)
 			cbLineState=128;
 		else if(cbLineState<(128-L4));	// 线路摘机
 		else 
 		    --cbLineState;	            
 	}
}	
// End function: DlpDetectOnOffHook()		 		

/*************************************************************
 *
 *	函 数 名:	DlpDetectRing()
 *	说    明:	检测振铃
 *	变量说明:	cbRingTimes:	振铃次数;
 *				cbRingLow: 		OH1低计时,单位5MS,下同;
 *				ciRingHigh:		OH1高计时,双字节宽度;
 *				cbRingPulseNum: 振铃脉冲个数	;	
 *
 *************************************************************/
void DlpDetectRing(void) using 1
{
 	byte bTemp;
 	DlpPageInt(6);
 	bTemp=XBYTE[IN_CE]&0x01;
 	DlpPageInt(5);
    if(bTemp==0x01)
    {								// 检测振铃,OH1=High ,摘机状态
    	cbRingLow=0; 
    	if(++ciRingHigh<9);
    	else if(ciRingHigh<100)
    	{
    		if(cbRingPulseNum<5)	// ciRingHigh==9,及40~45MS时间到
    			cbRingPulseNum=0;
		}    		
    	else if(ciRingHigh<910)
    	{
    		if(cbRingPulseNum>=5)
    		{						// ciRingLow==100,及400MS时间到
    			++cbRingTimes;
    			cbRingPulseNum=0;
    		}	
		}    		 
		else
		{
			ciRingHigh=910;         // HOOK ON
			cbRingTimes=0;
			cbRingPulseNum=0;
		}
    }	
    else
    {           	            	// OH1=LOW 挂机状态。
    	ciRingHigh=0;
    	if(++cbRingLow==2)
    	{
    		if(cbRingPulseNum<5)	
    			++cbRingPulseNum;
		}    		 		
		else if(cbRingLow<9);
    	else
    	{ 
    		cbRingLow=9;	
    		if(cbRingPulseNum<5)
    			cbRingPulseNum=0; 
    	}	
    }
}
// End function: DlpDetectRing()

/***********************************************************
 *
 *	函数名:DlpReadData()
 *	功	能:从FLASH存储器中读出指定参数
 *			存入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()

/**********************************************************************
 *
 *	函数名:	DlpWriteData()
 *	功	能:	将DataBuf中指定长度的数据写入FLASH存储器中
 *				写入过程在DlpTime0中断中进行
 *	入口参数:	bPage:欲写入的页面	
 *				tAddr:欲写入的目标地址
 *				bLen: 欲写入数据的长度(1-256)
 *	全局变量:	fWriteFlashRequest: 写入FLASH请求标志
 *				bWriteFlashPage:	欲写入的页面
 *				tWriteFlashAddr: 	欲写入的目标地址
 *				sWriteFlashBuf[256]:欲写入FLASH数据缓冲区					
 *				bWriteFlashLen: 欲写入数据的长度(1-256)
 *	注	意:		在有严格时间要求的过程中不能调用本函数,执行时间约20MS
 *
 **********************************************************************/
// 暂按128字节页面(SST29EE010/SST29EE020)设计:
void DlpWriteData(byte bPage,uint tAddr, byte bLen)
{
	byte i;
    byte code *Point1;
    byte xdata *Point0;
    DlpPage(4);						// 拷贝写FLASH过程到Page4
    for(Point1=0,Point0=0;Point1<0x0300;Point1++,Point0++)
        *Point0=*Point1;
    DlpPage(5);
	bWriteFlashPage=bPage;				// 设置页面
	tWriteFlashAddr=tAddr;				// 设置目标地址
	for(i=0;i<bLen;i++)
		sWriteFlashBuf[i]=aDataBuf[i];
	bWriteFlashLen=bLen;				// 设置长度
	fWriteFlashRequest=1;				// 开始请求写入
	while(fWriteFlashRequest) IDLE;		// 等待写入完成
}
// End function: DlpWriteData()


//
// End file: jbDlp.c
//
       

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -