📄 jbapi.c
字号:
/**************************************************************
*
* 文 名: jbApi.c
* 内 容: 含所有断服务程序
*
**************************************************************/
//#pragma SRC
//#pragma DEBUG
#include <jbApi.h>
/************************************************************
*
* 函数名: _ApiSecond()、ApiSecond
* 说 明: JJF24-1B型计费器秒定时中断
* 处理日常折扣时间、备用费率切换时间、通话计时。
*
************************************************************/
void _ApiSecond(void)
{
Api_Second();
}
void Api_Second(void) using 1
{
byte bTemp;
byte bPage;
bPage=P1&0x07;
SetPageInt(5); // 设置缺省页面值
if((cbDelaySecond!=0)&&(--cbDelaySecond==0))
fDelaySecond=1;
if((ciDelaySecond!=0)&&(--ciDelaySecond==0))
fiDelaySecond=1;
if((ciiDelaySecond!=0)&&(--ciiDelaySecond==0))
fiiDelaySecond=1;
fSecond=1;
// 存储当前时间:年、月、日、时、分
SetPageInt(6);
if((bStatusWord>=S_OLDPARAINIT)&&(bStatusWord<=S_NEWSLAVECALL)){
aUserRTCBuf[YEARH] =0x20;
aUserRTCBuf[YEARL] =XBYTE[0xc009];
aUserRTCBuf[MONTH] =XBYTE[0xc008];
aUserRTCBuf[DAY] =XBYTE[0xc007];
//aUserRTCBuf[WEEK] =XBYTE[0xc006];
aUserRTCBuf[HOUR] =XBYTE[0xc004];
aUserRTCBuf[MINUTE]=XBYTE[0xc002];
aUserRTCBuf[SECOND]=XBYTE[0xc000];
//lmt add 2001.3.13
XBYTE[EndTimeAddress]=aUserRTCBuf[HOUR]; //存储当班关机时间
XBYTE[EndTimeAddress+1]=aUserRTCBuf[MINUTE];
XBYTE[EndTimeAddress+2]=aUserRTCBuf[SECOND];
if((aUserRTCBuf[MONTH]!=XBYTE[0xc02c])
||(aUserRTCBuf[DAY]!=XBYTE[0xc02d]))
fDateUpdate=1;
}
bTemp=XBYTE[RTC_CONTROLC]; // 取消12887中断
SetPageInt(bPage);
}
// End function: ApiSecond()
/*************************************************************
*
* 函 数: _ApiTime0()、ApiTime0()
* 说 明: JJF24-1B型计费器5MS定时
* 实现按键检测、摘挂机检测、振铃检测及拨号检测。
* 及写FLASH过程.
*
************************************************************/
void _ApiTime0(void)
{
Api_Time0();
}
void Api_Time0(void) using 1
{
byte bPage;
byte i,j,bTemp;
byte xdata *Point0;
byte xdata *Point1;
TH0=L5MS_H; // 主频为11.0592MHZ,5MS定时常数
TL0=L5MS_L;
if((cbDelay5MS!=0)&&(--cbDelay5MS==0)){
fDelay5MS=1;
}
if(fTxFSKStart)
return;
bPage=P1&0x07;
SetPageInt(6);
if((cbDelay5MS!=0)&&(--cbDelay5MS==0)){
fDelay5MS=1;
// XBYTE[RTC_CONTROLA]=0x25; // 关闭声音
// XBYTE[RTC_CONTROLB]=0x12;
}
/*
if(cbFangDao<150){ // 防盗音发送过程
if(++cbFangDao<9)
OutBuf&=0x7f;
else if(cbFangDao<129)
OutBuf|=0x80;
else
cbFangDao=0;
}
else
*/
OutBuf|=0x80;
if(fLockRequest){ // 自动锁机过程
fLockContinue=1;
fLockRequest=0;
cbLockTime=L6;
OutBuf&=0xfd; // 吸合继电器
OutBuf&=0xef; // 取消模拟负载
}
else if(fLockContinue){
if(--cbLockTime==0){
fLockContinue=0;
OutBuf|=0x02; // 断开继电器
}
}
XBYTE[OUT_CE]=OutBuf; // 写入控制字
InBuf=XBYTE[IN_CE];
SetPageInt(5);
if(fWriteFlashRequest&&(bWriteFlashPage!=0)){ // 写FLASH过程
EA=0; // 关闭全局中断
fWriteFlashRequest=0;
TR0=0;
P1_3=0;
_nop_();
_nop_();
_nop_();
//先取出目标地址的128字节数据
SetPageInt(5);
Point1=tWriteFlashAddr&0xff80;
Point0=&aWriteFlashBuf;
for(i=0;i<128;i++)
{
SetPageInt(bWriteFlashPage);
bTemp=*Point1;
++Point1;
SetPageInt(5);
*Point0=bTemp;
++Point0;
}
//找到相对写入地址,更新缓冲区中欲修该部分数据
Point1=&sWriteFlashBuf;
Point0=&aWriteFlashBuf+(tWriteFlashAddr&0x007f);
for(i=0;i<bWriteFlashLen;i++,Point0++,Point1++)
*Point0=*Point1;
//将整理好的缓冲区数据写入FLASH存储器中
Point1=tWriteFlashAddr&0xff80;
Point0=&aWriteFlashBuf;
SetPageInt(0);
XBYTE[0x5555]=0xaa; // 打开FLASH写保护
XBYTE[0x2aaa]=0x55;
XBYTE[0x5555]=0xa0;
for(i=0;i<128;i++)
{
SetPageInt(5);
bTemp=*Point0;
Point0++;
SetPageInt(bWriteFlashPage);
*Point1=bTemp;
Point1++;
}
SetPageInt(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;
EA=1;
}
SetPageInt(5);
switch(bStatusWord){
case S_HARDWAREINIT:
case S_OLDPARAINIT:
case S_NEWPARAINIT:
break;
case S_OLDLOCKWAIT:
case S_NEWLOCKWAIT:
case S_OLDUNLOCKWAIT:
case S_NEWUNLOCKWAIT:
DetectOnOffHook();
DetectRing();
DetectTone();
DetectPulse();
DetectKey();
DetectBX();
break;
case S_OLDMASTERCALL:
case S_NEWMASTERCALL:
case S_OLDSLAVECALL:
case S_NEWSLAVECALL:
DetectOnOffHook();
DetectTone();
DetectPulse();
DetectFanji();
DetectKey();
break;
case S_SERIALCOMM:
case S_SERVICE:
DetectOnOffHook();
DetectTone();
DetectPulse();
DetectKey();
break;
case S_DOWNCALL:
case S_OLDDOWNCOMM:
case S_NEWDOWNCOMM:
case S_UPCALL:
case S_OLDUPCOMM:
case S_NEWUPCOMM:
case S_UPREPORT:
case S_OLDUPREPORT:
case S_NEWUPREPORT:
DetectKey();
break;
default:
bStatusWord=S_HARDWAREINIT;
break;
} // End switch(bStatusWord)
SetPageInt(bPage);
}
// End interrupt function: ApiTime0()
/*************************************************************
*
* 函 数 名: _ApiUart()、ApiUart()
* 说 明: JJF24-1B新型计费器串行口中断服务程序
* 处理串行口数据接收和发送。
*
************************************************************/
void _ApiUart(void)
{
Api_Uart();
}
void Api_Uart(void)
{
if(RI){
RI=0;
fRxDataReady=1;
bRecSBUF=SBUF;
}
else{
TI=0;
fTxDataReady=1;
}
}
// End function: ApiUart()
/*************************************************************
*
* 函数名: DetectKey()
* 说 明: 检测按键值
*
************************************************************/
void DetectKey(void) using 1
{
byte bTemp;
bTemp=InBuf&0xf0; // 检测计费器按键
if(bTemp!=bKeyBuf)
{
bKeyBuf=bTemp;
cbKey=0;
}
else if(bTemp==0xf0);
else
{
if(++cbKey==10)
fKey=1;
else if(cbKey==200)
fKey=1; // 长按键有效
else if(cbKey>=225){
fKey=1; // 短按键有效
cbKey=225;
}
}
}
// End function: DetectKey()
/*************************************************************
*
* 函数名: DetectOnOffHook()
* 说 明: 检测挂摘机
*
************************************************************/
void DetectOnOffHook(void) using 1
{
byte bTemp;
bTemp=InBuf&0x03;
EA=0;
if(bTemp==0x00); // 不定状态,忽略
else if(bTemp==0x03)
{ // OH1、OH2=11 OnHook
if(cbLineState<128)
cbLineState=128;
else if(cbLineState>(128+L0))
{ // 线路挂机
fFanjiRequest=0;
fFanjiContinue=0;
cbFanji=0;
}
else
++cbLineState;
}
else
{
if(cbLineState>128){
cbLineState=128;
bStatusSave=bTemp;
}
else if(cbLineState<(128-L4)); // 线路摘机
else if(bStatusSave==bTemp)
--cbLineState;
else
cbLineState=129;
}
EA=1;
}
// End function: DetectOnOffHook()
/*************************************************************
*
* 函数名: DetectFanji()
* 说 明: 检测反极信号
*
************************************************************/
void DetectFanji(void) using 1
{
byte bTemp;
bTemp=InBuf&0x03;
if(bTemp==0x03); // 挂机状态
else if(fFanjiRequest)
{
fFanjiRequest=0;
fFanjiContinue=1;
bLineState=bTemp;
cbFanji=0;
fFanJi=0;
}
else if(fFanjiContinue)
{
if(bTemp!=bLineState)
{
if(++cbFanji>L3) // 反极有效时长
{
fFanJi=1;
cbFanji=0;
fFanjiContinue=0;
}
}
else
cbFanji=0;
}
}
// End function: DetectFanji()
/*************************************************************
*
* 函数名: DetectRing
* 说 明: 检测振铃
* 说 明: cbRingTimes: 振铃次数;
* cbRingLow: OH1低计时,单位5MS,下同;
* ciRingHigh: OH1高计时;
* cbRingPulseNum: 振铃脉冲个数 ;
*
*************************************************************/
void DetectRing(void) using 1
{
if((InBuf&0x01)!=0)
{ // 检测振铃,OH1=High ,摘机状态
cbRingLow=0;
if(++ciRingHigh<9);
else if(ciRingHigh<100){
if(cbRingPulseNum<5) // ciRingHigh==9,及40~45MS时间到
cbRingPulseNum=0;
}
else if(ciRingHigh<920){
if(cbRingPulseNum>=5){ // ciRingLow==100,及400MS时间到
++cbRingTimes;
cbRingPulseNum=0;
}
}
else{
ciRingHigh=920; // 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: DetectRing()
/*************************************************************
*
* 函数名: DetectTone()
* 说 明: 检测DTMF拨号
*
************************************************************/
void DetectTone(void) using 1
{
byte bTemp;
bTemp=InBuf&0x04;
if(bTemp==0x04)
{ // 检测到 DV=1
if(cbTone<5)
cbTone++;
else if(!fToneAid){
fToneAid=1;
if(pWriteNumber<16){
SetPageInt(7);
aNumBuf[pWriteNumber]=XBYTE[DTMF_ENB]&0x0f;
if(aNumBuf[pWriteNumber]==0x0a)
aNumBuf[pWriteNumber]=0;
else if(aNumBuf[pWriteNumber]==0x00)
aNumBuf[pWriteNumber]=0x0a;
SetPageInt(5);
bDialType|=0x0f;
pWriteNumber++;
}
}
else
cbTone=6;
}
else
{ // 检测到 DV=0;
if(cbTone==0)
fToneAid=0; // Usually Time
else
--cbTone;
}
}
// End function: DetectTone()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -