基于51单片机GPS定位系统GSM短信上报设计方案原理图
系統功能分析
(末尾附文件)
系統功能分析
本系統由STC89C52單片機電路+GPS模塊電路+GSM模塊SIM800A+指示燈電路+電源電路組成。
1、系統上電后,系統向特定手機號碼發送短信,短信內容為系統的當前經緯度信息。40s左右發一次。
2、如果需要立刻發送經緯度信息,直接按板載按鍵即可立刻發送經緯度數據,不用等待40s。
3、短信發送及初始化有狀態指示燈指示。
4、GSM模塊是SIM800A,該模塊和SIM900A電路程序完全兼容外觀外形一模一樣。
3.1.2系統總體結構
本系統具體框圖如下圖所示:
模塊電路的設計
5V電源電路設計
本系統選擇5V直流電源作為系統總電源,為整個系統供電,電路簡單、穩定。DC為電源的DC插座,可以直接接USB電源線,一端插在DC插座上,另外一端可以插在5V電源上,如電腦USB、充電寶、手機充電器等等。LED為紅色LED燈,作為系統是否有點的指示燈,電阻為1K電阻,起到限流作用,保護LED燈,以防電流過大燒壞LED燈。SW為自鎖開關,開關按下后,紅燈亮,此時系統電源5V直流輸出。開關再次按下后,紅燈滅,此時系統電源無5V電源輸出。
GSM_SIM800A模塊電路設計
GSM模塊,是將GSM射頻芯片、基帶處理芯片、存儲器、功放器件等集成在一塊線路板上,具有獨立的操作系統、GSM射頻處理、基帶處理并提供標準接口的功能模塊。GSM模塊具有發送SMS短信,語音通話,GPRS數據傳輸等基于GSM網絡進行通信的所有基本功能。簡單來講,GSM模塊加上鍵盤、顯示屏和電池,就是一部手機。
SIM800A是SIMCOM公司推出的一款高性能工業級 GSM/GPRS 模塊, 該模塊具有極高的性價比,在雙頻的市場中占據極大份額。
GSM_SIM800A模塊采用高性能工業級GSM/GPRS模塊:SIM800A,工作頻段:GSM900/1800MHz。硬件設計在官方設計上加以優化,采用高效開關電源供電,SIM卡采用主流的卡座,質量更堅固。GSM_SIM800A模塊在外圍硬件的設計上參考了SIM800A 模塊的硬件設計指南,對板子的電源、保護和抗干擾上做足了功夫。電源采用開關電源模塊供電,電源利用效率高。
系統軟件設計
#include <reg52.h> #include <intrins.h> #include <stdio.h> #include "delay.h"/**The UART1 stage1**/ #define STAGE_SOHE 0x01 #define STAGE_TYPE 0x02 #define STAGE_NONE 0x03 #define STAGE_DATA 0x04#define INIT 0xFF #define TRUE 0x00 #define FALSE 0x01sbit LED = P1^0;//指示燈 sbit key =P2^0;//按鍵unsigned char Lin0_No[13]="N:000.000000";//顯示北緯 unsigned char Lin1_Ea[12]="E:000.000000";//顯示東經unsigned long xdata time_20ms=0;unsigned char xdata devide_flag; //GPS數據逗號分隔符 unsigned char xdata speed_end; //收速度數據結束標志 unsigned char xdata dir_end; //收方向角數據結束標志 unsigned char xdata sysmode_GPS=FALSE; //gps有效無效標志 unsigned char xdata ew_flag; //東西標志 unsigned char xdata ns_flag; //南北標志unsigned char xdata gps_infor_weijing[17]; //暫存經緯度 格式是以度分秒的是形式 unsigned char xdata gps_infor_speed[4]; //暫存速率 unsigned char xdata gps_infor_time[6]; //時間暫存 unsigned char xdata gps_infor_date[6]; //日期暫存 unsigned char xdata gps_infor_dir[3]; //方向暫存unsigned char xdata recv1_step=STAGE_SOHE; //串口接收指令步驟 unsigned char xdata uart1_r_buf; //串口的緩存 unsigned char xdata rev1_buf_busy; //串口接收忙碌標志 unsigned char xdata temp1_buf[85]; //串口接收數組 unsigned int xdata record1=0; //串口接收計數 unsigned char i ;unsigned char dealGpsMes=FALSE; //gps定時處理標志unsigned char reportTime = 0;//短信上報時間 計數void Init_Timer0(void);//函數聲明 void gpsDealfun(void); void uartSendStr(unsigned char *s,unsigned char length); void UART_Init(void); void uartSendByte(unsigned char dat);void main (void) {Init_Timer0(); //定時器0初始化UART_Init(); //串口初始化LED = 0; //打開ledkey = 1;for(i=0;i<50;i++) //延時有助于穩定{DelayMs(100);} uartSendStr("aAT+CMGF=1\r\n",12); //初始化gsm模塊for(i=0;i<7;i++) //延時有助于穩定{DelayMs(100);}uartSendStr("AT+CSCS=\"GSM\"\r\n",15);for(i=0;i<7;i++) //延時有助于穩定{DelayMs(100);}LED =1;while(1) //主循環{if(dealGpsMes==TRUE) //gps信息處理{dealGpsMes=FALSE; //清除標志gpsDealfun(); //gps信息處理函數}if((reportTime >= 20)||(key == 0)) //2s計數一次{reportTime = 0;LED=0; //打開leduartSendStr("AT+CMGF=1\r\n",11); //設置字符集for(i=0;i<5;i++){DelayMs(100);}uartSendStr("AT+CSCS=\"GSM\"\r\n",15); //設置for(i=0;i<5;i++){DelayMs(100);}uartSendStr("AT+CMGS=\"+8618105140357\"\r\n",26); //可以修改電話號碼 // uartSendStr("AT+CMGS=\"+8617686988225\"\r\n",26); //可以修改電話號碼for(i=0;i<3;i++){DelayMs(100);} uartSendStr(Lin0_No,13);//發送短信內容 在gps數據處理情況 uartSendStr(Lin1_Ea,12); for(i=0;i<2;i++){DelayMs(100);}uartSendByte(0x1a); //發送for(i=0;i<40;i++){DelayMs(100);}LED =1; //關閉led}DelayMs(5); } }void gpsDealfun(void) {unsigned char num=0;unsigned long Mid_Du; //中間變量 暫存經緯度的整數部分 即度unsigned long Mid_Fen; //中間變量 暫存經緯度的小數部分 即分 gps原始數據是度分秒格式unsigned long Mid_Vale; 中間變量 暫存經緯度 并將其擴大了10000000倍if(sysmode_GPS==TRUE) //檢測gps是否有效數據{sysmode_GPS=FALSE; //清除有效位Mid_Du=(gps_infor_weijing[0]-0x30)*10000000+(gps_infor_weijing[1]-0x30)*1000000; //處理緯度 暫存整數部分擴大10000000Mid_Fen=(gps_infor_weijing[2]-0x30)*10000000+(gps_infor_weijing[3]-0x30)*1000000+(gps_infor_weijing[4]-0x30)*100000+(gps_infor_weijing[5]-0x30)*10000+(gps_infor_weijing[6]-0x30)*1000+(gps_infor_weijing[7]-0x30)*100; //處理緯度 暫存小數部分擴大10000000 Mid_Fen=Mid_Fen/60; //分秒換算為小數位Mid_Vale=Mid_Du+Mid_Fen; //最終緯度 格式為000.00000000 非度分秒格式Lin0_No[0]='N';Lin0_No[1]='N'; Lin0_No[2]=':'; Lin0_No[3]='0'; Lin0_No[4]=Mid_Vale/10000000+0x30; //將處理后的緯度填入字符串 并打印顯示Lin0_No[5]=(Mid_Vale/1000000)%10+0x30;Lin0_No[6]='.';Lin0_No[7]=(Mid_Vale/100000)%10+0x30;Lin0_No[8]=(Mid_Vale/10000)%10+0x30;Lin0_No[9]=(Mid_Vale/1000)%10+0x30;Lin0_No[10]=(Mid_Vale/100)%10+0x30;Lin0_No[11]=(Mid_Vale/10)%10+0x30;Lin0_No[12]=Mid_Vale%10+0x30;Mid_Du=(gps_infor_weijing[8]-0x30)*100000000+(gps_infor_weijing[9]-0x30)*10000000+(gps_infor_weijing[10]-0x30)*1000000; //處理經度 暫存整數部分擴大10000000Mid_Fen=(gps_infor_weijing[11]-0x30)*10000000+(gps_infor_weijing[12]-0x30)*1000000+(gps_infor_weijing[13]-0x30)*100000+(gps_infor_weijing[14]-0x30)*10000+(gps_infor_weijing[15]-0x30)*1000+(gps_infor_weijing[16]-0x30)*100; //處理經度 暫存小數部分擴大10000000 Mid_Fen=Mid_Fen/60; //分秒換算為小數位Mid_Vale=Mid_Du+Mid_Fen; //最終經度 格式為000.00000000 非度分秒格式Lin1_Ea[0]='E'; Lin1_Ea[1]=':'; Lin1_Ea[2]=Mid_Vale/100000000+0x30; //將處理后的經度填入字符串 并打印顯示Lin1_Ea[3]=(Mid_Vale/10000000)%10+0x30;Lin1_Ea[4]=(Mid_Vale/1000000)%10+0x30;Lin1_Ea[5]='.';Lin1_Ea[6]=(Mid_Vale/100000)%10+0x30;Lin1_Ea[7]=(Mid_Vale/10000)%10+0x30;Lin1_Ea[8]=(Mid_Vale/1000)%10+0x30;Lin1_Ea[9]=(Mid_Vale/100)%10+0x30;Lin1_Ea[10]=(Mid_Vale/10)%10+0x30;Lin1_Ea[11]=Mid_Vale%10+0x30;}else{Lin1_Ea[0]='G'; //無gps信號情況下 打印正在連接Lin1_Ea[1]='P'; Lin1_Ea[2]='S'; Lin1_Ea[3]=' '; /*將處理后的緯度填入字符串 并打印顯示*/Lin1_Ea[4]='L';Lin1_Ea[5]='I';Lin1_Ea[6]='N';Lin1_Ea[7]='K';Lin1_Ea[8]='I';Lin1_Ea[9]='N';Lin1_Ea[10]='G';Lin1_Ea[11]='.';Lin1_Ea[12]='.';Lin1_Ea[13]='.';for(i=0;i<14;i++){Lin0_No[i]=Lin1_Ea[i];}} // DelayMs(10); // SendStr(Lin0_No,12); // DelayMs(10); // SendStr(Lin1_Ea,12); }void Init_Timer0(void) {TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響 TH0 = 0x0B8; //11.0592M 20msTL0 = 0x00;EA=1; //總中斷打開ET0=1; //定時器中斷打開TR0=1; //定時器開關打開 }void Timer0_isr(void) interrupt 1 {TH0 = 0x0B8; //11.0592M 20msTL0 = 0x00;time_20ms++;if(time_20ms%100==0) //2s左右處理一次{dealGpsMes=TRUE; reportTime++;} }void UART_Init(void) {SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收 TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重裝TH1 = 0xFD; // TH1: 重裝值 9600 波特率 晶振 11.0592MHz TR1 = 1; // TR1: timer 1 打開 EA = 1; //打開總中斷ES = 1; //打開串口中斷 }void uartSendByte(unsigned char dat) {unsigned char time_out;time_out=0x00;SBUF = dat; //將數據放入SBUF中while((!TI)&&(time_out<100)) //檢測是否發送出去{time_out++;DelayUs2x(10);} //未發送出去 進行短暫延時TI = 0; //清除ti標志 }void uartSendStr(unsigned char *s,unsigned char length) {unsigned char NUM;NUM=0x00;while(NUM<length) //發送長度對比{uartSendByte(*s); //放松單字節數據s++; //指針++NUM++; //下一個++} }void UART_SER (void) interrupt 4 //串行中斷服務程序 {if(RI) //判斷是接收中斷產生{RI=0; //標志位清零uart1_r_buf=SBUF; //提取buf中的值rev1_buf_busy=0x00; //判別 放置break問題switch(recv1_step){case STAGE_SOHE: if(uart1_r_buf == '$') //判斷接收到了$ 具體原因參考GPS標準協議NMEA0183{rev1_buf_busy=0x01;if(uart1_r_buf == '$') //再次查看接收的是否是${recv1_step=STAGE_TYPE; //跳轉到下一步record1=0; //計數清零}else{recv1_step=STAGE_SOHE; //恢復初始化record1=0;}}break;case STAGE_TYPE: if(rev1_buf_busy == 0x00){rev1_buf_busy=0x01;temp1_buf[record1]=uart1_r_buf;record1++;if(record1 == 0x05){ //查看$GPRMC開頭的命令行if((temp1_buf[0] == 'G') && (temp1_buf[1] == 'P') && (temp1_buf[2] == 'R') && (temp1_buf[3] == 'M') && (temp1_buf[4] == 'C')){recv1_step=STAGE_NONE; //跳轉到下一步record1=0;} else{recv1_step=STAGE_SOHE;//恢復初始化record1=0;}}}break;case STAGE_NONE: if(rev1_buf_busy == 0x00)//接收命令格式:$GPRMC,054347.00,A,3202.04770,N,11846.23632,E,0.000,0.00,221013,,,A*67{rev1_buf_busy=0x01;record1++;if((record1 > 0x01) && (record1 < 0x08)) {gps_infor_time[record1-2]=uart1_r_buf; //時間存儲 }if((uart1_r_buf == ',') && (record1 > 0x07) && (record1 < 0x010)) //||((uart1_r_buf == ',') && (record1==0x02)){record1=0xcc;}if(record1 == 0xcd){record1=0;devide_flag=2;speed_end=0x00;dir_end=0x00;if(uart1_r_buf == 'A') //gps收到數據 且有效{ recv1_step=STAGE_DATA; //跳轉到下一步}else{sysmode_GPS=FALSE;recv1_step=STAGE_SOHE; //無效恢復初始化record1=0;}}}break;case STAGE_DATA: if(rev1_buf_busy == 0x00){rev1_buf_busy=0x01;record1++;if(uart1_r_buf == ',') //判斷逗號{ devide_flag++; //逗號次數記錄record1=0;}if(devide_flag == 3){if((record1 > 0) && (record1 < 5)){gps_infor_weijing[record1-1]=uart1_r_buf; //存儲經緯度 此處為緯度 }if((record1 > 5) && (record1 < 10)) //跳過小數點的存儲{gps_infor_weijing[record1-2]=uart1_r_buf; //存儲經緯度 此處為緯度 }}if(devide_flag == 4){if(record1 > 0){ns_flag=uart1_r_buf; //接收緯度NS標志}}if(devide_flag == 5){if((record1 > 0) && (record1 < 6)){gps_infor_weijing[record1+7]=uart1_r_buf; //存儲經緯度 此處為緯度 }if((record1 > 6) && (record1 < 11)) //跳過小數點的存儲{gps_infor_weijing[record1+6]=uart1_r_buf; //存儲經緯度 此處為經度 }}if(devide_flag == 6){if(record1 > 0){ew_flag=uart1_r_buf; //經度度 EW標志}}if(devide_flag == 7){if(speed_end == 0x00){if((record1 > 0) && (uart1_r_buf != '.')){gps_infor_speed[record1-1]=uart1_r_buf; //接收速率}else if(uart1_r_buf == '.'){record1--;speed_end=0xff;}}else if(speed_end == 0xff){speed_end=0xfe;gps_infor_speed[record1-1]=uart1_r_buf;gps_infor_speed[3]=gps_infor_speed[record1-1];gps_infor_speed[2]=gps_infor_speed[record1-2];if(record1 > 2){gps_infor_speed[1]=gps_infor_speed[record1-3];}else{gps_infor_speed[1]=0x30;}if(record1 > 3){gps_infor_speed[0]=gps_infor_speed[record1-4];}else{gps_infor_speed[0]=0x30;}}}if(devide_flag == 8){if(dir_end == 0x00){if((record1 > 0) && (uart1_r_buf != '.')){gps_infor_dir[record1-1]=uart1_r_buf; //存儲方向}else if(uart1_r_buf == '.'){record1--;dir_end=0xff;}}else if(dir_end == 0xff){dir_end=0xfe;if(record1 == 2){gps_infor_dir[2]=gps_infor_dir[record1-2];gps_infor_dir[1]=0x30;gps_infor_dir[0]=0x30;}if(record1 == 3){gps_infor_dir[2]=gps_infor_dir[record1-2];gps_infor_dir[1]=gps_infor_dir[record1-3];gps_infor_dir[0]=0x30;}}}if(devide_flag == 9){if((record1 > 0) && (record1 < 7)){gps_infor_date[record1-1]=uart1_r_buf;}}if(uart1_r_buf == 0x0d){recv1_step=STAGE_SOHE; //接收完成 并信號確定 record1=0; //恢復初始化狀態 為下一次準備devide_flag=0;sysmode_GPS=TRUE; //置位 GPS 信號為正確}}break;}}if(TI) //如果是發送標志位,清零TI=0; }鏈接:https://pan.baidu.com/s/1FSMLsaumjvjNPuRfHn4CWw
提取碼:kpye
總結
以上是生活随笔為你收集整理的基于51单片机GPS定位系统GSM短信上报设计方案原理图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win系统如何修改远程桌面端口3389
- 下一篇: Mysql的用户与权限管理