📄 modem.c
字号:
/**
OK
+CMTI: "SM",1//短信提示
//读取到的一条短信 at+cmgl="all"
+CMGL: 1,"REC UNREAD","+8613425183694",,"06/11/24,17:31:14+00"
!020100000000003500800102FF041600000517000000B9DB!
OK
>
+CMGS: 120//发送短信
OK
+CSQ: 27,99//读取机站电平
//读取机站信息
+CCED: 460,00,253c,1327,40,86,51,,,0,,,0,460,00,253c,1326,29,92,46,460,00,252d,10c4,28,80,38,460,00,253c,12ea,41,78,33,460,00,253c,12ff,60,60,32,460,00,253c,1163,52,530,40,460,00,253c,,44,518,39,1
OK
+CMGL: 1,"REC UNREAD","+8613425183694",,"06/11/24,17:31:14+00"
!020100000000003500800102FF041600000517000000B9DB!
+CMGL: 11,"REC READ","+8613425183694",,"06/11/27,10:02:42+00"
!020100000000000500800102FF046E030057C0!
OK
**/
/*#include <stdio.h>*/
/*#include <string.h>*/
#include "..\inc\def.h"
#include "..\inc\all.h"
__flash schar ModemCSQ_Tab[]=
{/* 0 1 2 3 4 5 6 7 8 9*/
-113,-111,-109,-107,-105,-103,-101, -99, -97, -95,
-93, -91, -89, -87, -85, -83, -81, -79, -77, -75,
-73, -71, -69, -67, -65, -63, -61, -59, -57, -55,
-53, -51, 0,
};
#define MDM_READSMS_TIME 7
#define MAX_SEND_CCED_TIME 250
#define MAX_RINGIN 3
#define MAX_CONNECTTIME SWAIT50S//建立连接50S不成功则挂断
#define MAX_HOOKONTIME SWAIT300S//连接中120S内没有数据自动挂断---- 根据广东电信要求改为5分钟
extern void ModemMsg_Proc(uchar iport,uchar *ptr,uint revlen);
extern void SetDTR(uchar port, uchar op);
extern uchar CheckCarrierStatus(uchar port);
extern uchar AlmSmsBufIsBlank();
extern void CMCCObjTabPackProc();
__no_init uchar atcmd[MAX_MSGLEN2] @ ESRAM_MDM_ATCMD;
__no_init uchar mdmRtnbuf[MAX_MSGLEN2] @ ESRAM_MDM_RTN;
__no_init uchar SmsIndexBuf[40] @0x7e00,SmsBH @0x7e30,SmsBT @0x7e31;
extern uchar mdm_sending_busy;
tSMSStruct SMSPick;
extern __no_init uchar MDMSendBuf[MDM_SDBLEN];
uint mdmRtnbuf_cnt;
extern uchar msgA_state;
uchar mdm_state,mdm_state1,next_state1,mdm_ReadSMS_Timer;
uchar ucKeyPadOkayToSend,mdm_index,Rev_OK,RevSmsIndicator;
uint mdm_wait,mdm_wait1;
/* MODEM拨号 */
uchar RingCount;
__flash tModemSendResponse GSMModemInitString[] = {
{"AT+IFC=0,0\r\n", "OK\r\n",2},
{"ATE0\r\n", "OK\r\n",2}, /*设置Characters are not echoed*/
{"ATTS7=45S0=1S10=40V1X4M1&D2\r\n", "OK\r\n",2},/*接收短信,直通方式 无卡,返回ERROR*/
{"AT+CSMP=1,167,0,0\r\n", "OK\r\n",2}, /*设置Characters are not echoed*/
//{"AT+CPAS\r\n", "OK\r\n",2},
/*{"AT+CNMA\r\n", "",2}, *表明短信已收到,只对CDMA有效*/
//{"AT+CMGD=1,3\r\n", "OK\r\n",2},/*删除所有短信,包括:发送,接收,未读,保存 无卡,返回ERROR*/
/*{"AT+WSCL=0,2\r\n", "OK\r\n",4},*设置SMS的语言和编码方式,CDMA系统有效*/
{"AT+CMGF=1\r\n", "OK\r\n",2},/*SMS是文本模式, 0-则是PDU模式*/
{"AT+CLIP=1\r\n", "OK\r\n",2},/*来电号码显示*/
{"AT+CNMI=2,1,0,0,0\r\n", "OK\r\n",2},/*接收短信,直通方式 无卡,返回ERROR*/
{"AT+CSCA=\"", "OK\r\n",2},/*设置短信中心号码,只GSM有效*/
/*{"AT+CSMP=17,167,0,240\r\n", "OK\r\n",4}, CSMP命令可以设置
手机到中心是直通方式,或中心到手机是直通方式
此处设置,对方将是直通方式收到,设置文本模式的参数 无卡,返回ERROR*/
{"", "", 255},/*结束标志*/
};
#define SETTING_SMS_NUM 7
/*
static tModemSendResponse GSMModemDialString[] = {
{"ATE0\r\n", "OK\r\n"}, //设置Characters are not echoed
{"ATDT=", "OK\r\n"},//设置短信中心号码,只GSM有效
};
static tModemSendResponse GSMModemAnswerString[] = {
{"ATE0\r\n", "OK\r\n"}, //设置Characters are not echoed
{"ATA", "OK\r\n"},//设置短信中心号码,只GSM有效
};
*/
__flash tModemSendResponse ModemOperateCMDString[] = {
{"AT+CNMA\r\n", "OK",2},/*表明短信已收到,只对CDMA有效*/
{"AT+CMGL=\"REC UNREAD\"\r\n", "OK\r\n",2},/*GSM读取短信*/
{"AT+CMGD=", "OK\r\n",2},/*删除:已读,已发,未发*/
{"AT+CMGL=\"UREAD\"\r\n", "OK\r\n",2},/*CDMA读取短信*/
{"AT+CSQ\r\n", "OK\r\n",0},/*获取接收电平*/
{"ATD", "",0},/*拨号*/
{"ATA", "",0},/*应答*/
{"+++", "",0},/*应答*/
{"ATH0", "OK\r\n",2},/*拨号*/
{"ATH1", "OK\r\n",2},/*应答*/
{"AT+CCED=0\r\n", "OK\r\n",2},/*应答*/
{"AT+CMGR=", "OK\r\n",2},/*GSM读取短信*/
{"AT+CMGL=\"ALL\"\r\n", "OK\r\n",2},/* 12 GSM读取短信*/
{"AT+CMGD=1,3\r\n", "OK\r\n",2},/* 13 删除所有短信,包括:发送,接收,未读,保存 无卡,返回ERROR*/
};
__flash tModemSendResponse CDMAModemInitString[] = {
{"ATE0\r\n", "OK\r\n",2}, /*设置Characters are not echoed*/
{"AT+IFC=0,0\r\n", "OK\r\n",2},/*'设置硬件设备的 流控制协议*/
{"AT+CNMI=2,2,0,0,0\r\n", "OK\r\n",2},/*接收短信,直通方式*/
{"AT+CMGF=1\r\n", "OK\r\n",2},/*SMS是文本模式, 0-则是PDU模式*/
{"AT+CNMA\r\n", "OK\r\n",0},/*表明短信已收到,只对CDMA有效*/
{"AT+CMGD=1,4\r\n", "OK\r\n",0},/*删除所有短信,包括:发送,接收,未读,保存*/
{"AT+WSCL=0,2\r\n", "OK\r\n",2},/*设置SMS的语言和编码方式,CDMA系统有效*/
{"ATE0\r\n", "OK\r\n",2}, /*设置Characters are not echoed*/
{"", "", 255},/*结束标志*/
};
__flash tModemSendResponse ModemDialString[] = {
{"ATH0\r\n", "OK\r\n",2}, /*设置Characters are not echoed*/
{"ATZ\r\n", "OK\r\n",2}, /*设置Characters are not echoed*/
{"ATTS7=45S0=1S10=40V1X4L1M1&D2\r\n", "OK\r\n",2},/*M1,打开声音, M0,关闭声音*/
{"", "", 255},/*结束标志*/
};
__flash tModemSendResponse GPRSModemDialString[] = {
{"AT#DLEMODE=0\r\n", "OK\r\n",2}, /*设置转义无效*/
{"AT+WOPEN=1\r\n", "OK\r\n",2},/*打开TCP协议栈*/
{"AT#GPRSMODE=1\r\n", "OK\r\n",2},/*激活GPRS模式*/
{"AT#APNSERV=", "OK\r\n",2},/*"AT#APNSERV=\"CMNET\"\r\n"接入服务提供商*/
{"AT#APNUM=", "OK\r\n",2},/*"AT#APNUM=\"login\"\r\n"用户名*/
{"AT#APNPW=", "OK\r\n",2},/*"AT#APNPW=\"password\"\r\n"用户密码*/
{"AT#TCPSERV=", "OK\r\n",2},/*"AT#TCPSERV=\"210.75.18.74\"\r\n"设置服务器IP*/
{"AT#TCPPORT=", "OK\r\n",2},/*"AT#TCPPORT=5002\r\n"设置端口号*/
{"AT+CGATT=1\r\n", "OK\r\n",2},/*打开附着*/
{"AT#CONNECTIONSTOP\r\n", "OK\r\n",2}, /*关闭通信*/
{"AT#CONNECTIONSTART\r\n", "OK\r\n",2}, /*拨号建立连接*/
{"AT#OTCP\r\n", "OK\r\n",2}, /**/
{"", "", 255},/*结束标志*/
};
void Init_Modem()
{
mdm_sending_busy = 0;
//uiRtn_ch = 0;
mdmRtnbuf_cnt = 0;
mdm_state = mdm_state1 = 0;
ucKeyPadOkayToSend = 0;
mdm_index = 0;
Rev_OK = 0;
mdm_wait = mdm_wait1 = 0;
atpt = atph = 0;
MDMRvBuf_H = MDMRvBuf_T = 0;
MDMSendBuf_H = MDMSendBuf_T = 0;
mdm_ReadSMS_Timer = 0;
SmsBH = SmsBT = 0;
}
void PrintToUartB(uchar *str, uchar len)
{
#ifdef __DEBUG_PRINT__
uchar j=0;
while(j<len){
sdb[2][sdb_T[2]] = str[j++];
if(++sdb_T[2]>=MAX_RVBLEN) sdb_T[2] = 0;
}
sdb[2][sdb_T[2]] = '\r';
if(++sdb_T[2]>=MAX_RVBLEN) sdb_T[2] = 0;
sdb[2][sdb_T[2]] = '\n';
if(++sdb_T[2]>=MAX_RVBLEN) sdb_T[2] = 0;
#endif
}
void Reset_Modem(uchar res)
{
if(res){
PORTB = PORTB & 0xef;
}
else{
PORTB = PORTB | 0x10;
}
}
/*
//读取MODEM的命令行
uchar ReadCMDLine()
{
if(mdmRtnbuf_cnt==0){
while(MDMRvBuf_H !=MDMRvBuf_T) {*找同步头*
if((MDMRvBuf[MDMRvBuf_H] > 0x20) &&
(MDMRvBuf[MDMRvBuf_H] <= 'Z'))
{
uiRtn_ch = 0;
break;
}
if (++MDMRvBuf_H >= MDM_RVBLEN) MDMRvBuf_H = 0;
}
}
while(MDMRvBuf_H !=MDMRvBuf_T){
mdmRtnbuf[mdmRtnbuf_cnt++] = MDMRvBuf[MDMRvBuf_H];
uiRtn_ch = (uiRtn_ch<<8) + MDMRvBuf[MDMRvBuf_H];
if (++MDMRvBuf_H >= MDM_RVBLEN) MDMRvBuf_H = 0;
if(uiRtn_ch == KEY_CRCL)
{
if(mdmRtnbuf_cnt<3)
mdmRtnbuf_cnt = 0;*丢弃多余的:回车换行符号*
else
return 1;
}
if(mdmRtnbuf_cnt>=MAX_MSGLEN2)
mdmRtnbuf_cnt = 0;*丢弃无效消息*
}
return 0;
}
*/
uint Rtn_temp_ptr;
uchar Rtn_MDM_Count;/*解决收到包头尾标志"X"不全时, 程序不接收后续包的BUG.*/
/*=============================================
完成接收命令或命令行的获取*/
uchar ReadCMDLine()//GetMDMCMD()
{
uint uiRtn_ch,i;
if(ModemLineCount > 0)
{
mdmRtnbuf_cnt = 0;
if(MDMRvBuf_H == MDMRvBuf_T) {//容错检查
ModemLineCount = 0;
return 0;
}
Rtn_temp_ptr = MDMRvBuf_H;
while(Rtn_temp_ptr !=MDMRvBuf_T) {
uiRtn_ch = (uiRtn_ch<<8) + MDMRvBuf[Rtn_temp_ptr];
mdmRtnbuf[mdmRtnbuf_cnt++] = MDMRvBuf[Rtn_temp_ptr];
if (++Rtn_temp_ptr >= MDM_RVBLEN) Rtn_temp_ptr = 0;
if(uiRtn_ch == KEY_CRCL){
MDMRvBuf_H = Rtn_temp_ptr;
ModemLineCount--;
if(RealPara.DebugMod == 1 )//modem接收到消息抄送到近端维护端口
{
for(i = 0; i < mdmRtnbuf_cnt; i++)
{
sdb[2][sdb_T[2]] = mdmRtnbuf[i];
if(++sdb_T[2]>=MAX_RVBLEN) sdb_T[2] = 0;
}
}
return 1;
}
}
}
return 0;
}
uchar ReadRS232()//GetMDMCMD()
{
uint uiRtn_ch = 0,i,Rtn_temp_ptr;
if(ModemLineCount > 1)//必须要2个同步字节才有一条消息
{
uiCmdFlag = 0;
mdmRtnbuf_cnt = 0;
if(MDMRvBuf_H == MDMRvBuf_T) {//容错检查
ModemLineCount = 0;
return 0;
}
while(MDMRvBuf_H != MDMRvBuf_T) {//找到第一个同步头
if(MDMRvBuf[MDMRvBuf_H] == SYNCA){
//ModemLineCount--;
break;
}
if (++MDMRvBuf_H >= MDM_RVBLEN) MDMRvBuf_H = 0;
}
Rtn_temp_ptr = MDMRvBuf_H;
mdmRtnbuf[mdmRtnbuf_cnt++] = MDMRvBuf[Rtn_temp_ptr];
if (++Rtn_temp_ptr >= MDM_RVBLEN) Rtn_temp_ptr = 0;
while(Rtn_temp_ptr !=MDMRvBuf_T) {
uiRtn_ch = (uiRtn_ch<<8) + MDMRvBuf[Rtn_temp_ptr];
if(uiRtn_ch == 0x5E5D)
mdmRtnbuf[mdmRtnbuf_cnt++] = SYNCTM;
else if(uiRtn_ch == 0x5E7D)
mdmRtnbuf[mdmRtnbuf_cnt++] = SYNCA;
else{
if(MDMRvBuf[Rtn_temp_ptr] != SYNCTM)
mdmRtnbuf[mdmRtnbuf_cnt++] = MDMRvBuf[Rtn_temp_ptr];
}
if(MDMRvBuf[Rtn_temp_ptr] == SYNCA){
//ModemLineCount--;
if(mdmRtnbuf_cnt<10)//消息长度不够,无效消息
{
if (++MDMRvBuf_H >= MDM_RVBLEN) MDMRvBuf_H = 0;
mdmRtnbuf_cnt = 0;
return 0;
}
if (++Rtn_temp_ptr >= MDM_RVBLEN) Rtn_temp_ptr = 0;
MDMRvBuf_H = Rtn_temp_ptr;
ModemLineCount -= 2;
if(RealPara.DebugMod == 1 )
{//modem接收到消息抄送到近端维护端口
for(i = 0; i < mdmRtnbuf_cnt; i++){
sdb[2][sdb_T[2]] = mdmRtnbuf[i];
if(++sdb_T[2]>=MAX_RVBLEN) sdb_T[2] = 0;
}
}
return 1;//收到消息包
}
if (++Rtn_temp_ptr >= MDM_RVBLEN) Rtn_temp_ptr = 0;
}
}
else if(ModemLineCount==0){
if(uiCmdFlag == KEY_CRCL){//可能收到modem命令
mdmRtnbuf_cnt = 0;
uiCmdFlag = 0;
Rtn_temp_ptr = MDMRvBuf_H;
while(Rtn_temp_ptr !=MDMRvBuf_T) {
uiRtn_ch = (uiRtn_ch<<8) + MDMRvBuf[Rtn_temp_ptr];
mdmRtnbuf[mdmRtnbuf_cnt++] = MDMRvBuf[Rtn_temp_ptr];
if (++Rtn_temp_ptr >= MDM_RVBLEN) Rtn_temp_ptr = 0;
if(uiRtn_ch == KEY_CRCL){
MDMRvBuf_H = Rtn_temp_ptr;
if(RealPara.DebugMod == 1 )//modem接收到消息抄送到近端维护端口
{
for(i = 0; i < mdmRtnbuf_cnt; i++)
{
sdb[2][sdb_T[2]] = mdmRtnbuf[i];
if(++sdb_T[2]>=MAX_RVBLEN) sdb_T[2] = 0;
}
}
return 1;
}
}
}
}
return 0;
}
void SendATCmd(uchar *ucData, uchar ucLen, uchar ucFlag)
{
uchar i,j;
atph = 0;
atpt = ucLen;
strcpy(atcmd, ucData);
if (ucFlag == 2)//拷贝短信中心号码
{
for(i = 0; i < 20; i++){//设置短信中心号码
if((NetPara.SmsTel[i]==0) ||
(NetPara.SmsTel[i]==0x20))
break;
else
atcmd[atpt+i] = NetPara.SmsTel[i];
}
atpt += i;
atcmd[atpt++] = 0x22;
}
else if (ucFlag == 3)//拷贝上报号码
{
for(i = 0; i < 20; i++){
if((NetPara.AlarmTel[i]==0) ||
(NetPara.AlarmTel[i]==0x20))
break;
else
atcmd[atpt++] = NetPara.AlarmTel[i];
}
}
else if (ucFlag == 0x83)//GPRS:接入运营商
{
atcmd[atpt++] = '"';
for(i = 0; i < 20; i++){
if((NetPara1.GPRSAccessName[i]==0) ||
(NetPara1.GPRSAccessName[i]==0x20))
break;
else
atcmd[atpt++] = NetPara1.GPRSAccessName[i];
}
atcmd[atpt++] = '"';
}
else if (ucFlag == 0x84)//GPRS:用户名
{
atcmd[atpt++] = '"';
for(i = 0; i < 20; i++){
if((NetPara1.GPRSName[i]==0) ||
(NetPara1.GPRSName[i]==0x20))
break;
else
atcmd[atpt++] = NetPara1.GPRSName[i];
}
atcmd[atpt++] = '"';
}
else if (ucFlag == 0x85)//GPRS:用户密码
{
atcmd[atpt++] = '"';
for(i = 0; i < 20; i++){
if((NetPara1.GPRSPass[i]==0) ||
(NetPara1.GPRSPass[i]==0x20))
break;
else
atcmd[atpt++] = NetPara1.GPRSPass[i];
}
atcmd[atpt++] = '"';
}
else if (ucFlag == 0x86)//GPRS:IP地址
{
atcmd[atpt++] = '"';
for(j = 0; j < 4; j++){
EEBuf[0] = UCharToStrCRLF(NetPara.OMCIPAddr[j],&EEBuf[1],0);
for(i = 0; i < EEBuf[0]; i++){
atcmd[atpt++] = EEBuf[1+i];
}
atcmd[atpt++] = '.';
}
atcmd[atpt-1] = '"';
}
else if (ucFlag == 0x87)//GPRS:端口号
{
EEBuf[0] = UIntToStr(NetPara.OMCIPPort,&EEBuf[1]);
for(i = 0; i < EEBuf[0]; i++){
atcmd[atpt++] = EEBuf[1+i];
}
}
if (ucFlag)//附加"\r\n"
{
atcmd[atpt++] = '\r';
atcmd[atpt++] = '\n';
}
if(RealPara.DebugMod == 1 )//modem接收到消息抄送到近端维护端口
{
for(i = 0; i < atpt; i++){
sdb[2][sdb_T[2]] = atcmd[i];
if(++sdb_T[2]>=MAX_RVBLEN) sdb_T[2] = 0;
}
}
}
static tModemSendResponse rtnPtr;
uchar Init_Modem_Proc()
{
uchar i;
switch(mdm_state1){
case INIT_MDM_WAIT_POWEROK:
mdm_wait1 = 0;
mdm_state1 = INIT_MDM;
break;
case INIT_MDM:
if(++mdm_wait1>SWAIT5S){
/* if(NetPara.CommMode == COMM_MODE_GSM_SMS)
mdm_state1 = INIT_MDM_GSM_SEND_ATCMD;
else if (NetPara.CommMode == COMM_MODE_CDMA_SMS)
mdm_state1 = INIT_MDM_GSM_SEND_ATCMD;
else if(NetPara.CommMode == COMM_MODE_PSTN_DATA)*/
mdm_state1 = INIT_MDM_GSM_SEND_ATCMD;
//else mdm_state1 = INIT_MDM_DATA;
mdm_index = 0;
atpt = atph = 0;
//SetLEDWarn(LED_OFF,0);
RunLed_Period = 1;
}
break;
case INIT_MDM_GSM_SEND_ATCMD:
if(NetPara.CommMode == COMM_MODE_GSM_SMS)
rtnPtr = GSMModemInitString[mdm_index];
else if (NetPara.CommMode == COMM_MODE_CDMA_SMS)
rtnPtr = CDMAModemInitString[mdm_index];
else if(NetPara.CommMode == COMM_MODE_PSTN_DATA)
rtnPtr = ModemDialString[mdm_index];
/*else mdm_state1 = INIT_MDM_DATA;*/
if (rtnPtr.lenAck == 255){
return INIT_OK;//初始化正确,完成
//mdm_state1 = INIT_READALL_SMS;
}
else{
if((mdm_index == SETTING_SMS_NUM)
&&(NetPara.CommMode == COMM_MODE_GSM_SMS))
{
for(i = 0; i < 20; i++){//设置短信中心号码
if((NetPara.SmsTel[i]==0) ||
(NetPara.SmsTel[i]==0x20))
break;
}
if((i<4)||(i>20)){
mdm_index++;
}
else {
SendATCmd(rtnPtr.pSend, strlen(rtnPtr.pSend), 2);
mdm_state1 = INIT_MDM_GSM_WAIT_RESPONSE;
}
}
else{
SendATCmd(rtnPtr.pSend, strlen(rtnPtr.pSend), 0);
mdm_state1 = INIT_MDM_GSM_WAIT_RESPONSE;
}
mdm_wait1 = 0;
//SetLEDWarn(LED_ON,0);
RunLed_Period = 255;
}
break;
case INIT_MDM_GSM_WAIT_RESPONSE:
if(ReadCMDLine()){
//SetLEDWarn(LED_OFF,0);
RunLed_Period = 1;
if (strncmp(mdmRtnbuf,
rtnPtr.pAck,
rtnPtr.lenAck)==0) {
mdm_state1 = INIT_MDM_GSM_SEND_ATCMD;
mdm_index++;
if(mdm_sending_busy) mdm_sending_busy = 0;
/*if(++mdm_index>7) return INIT_OK; 初始化正确,完成*/
}
else if((strncmp(mdmRtnbuf,"ERROR\r\n",7)==0)
&&(rtnPtr.lenAck != 0))
{/*响应错误*/
mdm_state1 = INIT_MDM_WAIT_POWEROK;
//SetLEDWarn(LED_ON,0);
RunLed_Period = 255;
}
else if(strncmp(mdmRtnbuf,
rtnPtr.pSend,
strlen(rtnPtr.pSend)-2)==0)/*回显开*/
{
}
mdmRtnbuf_cnt = 0;
}
if(++mdm_wait1 > SWAIT10S){
mdm_state1 = INIT_MDM_WAIT_POWEROK;
//SetLEDWarn(LED_ON,0);
RunLed_Period = 255;
}
break;
case INIT_MDM_CDMA:
mdm_state1 = 0;
break;
case INIT_MDM_DATA:
mdm_state1 = 0;
break;
/* case INIT_READALL_SMS://读取所有短信
if(mdm_sending_busy==0){
SendATCmd(ModemOperateCMDString[12].pSend, strlen(ModemOperateCMDString[12].pSend), 0);
mdm_state1 = INIT_READALL_SMS_WAIT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -