中级会员
- 积分
- 498
- 金钱
- 498
- 注册时间
- 2015-10-3
- 在线时间
- 65 小时
|
楼主 |
发表于 2016-7-24 17:07:40
|
显示全部楼层
本帖最后由 残风乱了温柔 于 2016-7-24 17:16 编辑
共享一下自己的代码好了(主要是GPRS部分),有关的具体实现功能请参照1楼和9楼,这里不再赘述。注:所有注释掉的LED均为方便调试所用,可忽略。
#include "sim900a.h"
#include "usart2.h"
#include "delay.h"
#include "led.h"
#include "string.h"
#include "usart.h"
#include "stdlib.h"
#include "key.h"
#include "sys.h"
#include "stdio.h"
//ATK-SIM900A 各项测试(拨号测试、短信测试、GPRS测试)共用代码
//sim900a发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果
// 其他,期待应答结果的位置(str的位置)
u8* sim900a_check_cmd(u8 *str)
{
char *strx=0;
if(USART2_RX_STA&0X8000) //接收到一次数据了
{
USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符
strx=strstr((const char*)USART2_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
//向sim900a发送命令
//cmd:发送的命令字符串(不需要添加回车了),当cmd<0XFF的时候,发送数字(比如发送0X1A),大于的时候发送字符串.
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
// 1,发送失败
u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART2_RX_STA=0;
if((u32)cmd<=0XFF)
{
while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成
USART2->DR=(u32)cmd;
}else u2_printf("%s\r\n",cmd);//发送命令
if(ack&&waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART2_RX_STA&0X8000)//接收到期待的应答结果
{
if(sim900a_check_cmd(ack))break;//得到有效数据
USART2_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
//查看SIM900A模块的状态。
//返回值:
// 1: 发送AT指令出错
// 2: SIM卡出错。
// 3: 查询不到运营商
u8 sim900a_check_status(void){
if(sim900a_send_cmd("AT","OK",200)) return 1;//发送AT指令,判断返回是否是OK。
if(sim900a_send_cmd("AT+COPS?","OK",200)) return 2;// 查询运营商。
if(sim900a_send_cmd("AT+CSQ","OK",200))return 3;//查询信号质量;
return 0;
}
//SIM900A拨号测试
//其中sprintf是字符串格式化函数
//sprintf函数使用请参考http://baike.baidu.com/view/1295144.htm
u8 sim900a_call_test(u8* msisdn)
{
u8 status=0;
char cmd[20];
status=sim900a_check_status();
if(status) return status;
// LED0=!LED0;
// LED1=!LED1;
if(sim900a_send_cmd("AT+CLIP=1","OK",200))return 4; //设置来电显示
if(sim900a_send_cmd("AT+COLP=1","OK",200))return 5; //设置被叫号码显示
sprintf((char*)cmd,"ATD%s;",msisdn);//命令格式:ATDXXXX;
if(sim900a_send_cmd((u8*)cmd,"+COLP:",200)) return 6;//拨号失败
return 0;
}
//SIM900a挂机函数。
void sim900a_hangup_call(void)
{
sim900a_send_cmd("ATH","OK",200);//挂机
// LED0=!LED0;
// LED1=!LED1;
}
//SIM900A发英文短信测试。
//NOTE:此函数只能发送英文短信
//其中sprintf是字符串格式化函数
//sprintf函数
u8 si900a_sms_test(u8* msisdn)
{
u8 status=0;
// u8 *p7="There is an emergency!!!";
char cmd[20];
status=sim900a_check_status();
if(status) return status;
// LED0=!LED0;
// LED1=!LED1;
if(sim900a_send_cmd("AT+CMGF=1","OK",200))return 4; //设置文本模式
if(sim900a_send_cmd("AT+CSCS=\"GSM\"","OK",200))return 5; //设置TE字符集为UCS2
sprintf((char*)cmd,"AT+CMGS=\"%s\"",msisdn);//命令格式:AT+CMGS="XXX"
if(sim900a_send_cmd((u8*)cmd,">",200))return 6; //设置短消息文本模式参数
// u2_printf("%s","Dear baby,Happy new year!!!");//发送短信内容到GSM模块
// u2_printf("%s\r\n%s\r\n%s\r\n%s\r\n",etbuf,ftbuf,heartdisplay,p7);//发送短信内容到GSM模块
u2_printf("%s\r\n%s\r\n%s\r\n%s\r\n",etbuf,ftbuf,heartdisplay);//发送短信内容到GSM模块
if(sim900a_send_cmd((u8*)0X1A,"+CMGS:",1000)) return 7;//发送结束符
return 0;
}
//ATK-SIM900A GPRS主测试控制部分
u8 sim900a_gprs_test(u8 *p)
{
// u8 i;
u8 status=0;
u8 *p1="1\r\nfggh\r\nfggh";
//u8 *p2="6\r\nwertt\r\n";
// u8 *p3="3\r\nwerr\r\neverything is OK";
u16 timex=0;
u8 count=0;
u8 connectsta=0; //0,正在连接;1,连接成功;2,连接关闭;
u8 hbeaterrcnt=0; //心跳错误计数器,连续5次心跳信号无应答,则重新连接
status=sim900a_check_status();
if(status) return status;
sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",100); //关闭连接
sim900a_send_cmd("AT+CIPSHUT","SHUT OK",100); //关闭移动场景
if(sim900a_send_cmd("AT+CGCLASS=\"B\"","OK",1000))return 1; //设置GPRS移动台类别为B,支持包交换和数据交换
if(sim900a_send_cmd("AT+CGDCONT=1,\"IP\",\"CMNET\"","OK",1000))return 2;//设置PDP上下文,互联网接协议,接入点等信息
if(sim900a_send_cmd("AT+CGATT=1","OK",500))return 3; //附着GPRS业务
if(sim900a_send_cmd("AT+CIPCSGP=1,\"CMNET\"","OK",500))return 4; //设置为GPRS连接模式
if(sim900a_send_cmd("AT+CIPHEAD=1","OK",500))return 5; //设置接收数据显示IP头(方便判断数据来源)
if(sim900a_send_cmd("AT+CLPORT=\"TCP\",\"2000\"","OK",500))return 12;//设置本地 TCP 连接端口为 2000
if(sim900a_send_cmd("AT+CIPSTART=\"TCP\",\"XX.XXX.XX.XXX\",\"XXXX\"","OK",500))return 13;
//建立 TCP连接,连接到IP:XX.XXX.XX.XXX,连接端口为:XXXX.等待 TCP 连接成功建立,模块返回:OK
delay_ms(1000);
// LED0=!LED0; //红灯
// LED1=!LED1; //黄灯
if(sim900a_send_cmd("AT+CIPSEND",">",500)) //测试
{
printf("CIPSEND DATA:%s\r\n",p1);
u2_printf("%s",p1);
}
delay_ms(10);
// LED0=!LED0;
if(sim900a_send_cmd((u8*)0X1A,"SEND OK",1000))
{
// LED1=!LED1;
}
delay_ms(10000);
if(sim900a_send_cmd("AT+CIPSEND",">",500)==0)//登陆
{
printf("CIPSEND DATA:%s\r\n",p1);
u2_printf("%s",p1);
}
delay_ms(10);
// LED0=!LED0;
if(sim900a_send_cmd((u8*)0X1A,"SEND OK",1000)==0)
{
// LED1=!LED1;
}
delay_ms(1000);
// while(1)
// {
if(sim900a_send_cmd("AT+CIPSEND",">",500)==0)//发送消息
{
printf("CIPSEND DATA:%s\r\n",p);
u2_printf("3\r\nwerr\r\n%s\r\n%s\r\n%s\r\n%s\r\n",etbuf,ftbuf,heartdisplay,p);
connectsta=1;
}
else
connectsta=2;
delay_ms(10);
// LED0=!LED0;
if(sim900a_send_cmd((u8*)0X1A,"SEND OK",1000)==0)
{
// LED1=!LED1;
}
delay_ms(1000);
// for(i=0;i<5;i++)//,自动间隔时间发送,i<10时,间隔为12s;i<58时,间隔为1min
// {
// delay_ms(1000);
// }
if((timex%20)==0)
{
// LED0=!LED0;
count++;
if(connectsta==2||hbeaterrcnt>8)//连接中断了,或者连续8次心跳没有正确发送成功,则重新连接
{
sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",500); //关闭连接
sim900a_send_cmd("AT+CIPSHUT","SHUT OK",500); //关闭移动场景
if(sim900a_send_cmd("AT+CIPSTART=\"TCP\",\"XX.XXX.XX.XXX\",\"XXXX\"","OK",500))return 18;//尝试重新连接
connectsta=0;
hbeaterrcnt=0;
}
}
if(connectsta==0&&(timex%200)==0)//连接还没建立的时候,每2秒查询一次CIPSTATUS.
{
sim900a_send_cmd("AT+CIPSTATUS","OK",500); //查询连接状态
if(strstr((const char*)USART2_RX_BUF,"CLOSED"))connectsta=2;
if(strstr((const char*)USART2_RX_BUF,"CONNECT OK"))connectsta=1;
}
if(connectsta==1&&timex>=600)//连接正常的时候,每6秒发送一次心跳
{
timex=0;
if(sim900a_send_cmd("AT+CIPSEND",">",200)==0)//发送数据
{
sim900a_send_cmd((u8*)0X00,0,0); //发送数据:0X00
delay_ms(20); //必须加延时
sim900a_send_cmd((u8*)0X1A,0,0); //CTRL+Z,结束数据发送,启动一次传输
}else sim900a_send_cmd((u8*)0X1B,0,0); //ESC,取消发送
hbeaterrcnt++;
printf("hbeaterrcnt:%d\r\n",hbeaterrcnt);//方便调试代码
}
delay_ms(10);
if(USART2_RX_STA&0X8000) //接收到一次数据了
{
USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0; //添加结束符
printf("%s",USART2_RX_BUF); //发送到串口
if(hbeaterrcnt) //需要检测心跳应答
{
if(strstr((const char*)USART2_RX_BUF,"SEND OK"))hbeaterrcnt=0;//心跳正常
}
USART2_RX_STA=0;
}
timex++;
// }
return 0;
}
|
|