通過GSM模塊發送經緯度求救信息。
- 2020 年 4 月 17 日
- 筆記
本博客作為實驗筆記,僅供學習交流。(轉載請註明出處)
本實驗通過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) //[email protected] 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() //[email protected] 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() //[email protected] 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