📄 cmx868.c
字号:
#include "CMX868.h"
#include "Key.h"
#include "Timer.h"
#include "save.h"
#include "I2c.h"
#include "Serial.h"
#include"Lcd.h"
CMXBUFF cmxBUF;
/**********
#pragma vector=UART0RX_VECTOR
__interrupt void UART0RXinterrupt(void)
{
char nChar = U0RXBUF;
cmxBUF.RBuff[cmxBUF.cRHead] = nChar;
++cmxBUF.cRHead;
if (cmxBUF.cRHead >= CMXRXLEN)
cmxBUF.cRHead = 0;
}
***************/
void TestCMX(void)
{
uchar i;
Rest_Buff();
for(i=0;i<0xff;i++)
cmxBUF.RBuff[cmxBUF.cRHead++]='0';
cmxBUF.RBuff[cmxBUF.cRHead++]='|';
}
void Cspi_bytewrite(uchar data)
{
uchar i;
CSPICLK_0;
for(i=0; i<8; i++)
{
if((data & BIT7)==BIT7)
CSPIMO_1;
else
CSPIMO_0;
_NOP();
CSPICLK_1;
NOP4;
CSPICLK_0;
data <<= 1;
}
}
//读字节
uchar Cspi_byteread(void)
{
uchar i,tempdata,tempbit;
for (i=0; i<8; i++)
{
CSPICLK_1;
_NOP();
if (CSPIDATA_IN == 0X80)
tempbit = 1;
else
tempbit = 0;
tempdata = (tempdata << 1) | tempbit;
CSPICLK_0;
NOP4;
}
return tempdata;
}
void Rest_Buff(void)
{
cmxBUF.cRHead=0;
cmxBUF.cRTail=0;
}
void StartFSK()
{
P2IE &= 0XFE;
P2IFG &= 0XFE;//禁止FSK数据接收
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXGENCTRL_ADDR); //写控制控制寄存器地址
Cspi_bytewrite(0x11); //选择外部晶体11.0592M,loopback-off,平衡禁止,
Cspi_bytewrite(0x41);//选择中断接收
NOP4;
CSPI_DIS;
Delay(100);
WATCHDOG_CLEAR;
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXTXMODE_ADDR); //接收模式设置:禁止RX
Cspi_bytewrite(0x3E);
Cspi_bytewrite(0X16);
NOP4; //bell202的逻辑'1'的信号频率为2200
CSPI_DIS;
Delay(0x100);
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXRXMODE_ADDR); //发送模式设置,禁止TX
Cspi_bytewrite(0x3E);
Cspi_bytewrite(0X36); //异步36数据
NOP4;
CSPI_DIS;
msDelay(1);
}
uint CSpi_Read_Int(ulong addr)
{
uint data1, data2;
uint data;
CSPI_EN;
NOP4;
Cspi_bytewrite(addr); //写低字节地址
data1 = Cspi_byteread(); //读数据
data2 = Cspi_byteread(); //读数据
NOP4;
CSPI_DIS;
Delay(100);
data = ((data1<< 8)&0XFF00)+data2;
return data;
}
uchar Read_CPH(uchar addr)
{
uchar total;
CSPI_EN;
NOP4;
Cspi_bytewrite(addr);
total=Cspi_byteread( );
NOP4;
CSPI_DIS;
Delay(100);
return total;
}
void reset_cbus()
{
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXGENRESET); //复位芯片操作
NOP4;
CSPI_DIS;
Delay(0x100);
}
void TX_cmx868(uchar data)
{
while((CSpi_Read_Int(0XE6)&0x1000)!=0x1000)
{_NOP();WATCHDOG_CLEAR; }
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXTXDATA_ADDR); //接收模式设置:禁止RX
Cspi_bytewrite(data);
NOP4; //bell202的逻辑'1'的信号频率为2200
CSPI_DIS;
}
void Init_CMX868(void)
{
P6DIR |=0X70;
P6DIR &=0X7F;
P6OUT &=0X0F;
//------------------------------
P2DIR &=0XFE;// P2.0CMX868中断信号输入
P2IES |= 0X01;//高到低产生中断
P2IFG &= 0xFE;//清可疑中断
P2IE &= 0xFE;//禁止产生中断
WATCHDOG_CLEAR;
NOP4;
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXGENRESET); //复位芯片操作
NOP4;
CSPI_DIS;
Delay(0x100); //每次写一个指令
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXGENCTRL_ADDR); //写控制控制寄存器地址
Cspi_bytewrite(0x13); //选择外部晶体11.0592M,loopback-off,平衡禁止,
Cspi_bytewrite(0x40);
NOP4;
CSPI_DIS;
Delay(0x100);
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXRXMODE_ADDR); //接收模式设置:RX设置为DTMF接收模式
Cspi_bytewrite(0x00);
Cspi_bytewrite(0X00);
NOP4;
CSPI_DIS;
msDelay(10);
}
//摘机
void Hook_On(void)
{
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXGENCTRL_ADDR); //写控制控制寄存器地址
Cspi_bytewrite(0x11); //选择外部晶体11.0592M,loopback-off,平衡禁止,
Cspi_bytewrite(0x40);
NOP4;
CSPI_DIS;
//延时等待拨号音
msDelay(2000); //等待1.5s
}
//挂机
void Hook_Off(void)
{
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXGENCTRL_ADDR); //写控制控制寄存器地址
Cspi_bytewrite(0x13); //选择外部晶体11.0592M,loopback-off,平衡禁止,
Cspi_bytewrite(0x40);
NOP4;
CSPI_DIS;
msDelay(1500);//等待1.5s
}
//拨号呼叫Sp,并并切换到FSK状态
//返回 0 --- 成功
// 其他 --- 失败
uchar ConnectSp()
{
uchar nChar;
uchar idx;
WATCHDOG_CLEAR;
//每次重新初始化
Init_CMX868();
//进行摘机操作
Hook_On();
//开始拨号,05305361944
for (idx=0;idx<16;idx++)
{
nChar = I2c_Read (ACCESSCODE+idx);
if (nChar<'0' || nChar>'9') break;
DTMF_SENT(nChar=='0'? 10 :nChar-0x30);
}
//延时切换至 FSK状态
msDelay(5000);
StartFSK();
P2IE |= 0X01;//打开接收中断
//Lcd_Show(0X80, "任意键退出");
//idx = 1;
//while (idx)
// {
// nChar = CSpi_Read_Int(CMXSTAT_ADDR) ;
// if(nChar&0X0040) //接收检测中断
// {
// nChar= Read_CPH(CMXRXDATA_ADDR);
// //调试输出
// while (TX0BUSY) NOP;
// U0TXBUF = nChar;
// }
// if (GetKey()!=KEYNO) idx=0;
// }
//return 1;
return 0;
}
//双音多频发送函数
void DTMF_SENT(uchar code)
{
if(code <= 0x0f)
{
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXTXMODE_ADDR); //发送模式设置
Cspi_bytewrite(0X1E);
Cspi_bytewrite(0X10+code); //发送双音多频
NOP4;
CSPI_DIS;
NOP4;
msDelay(60);
CSPI_EN;
NOP4;
Cspi_bytewrite(CMXTXMODE_ADDR);
Cspi_bytewrite(0X1E);
Cspi_bytewrite(0X00); //停止双音多频
NOP4;
CSPI_DIS;
msDelay(150);
}
}
/********CMX868中断输入 P2.0端口********
发送数据的时候屏蔽掉接收中断
接收数据的时候屏蔽掉发送中断
***************************************/
/*************/
#pragma vector=PORT2_VECTOR
__interrupt void CmxInterrupt(void)
{
uint status; //读状态寄存器的情况,判断产生中断的类型
uchar nChar;
if((P2IFG&0X01)==0x01)
{
status=CSpi_Read_Int(CMXSTAT_ADDR);
if((status &0X0040)==0X0040) //接收检测中断
{
nChar= Read_CPH(CMXRXDATA_ADDR);
cmxBUF.RBuff[cmxBUF.cRHead] = nChar;
++cmxBUF.cRHead;
if (cmxBUF.cRHead >= CMXRXLEN)
cmxBUF.cRHead = 0;
}
}
else if((P2IFG &0X02)==0X02)
{
}
P2IFG &= 0XFC;
}
/*****************/
/***********************************/
void WaitCMXCharCount(uint cnt)
{
while (g_WaitTimeOut == FALSE)
{
if (GetKey() == KEYCLEAR)
g_WaitTimeOut = TRUE;
else if (CMXGetCount()>=cnt)
break;
WATCHDOG_CLEAR;
}
}
/****************************************/
void WaitCMXUartChar(uchar ch)
{
uchar nChar;
while (g_WaitTimeOut == FALSE)
{
if (GetKey() == KEYCLEAR)
g_WaitTimeOut = TRUE;
else
{
nChar = CMXReadChar();
if ( nChar==ch)
break;
}
WATCHDOG_CLEAR;
}
}
//返回缓冲区内字节数
uint CMXGetCount(void)
{
uint count = 0;
P2IE &=0XFE; //禁止中断
if (cmxBUF.cRHead >= cmxBUF.cRTail)
{
count = cmxBUF.cRHead - cmxBUF.cRTail;
}else{
count = CMXRXLEN + cmxBUF.cRHead - cmxBUF.cRTail;
}
P2IE |=0X01;
return count;
}
//读取缓冲区的中len字节,并且设置m_Uart_State为错误代码
uchar CMXnReadChar( char *dst, uchar len)
{
uchar count=0,idx;
P2IE &=0XFE;
if (cmxBUF.cRHead >= cmxBUF.cRTail)
{
count = cmxBUF.cRHead - cmxBUF.cRTail;
}else{
count = CMXRXLEN + cmxBUF.cRHead - cmxBUF.cRTail;
}
if (count<len)
{
//m_CMX_State = ERR_UART_LESS;
}
else
{
for (idx=0;idx<len;idx++)
{
*(dst+idx) = cmxBUF.RBuff[cmxBUF.cRTail];
cmxBUF.cRTail = (cmxBUF.cRTail+1)% CMXRXLEN;
}
}
P2IE |=0X01;
return count;
}
//读取一行,'|'结束,返回读取的字符串长度
uchar CMXReadLine( char *pdst, char max)
{
uchar count = 0,total;
int idx,off;
P2IE &=0XFE;
if (cmxBUF.cRHead != cmxBUF.cRTail)
{
//计算有效数据总长度
if (cmxBUF.cRHead >= cmxBUF.cRTail)
{
total = cmxBUF.cRHead -cmxBUF.cRTail;
} else{
total = CMXRXLEN + cmxBUF.cRHead - cmxBUF.cRTail ;
}
//找结束符
for (idx=0;idx<max-1 && idx<total;idx++)
{
WATCHDOG_CLEAR;
off = cmxBUF.cRTail + idx;
if (off >= CMXRXLEN) off -= CMXRXLEN;
pdst[idx] = cmxBUF.RBuff[off];
if (cmxBUF.RBuff[off]=='|')
{
count = idx+1;
pdst[count-1] = 0;
cmxBUF.cRTail = off + 1;
if ( cmxBUF.cRTail >= CMXRXLEN) cmxBUF.cRTail =0;
//增加内容,可以保证"\r\n"结束不影响下一行处理
//if (cmxBUF.RBuff [cmxBUF.cRTail]=='\n')
//{
// cmxBUF.cRTail += 1;
// if ( cmxBUF.cRTail >= CMXRXLEN) cmxBUF.cRTail =0;
// }
break;
}
}
}
P2IE |=0X01;
return count;
}
char CMXReadChar(void)
{
char val='*';
P2IE &=0XFE; // Disable USART0 RX interrupt
if (cmxBUF.cRHead != cmxBUF.cRTail)
{
val = cmxBUF.RBuff[cmxBUF.cRTail++];
if (cmxBUF.cRTail>=CMXRXLEN) cmxBUF.cRTail = 0;
}else{
// m_Uart_State = ERR_UART_EMPTY;
}
P2IE |=0X01;
return val;
}
uchar CMXReFirst(void) //读第一段落的内容
{
uint count = 0,total;
int off;
P2IE &=0XFE; // Disable USART0 RX interrupt
if (cmxBUF.cRHead != cmxBUF.cRTail)
{
//计算有效数据总长度
if (cmxBUF.cRHead >= cmxBUF.cRTail)
{
total = cmxBUF.cRHead - cmxBUF.cRTail;
} else{
total = CMXRXLEN + cmxBUF.cRHead -cmxBUF.cRTail ;
}
//找结束符
if (total>11)//帧长度至少为7
{
if (cmxBUF.RBuff[cmxBUF.cRTail]!='B')
{
cmxBUF.cRTail = (cmxBUF.cRTail+1)% CMXRXLEN;
}else{
off = (cmxBUF.cRTail + 1) % CMXRXLEN;
if (cmxBUF.RBuff[off]!='B')
{
cmxBUF.cRTail = (cmxBUF.cRTail+2)% CMXRXLEN;
}else{
count=total;
}
}
}
}
P2IE |=0X01;
WATCHDOG_CLEAR;
return count;
}
//*********读取一桢的数据***********************
//返回 1 收到完整数据帧
// 0 没有数据或超时或校验错误
uchar ReadOneBlock(void)
{
uchar nChar;
uint cmxlength=0;
uint idx;
uchar count=0;
uchar recout=0;
uchar space=0;
g_WaitTimeOut = FALSE;//设定超时
SetTimer(TIMER_TIMEOUT,30000,Do_TimeOut);
while(g_WaitTimeOut == FALSE)
{
if (GetKey() == KEYCLEAR)
g_WaitTimeOut = TRUE;
nChar= CMXReFirst();
if(nChar>=11) break;
WATCHDOG_CLEAR;
}
KillTimer(TIMER_TIMEOUT);
if(g_WaitTimeOut == TRUE)
{
//Lcd_Clear();
// Lcd_Show(0x80,"通信繁忙无法传输");
//Lcd_Show(0x90,"请挂机重拨");
//Lcd_Show(0x98,CmdHelp);
return recout;
}
for(idx=0;idx<4;idx++)
{
if(cmxBUF.RBuff[cmxBUF.cRTail+3+idx]==32)
space++;
}
switch(space)
{
case 0:cmxlength=((cmxBUF.RBuff[cmxBUF.cRTail+3]-48)*1000+(cmxBUF.RBuff[cmxBUF.cRTail+4]-48)*100+(cmxBUF.RBuff[cmxBUF.cRTail+5]-48)*10+(cmxBUF.RBuff[cmxBUF.cRTail+6]-48));break;
case 1:cmxlength=((cmxBUF.RBuff[cmxBUF.cRTail+3]-48)*100+(cmxBUF.RBuff[cmxBUF.cRTail+4]-48)*10+(cmxBUF.RBuff[cmxBUF.cRTail+5]-48));break;
case 2:cmxlength=((cmxBUF.RBuff[cmxBUF.cRTail+3]-48)*10+(cmxBUF.RBuff[cmxBUF.cRTail+4]-48));break;
case 3:cmxlength=(cmxBUF.RBuff[cmxBUF.cRTail+3]-48);break;
default:break;
}
g_WaitTimeOut = FALSE;//设定超时
SetTimer(TIMER_TIMEOUT,60000,Do_TimeOut);
WaitCMXCharCount(cmxlength+11); //不精确,还有前面没有计算到的字节数
KillTimer(TIMER_TIMEOUT);
if(g_WaitTimeOut == TRUE) return recout;
else
recout=1;
for(idx=0;idx<cmxlength+8;idx++)
{
WATCHDOG_CLEAR;
count^=cmxBUF.RBuff[cmxBUF.cRTail+idx];
}
if(count==0) recout=1;
return recout;
}
uchar ReadDelaiyBlock(void)
{
uchar nChar;
uint cmxlength=0;
uint idx;
uchar count=0;
uchar recout=0;
uchar space=0;
g_WaitTimeOut = FALSE;//设定超时
SetTimer(TIMER_TIMEOUT,5000,Do_TimeOut);
while(g_WaitTimeOut == FALSE)
{
if (GetKey() == KEYCLEAR)
g_WaitTimeOut = TRUE;
nChar= CMXReFirst();
if(nChar>=11) break;
WATCHDOG_CLEAR;
}
KillTimer(TIMER_TIMEOUT);
if(g_WaitTimeOut == TRUE)
{
//Lcd_Clear();
// Lcd_Show(0x80,"通信繁忙无法传输");
//Lcd_Show(0x90,"请挂机重拨");
//Lcd_Show(0x98,CmdHelp);
return recout;
}
for(idx=0;idx<4;idx++)
{
if(cmxBUF.RBuff[cmxBUF.cRTail+3+idx]==32)
space++;
}
switch(space)
{
case 0:cmxlength=((cmxBUF.RBuff[cmxBUF.cRTail+3]-48)*1000+(cmxBUF.RBuff[cmxBUF.cRTail+4]-48)*100+(cmxBUF.RBuff[cmxBUF.cRTail+5]-48)*10+(cmxBUF.RBuff[cmxBUF.cRTail+6]-48));break;
case 1:cmxlength=((cmxBUF.RBuff[cmxBUF.cRTail+3]-48)*100+(cmxBUF.RBuff[cmxBUF.cRTail+4]-48)*10+(cmxBUF.RBuff[cmxBUF.cRTail+5]-48));break;
case 2:cmxlength=((cmxBUF.RBuff[cmxBUF.cRTail+3]-48)*10+(cmxBUF.RBuff[cmxBUF.cRTail+4]-48));break;
case 3:cmxlength=(cmxBUF.RBuff[cmxBUF.cRTail+3]-48);break;
default:break;
}
g_WaitTimeOut = FALSE;//设定超时
SetTimer(TIMER_TIMEOUT,60000,Do_TimeOut);
WaitCMXCharCount(cmxlength+11); //不精确,还有前面没有计算到的字节数
KillTimer(TIMER_TIMEOUT);
if(g_WaitTimeOut == TRUE) return recout;
for(idx=0;idx<cmxlength+8;idx++)
{
WATCHDOG_CLEAR;
count^=cmxBUF.RBuff[cmxBUF.cRTail+idx];
}
if(count==0) recout=1;
return recout;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -