GPS的获取采用串口3与AIR780进行AT指令收发的方式,AIR780有个DTU固件和AT固件,AT相对好开发一点,DTU是厂家那边写好内部”小系统“的方式,注册他们官网账户后进行网络设置(个人感觉它的工作比AT方式稳定点),但是AT指令很好二次开发,根据厂家给的技术手册里写命令即可完成功能与数据反馈。
STM32部分的AT指令发送我用的是ESP8266的AT收发函数esp8266_send_cmd(),重映射printf给串口三:
//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART3_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度
for(j=0;j<i;j++) //循环发送数据
{
while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART3,USART3_TX_BUF[j]);
}
}
u8 esp8266_send_cmd(u8 *cmd, u8 *ack, u16 waittime)//命令,应答,等待时间(10ms)
{
u8 res = 0;
USART3_RX_STA = 0;
u3_printf("%s\r\n", cmd); //发送AT命令
delay_ms(1);
if (ack && waittime) //需要等待应答
{
while (--waittime) //等待倒计时
{
delay_ms(10);
if (USART3_RX_STA&0X8000) //接收到期待的应答结果
{
if (esp8266_check_cmd(ack))
{
printf("%s\r\n", (u8 *)USART3_RX_BUF);
break; //得到有效数据
}
USART3_RX_STA = 0;
//strcpy((char *)USART3_RX_BUF, ""); // 清空接收缓存区
}
}
if (waittime == 0) res = 1;
}
return res;
}
发送完后AIR780会根据命令进行设置,在完成GPS搜星(大概几分钟,因此初始化命令跟其他外设初始化放一块,尽早搜星)后才会返回定位信息,定位信息中不仅包含经纬度,还包含了许多杂七杂八的信息。为此在接收到发回的字串里我们要从字符串数组USART3_RX_BUF中截取特定长度,放入duanxin1数组和duanxin2数组,方便后续的API拼接。
void hujiu(u8 jingdu[],u8 weidu[])
{
int a,b;
int flag=0;
GPS_GET();
for(a=43;a<52;a++)//截取纬度
{
Wei[flag]=USART3_RX_BUF[a];
flag++;
}
flag=0;
for(b=53;b<62;b++)截取经度
{
Jing[flag]=USART3_RX_BUF[b];
flag++;
}
flag=0;
duanxinfasong();
}
去高德地图开放平台申请个账号,里面有个官方提供的逆地理编码API,我们要想做到发送一个链接直接获取服务器终端结果响应得使用的GET形式的请求:高德地图https://ditu.amap.com/regeo?lng=116.473195&lat=39.993253对这段链接中的经度(前)和纬度(后)存入本地数组,与截取了的duanxin1和duanxin2数组内容进行拼接和替换,最后的结果数组通过AT指令发送给AIR780,其集成的GSM短信功能可以由此发送信息给特定手机号。以下课根据官方手册获取AT指令自行编写:
首先注册好网络 | ||||||||
AT+CSMS=1 | 设置短信服务 | |||||||
AT+CMGF=1 | 设置短信格式为TEXT | |||||||
AT+CSMP? | 查询当前TEXT短信参数 | |||||||
二选一 | AT+CSMP=17,167,0,0 | 设置为英文格式 | ||||||
二选一 | AT+CSMP=17,167,0,8 | 设置为中文格式 | ||||||
AT+CMGS="19312901312" | 设置联系人电话 | |||||||
hello Test | 编辑内容 | |||||||
1A | 以十六进制发送1A,确认发送 |
需要特别注意的是,AT指令里有个”确认发送“字码,这个字码需要以十六进制形式发送,故 u8 queren = 0x1A;USART_SendData(USART3,queren);放在最后。短信发送函数:
void duanxinfasong(void)
{
int a,b;
int result1,result2,result3,result4,result5;
u8 queren = 0x1A;
u8 duanxin1[]={"Warmming Click this URL to find your chirld: "};
u8 duanxin2[]={"https://ditu.amap.com/regeo?lng=116.473195&lat=39.993253"};
int flag = 0;//flag 的起始值也要根据接收到的GPS信息确定
//Êý¾ÝÆ´½Ó-----------------------------------------------------------------------------------------------Êý¾ÝÆ´½Ó
for(a=32;a<41;a++)
{
duanxin2[a] = Jing[flag];
flag++;
}
flag=0;
for (b=47;b<56;b++)
{
duanxin2[b] = Wei[flag];
flag++;
}
result1 = esp8266_send_cmd("AT+CSMS=1","ok",50);
result2 = esp8266_send_cmd("AT+CMGF=1","ok",50);
result3 = esp8266_send_cmd("AT+CSMP=17,167,0,0","ok",50);
esp8266_send_cmd("AT+CMGS=\"19312******\"" , "ok",50);//手机号
result4 = esp8266_send_cmd(duanxin1,"ok",50);
result5 = esp8266_send_cmd(duanxin2,"ok",50);
USART_SendData(USART3,queren);//确认发送
}
由此即可完成GPS获取并发送短信追踪定位,为方便用户查看结果我在GPS的功能函数尾端加上了主界面发送GPS的动态显示(就跟completed一样)进行提示。(对了,插的卡一定是移动卡才行,不知道是不是厂家未适配)(另外:使用XCOM进行调试的时候1A别勾选发送新行,不然识别错误,且1A记得要勾选十六进制发送)