📄 sms.c
字号:
{
nLength=16;
}
buf[0] =(uchar)((nLength & 1) == 0 ? nLength : nLength + 1) / 2 + 1; // SMSC地址信息长度
buf[1] = 0x91; // 固定: 用国际格式号码
nDstLength = gsmBytes2String(buf, pDst, 2); // 转换2个字节到目标PDU串(转ASCII)
nDstLength += gsmInvertNumbers(addr_buf, &pDst[nDstLength], nLength); // (需提前将其转为ASCII)转换SMSC到目标PDU串(两两交换)
// TPDU段基本参数、目标地址等
nLength =countsn(phone_buf); // TP-DA地址字符串的长度用户电话号码长度
if(nLength>16)
{
nLength=16;
}
buf[0] = 0x11; // 是发送短信(TP-MTI=01),TP-VP用相对格式(TP-VPF=10)
buf[1] = 0; // TP-MR=0
buf[2] = (uchar)nLength; // 目标地址数字个数(TP-DA地址字符串真实长度)
buf[3] = 0x91; // 固定: 用国际格式号码
nDstLength += gsmBytes2String(buf, &pDst[nDstLength], 4); // 转换4个字节到目标PDU串
nDstLength += gsmInvertNumbers(phone_buf, &pDst[nDstLength], nLength); // 转换TP-DA到目标PDU串
// TPDU段协议标识、编码方式、用户信息等
nLength =countsn(msg_buf); // 用户信息字符串的长度
if(nLength>280)
{
nLength=280;
}
buf[0] = 0X00; // 协议标识(TP-PID)
buf[1] = 0X08; // 用户信息编码方式(TP-DCS)
buf[2] = 0XA7; // 有效期(TP-VP)为5分钟(最长时间)
buf[3] = nLength/2;
nDstLength += gsmBytes2String(buf, &pDst[nDstLength], 4); // 转换该段数据到目标PDU串
nDstLength += a_stutob_stu(msg, &pDst[nDstLength], nLength); // 转换TP-DA到目标PDU串(msg用户数据)
pDst[nDstLength]=0;
// 返回目标字符串长度(转成压缩的BCD码)
nDstLength=(nDstLength-18)/2;
for(a=3;a>0;a--) //取出每位中的数据
{
buf[a-1]=nDstLength%10+48;
nDstLength/=10;
}
if(buf[0]!=48)
UART0_TransmitByte(buf[0]);
UART0_TransmitByte(buf[1]);
UART0_TransmitByte(buf[2]);
}
//***********************************************************************//
//***********************************************************************//
//串口返回数据比较
//********************************
void read_inbuf(void)
{
uint n=0;
uchar rx_buf[64];
if(UART0_DataInReceiveBuffer())
{
n=0;
ok=0;
error=0;
while((UART0_DataInReceiveBuffer())&(n<63))
{
rx_buf[n ++] = UART0_ReceiveByte(); //
}
if(string_match(n,rx_buf,5,"+CMTI")!=0) //有新短消息
{
read_sms=1;
count30s=0;
time30s=0;
DelayMs(1000);
}
if(string_match(n,rx_buf,11,"13562503079")!=0) //系统响应OK
{
qu=1;
count30s=0;
time30s=0;
DelayMs(6500);
sms_counts(5);//发送状态报告
}
if(string_match(n,rx_buf,2,"OK")!=0) //系统响应OK
{
ok=1;
//UART0_Transmitstr("好的");
//CR;
}
if(string_match(n,rx_buf,2,"ERROR")!=0) //系统响应OK
{
error=1;
//UART0_Transmitstr("错误");
//CR;
}
}
}
//***********************************************************
//GSM模块控制,包括模块控制及应答信号检查
//防止死机
//tc35=1;gsm模块已经开机
//signal=0;注册中国移动
//signal=1;注册到中国联通
//signal=3;请等待
//signal_c=1;进网标志
//signal_c=0;没有进网
//***********************************************************
void tc35_count (void)
{
uchar n=0;
static uchar signal_no=0;//无信号次数
uchar rx_buf[64];
wdt_reset();//复位看门狗
while(UART0_DataInReceiveBuffer()) UART0_ReceiveByte(); //清空接收区
DelayMs(10);
UART0_Transmitstr("AT+COPS?");
CR;
DelayMs(100);
n=0;
while((UART0_DataInReceiveBuffer())&(n<63))
{
rx_buf[n ++] = UART0_ReceiveByte(); //
}
wdt_reset();//复位看门狗
if(string_match(n,rx_buf,5,"+COPS")!=0) //系统响应COPS
{
if(n>30)
{
signal_c=1;
signal_no=0;//无信号计数器
}
else
{
signal_c=0;
signal_no++;//无信号计数器
}
}
else
{
addr_e=0; //标记重新识别短信中心(addr_e=0,SIM接触不良时,TC35重启一次,否则SIM接触不良时,TC35一直重启)
CLR_IGT;//GSM开机
DelayMs(100);
SET_IGT;//拉高
signal_c=0; //没有进网
signal_no=0;//无信号计数器
}
if((signal_no>2)&(addr_e==1))
{
UART0_Transmitstr("AT^SMSO"); //关闭,退出网络
CR;
}
ok=0;
error=0;
}
//*************************************************************//
//获取短信中心号码
//入口 AT+CSCA?
//出口 码片的ADDR
void write_addr(void)
{
uint n=0,temp,temp1;
uchar a,c;
uchar rx_buf[50];
uchar buf[16];
if((addr_e==0)&(signal_c==1))
{
wdt_reset();//复位看门狗
while(UART0_DataInReceiveBuffer())UART0_ReceiveByte(); //
DelayMs(10);
UART0_Transmitstr("AT+CSCA?");
CR;
DelayMs(200);
n=0;
while((UART0_DataInReceiveBuffer())&(n<49))
{
rx_buf[n ++] = UART0_ReceiveByte(); //
}
wdt_reset();//复位看门狗
if(string_match(n,rx_buf,2,"OK")!=0)
{
temp=string_match(n,rx_buf,6,"+CSCA:");//匹配到的字符串长度
temp+=3;
temp1=string_match(n,rx_buf,1,",");//匹配到的字符串长度
temp1-=2;
temp1-=temp;
c=0;
for(a=0;a<temp1;a++)//,
{
buf[c]=rx_buf[temp+a];
c++;
}
buf[c]='#';
eeprom_busy_wait();
eeprom_write_block (&buf[0], &E_addr[0], 16);//块写入0
addr_e=1;
}
wdt_reset();//复位看门狗
while(UART0_DataInReceiveBuffer())n=UART0_ReceiveByte(); //清空接收区
wdt_reset();//复位看门狗
tc35_devices();
UART0_Transmitstr("AT+CMGD=1");
CR;
DelayMs(1000);//等待TC35完成
while(UART0_DataInReceiveBuffer())n=UART0_ReceiveByte(); //清空接收区
wdt_reset();//复位看门狗
ok=0;
error=0;
}
}
//***************************短信事件循环******************************************//
//目标:发送SMS
//1)读取要发送的事件
//2)读取用户0,如果该用户不空,发送SMS
//3)如果OK,发送下一用户,如果ERR|TIMEOUT 错误计数器+1,错误累计到3,清除该用户,读取新用户
//4)所有用户发送完毕,清除该事件,返回1)循环
//日期:2007/09/13
//ver:1.0
//********************************************************************************//
void sms_event_circulation (void) //短信事件循环
{
{
if((signal_c==1)&(addr_e==1)) //1=已经进网
{
if((sms_t==0)&(request_msm_to==0))//没有正在发送的短信
{
if(sms_event[sms_to_event]!=0)//事件不空
{
request_msm_to=1; //标记发送短信
phone_n=0;
if(((sms_event[sms_to_event]==5)&(qu==1))|(sms_event[sms_to_event]==14))
{
phone_n=5;
qu=0;
}
}
else //事件空
{
if(sms_to_event<4)
{
sms_to_event++; //事件++
}
else
{
sms_to_event=0;
}
}
}
}
}
if((request_msm_to)&(signal_c)&(sms_t==0))//发送
{
if(eeprom_read_byte(&E_phone[phone_n][0])!='#')
{
sms_to(E_phone[phone_n]);//号码补为空
rest_timeout();//清timeout
sms_t=1;
}
else
{
phone_circulation();//号码循环
}
}
if(sms_t==1)//判断结果
{
if(ok)//短信成功|超时
{
sms_t=0;//发送结束
ok=0;
error=0;
rest_timeout();//清timeout
time_out_seconds=0;//清除time_out 计次器
phone_circulation();//号码循环
DelayMs(500);
}
if(timeout|error)
{
error=0;
ok=0;
time_out_seconds++;
//UART0_Transmitstr("错误次数");
//hex_bcd(time_out_seconds);//串口显示
sms_t=0;//发送结束
rest_timeout();//清timeout
signal_c=0;//重新检测信号
DelayMs(500);
}
if(time_out_seconds==3)//******************************************3
{
time_out_seconds=0;
phone_circulation();//号码循环
sms_t=0;//发送结束
DelayMs(500);
}
}
}
//*********************************************
//号码循环
void phone_circulation(void)
{
if(phone_n<4)
{
phone_n++;
//UART0_Transmitstr("读取号码");
//hex_bcd(phone_n);//串口显示
}
else
{
phone_n=0;
sms_event[sms_to_event]=0; //清除该事件
request_msm_to=0; //标记没发送短信
}
}
//**************************************************************************//
//**********************************************************//
//发送AT+CMGS=
//发送短信字长ASCII码
//发送短信中心相关数据
//发送接收的手机号码及相关数据
//发送协议及短信存活时间0008A7
//发送用户数据字长
//发送用户数据
//发送结束符号1A
//发送短信的完整步骤(号码1),把用户数据放入msg_buf,并以0x23结束
//用到的数组有 addr_buff;phone_buf;msg_buf;
/******************************************************/
// 发送中文短信
//
//
//
// 返回: 成功=1,失败=0
//*****************************************************//
void sms_to(uchar *phone)
{
uchar pdu[320];
if(sms_event[sms_to_event]!=0)//事件不空
{
switch(sms_event[sms_to_event])//事件代码
{
case 0: event_00();break;//
case 1: event_01();break;//用户号码,【控制返回值】1
case 2: event_02();break;
case 3: event_03();break;//新密码 【控制返回值】3
case 4: event_04();break;
case 5: event_05();break;//查询状态5
case 6: event_06();break;//新名称 【控制返回值】
case 7: event_07();break;
case 8: event_08();break;//上电报告92
case 9: event_09();break;//通讯故障
case 10: event_10();break;//指令错误 【控制返回值】
case 11: event_11();break;//短信电话1
case 12: event_12();break;//短信电话2
case 13: event_13();break;//短信电话3
case 14: event_14();break;//密码??
case 21: event_21();break;//电源检测
case 22: event_22();break;//系统断电
default:{break;}
}
ok=0;
error=0;
UART0_Transmitstr("AT+CMGS="); //发送AT+CMGS=
gsmEncodePdu(pdu,phone,msg_buf); //发送短信的字符长度 汉字X2+15))
CR; //发送回车换行
DelayMs(300);
UART0_Transmitstr(pdu); //发送PDU数据
UART0_TransmitByte(0x1a); //发送结束符号
CR;
DelayMs(200);
count30s=0;
time30s=0;
rest_timeout();//清timeout
wdt_reset();//复位看门狗
read_sms=0; //防止立即读短信
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -