通过GSM模块发送经纬度求救信息。
本博客作为实验笔记,仅供学习交流。(转载请注明出处)
本实验通过GSM模块:SIM900a,实现向特定手机发送sos求救信号,并且利用GPS模块:微科VK2828U7G5LF,将经纬度信息同时发送到手机中。目前已经实现通过串口2发送短信到手机,通过串口3实现接受gps数据并解析至单片机(串口1已预留其他功能)。
本实验的不足之处:由于接收的卫星数越多,GPS信号越精确,定位误差越小,下一步打算通过一些算法实现gps经纬度定位的高精确度。
1 #include <stc15wxx.h> 2 #include <string.H> 3 #include <intrins.h> 4 #define uchar unsigned char 5 #define uint unsigned int 6 7 8 void Uart2Init(); 9 void Uart2Sends(uchar *str); 10 void Uart2BYTE(uchar temp); 11 uchar hand(uchar *ptr); 12 void clear_rec_data(); 13 void DelaySec(int sec); 14 uchar rec_data[40];//GSM模块返回数据数组 15 uchar rec_num; 16 void Uart3Init(); 17 uchar rec_gpsdata[51]={0};//Gps模块返回数据数组 18 uchar rec_gpsnum=0; 19 uchar ok[]=",A,"; 20 uchar gpsdata[17]={0}; 21 uchar tn,p,gps_ok=0; 22 long tm; 23 24 void Init () 25 { 26 P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口 27 P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口 28 P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口 29 } 30 //串行口连续发送char型数组,遇到终止号/0将停止 31 void Uart1Init(void) //9600bps@11.0592MHz 32 { 33 SCON = 0x50; //8位数据,可变波特率 34 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 35 AUXR |= 0x04; //定时器2时钟为Fosc,即1T 36 T2L = 0xE0; //设定定时初值 37 T2H = 0xFE; //设定定时初值 38 AUXR |= 0x10; //启动定时器2 39 EA=1;//开总中断 40 ES=1;//开串行口中断 41 } 42 43 void Uart1Sends(uchar *str) 44 { 45 while(*str!='\0') 46 { 47 SBUF=*str; 48 while(!(SCON & 0x02));//等待发送完成信号(TI=1)出现 49 SCON &= ~0x02; // 清中断标志 50 str++; 51 } 52 } 53 54 void main() 55 { 56 uchar i=0; 57 Init(); 58 Uart1Init(); 59 Uart2Init(); 60 Uart3Init(); 61 gps_ok=0; 62 63 while(1) 64 { 65 if(strstr(rec_gpsdata,ok)>0)//串口3GPS数据解析******************************************************************************************************** 66 { 67 gpsdata[0]=rec_gpsdata[7]; //纬度解析 68 gpsdata[1]=rec_gpsdata[8]; 69 gpsdata[2]='.'; 70 tm=(10000*(rec_gpsdata[9]-0x30)+1000*(rec_gpsdata[10]-0x30)+100*(rec_gpsdata[12]-0x30)+10*(rec_gpsdata[13]-0x30)+(rec_gpsdata[14]-0x30))/6; 71 gpsdata[3]=tm/1000+0x30; //更新数据接口数据 72 gpsdata[4]=(tm%1000)/100+0x30; 73 gpsdata[5]=(tm%100)/10+0x30; 74 if(tm%10==9) 75 gpsdata[6]=tm%10+0x30; 76 else gpsdata[6]=tm%10+0x31; 77 gpsdata[7]=','; 78 tn=20; 79 gpsdata[8]=rec_gpsdata[tn]; //经度解析 80 gpsdata[9]=rec_gpsdata[tn+1]; 81 gpsdata[10]=rec_gpsdata[tn+2]; 82 gpsdata[11]='.'; 83 tm=(10000*(rec_gpsdata[tn+3]-0x30)+1000*(rec_gpsdata[tn+4]-0x30)+100*(rec_gpsdata[tn+6]-0x30)+10*(rec_gpsdata[tn+7]-0x30)+(rec_gpsdata[tn+8]-0x30))/6; 84 gpsdata[12]=tm/1000+0x30; 85 gpsdata[13]=(tm%1000)/100+0x30; 86 gpsdata[14]=(tm%100)/10+0x30; 87 gpsdata[15]=tm%10+0x31; 88 gpsdata[16]='\n'; 89 gps_ok=1; 90 break; 91 } 92 else gps_ok=0; 93 } 94 if(gps_ok==1) 95 { 96 Uart2Sends("AT\r\n"); //同步波特率,如果将模块配置固定波特率,此条指令就不需要发了 97 while(!hand("OK")) 98 { 99 clear_rec_data(); 100 i++; 101 Uart2Sends("AT\r\n");// 102 DelaySec(1);//延时 103 if(i>=5) 104 { 105 break; 106 } 107 } 108 clear_rec_data();//删除存储的GSM模块返回的数据,以便于以后继续判断 109 DelaySec(1);//延时 110 P0=0x00;//初始化和检验完毕,led灯产生信号。 111 Uart2Sends("AT+CSCS=\"GSM\"\r\n"); // 112 DelaySec(1);//延时 113 Uart2Sends("AT+CSCA?\r\n"); //短信中心号码 114 DelaySec(1);//延时 115 Uart2Sends("AT+CMGF=1\r\n"); //方式1 116 DelaySec(1);//延时 117 Uart2Sends("AT+CMGS=\"156-------\"\r\n"); //此处修改短信接收方电话号 118 DelaySec(1);//延时 119 Uart2Sends("SOS:I need help! My position is https;//mo.amap.com/?q="); //此处修改短信内容 120 Uart2Sends(gpsdata); 121 DelaySec(1);//延时 122 Uart2BYTE(0X1A); 123 DelaySec(1);//延时 124 //拨打电话代码 125 Uart2Sends("ATD156--------;\r\n"); //拨打电话 126 } 127 } 128 /* 129 串口2,sim900a通信串口 130 */ 131 132 void Uart2Init() //9600bps@11.0592MHz 133 { 134 135 S2CON = 0x50; //8位数据,可变波特率 136 AUXR |= 0x04; //定时器2时钟为Fosc,即1T 137 T2L = 0xE0; //设定定时初值 138 T2H = 0xFE; //设定定时初值 139 AUXR |= 0x10; //启动定时器2 140 EA=1;//开总中断 141 ES=1;//开串行口中断 142 IE2=0x01; 143 } 144 /** 145 interrupt 8 interrupt 17 interrupt 18:串口2 3 4的串口号 146 **/ 147 void Serial_interrupt() interrupt 8 using 1 148 { 149 uchar temp; 150 if(S2CON & 0x01) // 接收中断标志判断 151 { 152 S2CON &= ~0x01;//等价于RI=0 153 154 temp=S2BUF; 155 rec_data[rec_num++]=temp; 156 if(rec_num>=50) 157 rec_num=0; 158 else 159 ; 160 //RI=0;//接收中断信号清零,表示将继续接收 161 } 162 163 164 } 165 166 //串行口连续发送char型数组,遇到终止号/0将停止 167 void Uart2Sends(uchar *str) 168 { 169 while(*str!='\0') 170 { 171 S2BUF=*str; 172 while(!(S2CON & 0x02));//等待发送完成信号(TI=1)出现 173 S2CON &= ~0x02; // 清中断标志 174 str++; 175 } 176 } 177 void Uart2BYTE(uchar temp) 178 { 179 S2BUF=temp; 180 while(!(S2CON & 0x02));//等待发送完成信号(TI=1)出现 181 S2CON &= ~0x02; // 清中断标志 182 183 } 184 185 uchar hand(uchar *ptr) 186 { 187 if(strstr(rec_data,ptr)!=NULL) 188 return 1; 189 else 190 return 0; 191 } 192 193 void clear_rec_data() 194 { 195 uchar i; 196 for(i=0;i<strlen(rec_data);i++) 197 { 198 rec_data[i]='0'; 199 } 200 rec_num=0; 201 } 202 //延时函数1s钟 203 void DelaySec(int sec) 204 { 205 unsigned char i, j, k,m; 206 207 for(m=0; m<sec; m++) 208 { 209 _nop_(); 210 _nop_(); 211 i = 43; 212 j = 6; 213 k = 203; 214 do 215 { 216 do 217 { 218 while (--k); 219 } while (--j); 220 } while (--i); 221 } 222 } 223 /* 224 GPS 模块,串口3通信 225 */ 226 // $GPGLL,2236.91284,N,11403.24705,E,060826.00,A,D*66,gps返回数据的示例 227 void Uart3Init() //9600bps@11.0592MHz 228 { 229 S3CON = 0x10; //8位数据,可变波特率 230 S3CON &= 0xBF; //串口3选择定时器2为波特率发生器 231 AUXR |= 0x04; //定时器2时钟为Fosc,即1T 232 T2L = 0xE0; //设定定时初值 233 T2H = 0xFE; //设定定时初值 234 AUXR |= 0x10; //启动定时器2 235 EA=1;//开总中断 236 IE2 |= 0x08; // 串口3中断打开 237 } 238 void GPSreturn(void) interrupt 17 239 { 240 uint temp; 241 if (S3CON & 0x01) // 接收中断标志位 242 { 243 S3CON &= ~0x01; // 清中断标志 244 temp=S3BUF; 245 if(rec_gpsnum<=50) 246 rec_gpsdata[rec_gpsnum++]=temp; 247 if(rec_gpsnum>50) 248 rec_gpsnum=0; 249 } 250 } 251 252 253 254
版权声明:本文为wang-zefeng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。