基于STM32开发板的GPS定位模块设计.docx
《基于STM32开发板的GPS定位模块设计.docx》由会员分享,可在线阅读,更多相关《基于STM32开发板的GPS定位模块设计.docx(22页珍藏版)》请在冰点文库上搜索。
基于STM32开发板的GPS定位模块设计
生产实习设计报告
设计题目:
基于GPS模块的定位装置
生产组长:
王海昕
设计组长:
孙振邦
小组成员:
王洪振、唐政亮、帖小龙、宋劲草、宋晓林
苏刚、孙晓龙、史俊、赵若曦
实习日期:
2012年8月27日-9月15日
一、概述
本设计基于STM32F10开发板,结合iTrax03-02型GPS接收机,实现GPS模块与STM32的通信;通过GPS模块实现定位,STM32对GPS模块传入的数据进行读取和处理,将得到定位信息在OLED显示。
该定位装置还有如下附加功能:
SD卡数据存储功能,定位状态显示(卫星颗数等);可通过RS232串口传输坐标和时间至PC机,并通过上位机软件实现路径计算和网络地图定位。
二、总体设计
1.总体系统结构
2.功能实现
⑴.经纬度测定,海拔高度测定
⑵.速度计算与方向指示
⑶.SD卡定时存储信息⑷.上位机制作及路径计算
3.人员分工
孙振邦、王海昕完成源程序的编写,以及代码的修改、编译、下载、调试等工作;
宋劲草、宋晓林、苏刚负责GPS数据编码转换编程;
王洪振、帖小龙、唐政亮负责串口数据传输、SD卡定时存储设置;
史俊、赵若曦、孙晓龙负责上位机界面设计和各项功能的验证。
三、关键模块设计
⑴.GP模块
iTrax03-02型GPS接收机是根据芬兰FASTRA公司的GPS模块进行了电平转换、通信接口等电路设计后生产的一款GPS(OEM接
收机产品。
该产品通过底板上9pin排线与计算机串口直接通信,定位后即可输出载体的经纬度信息、时间信息、速度信息等。
(2)GPS定位数据格式解析
数据形式:
$GPGGA,hhmmss.dd,xxmm.dddd,,yyymm.dddd,,v,ss,d.d,h.h,M,g.g,M,a.a,xxxx*hh
名称
说明
$GPGGA
GGA消息协议头
hhmmss.dd
UTC时间
xxmm.dddd
纬度信息,度、分格式
纬度半球N(北半球)或S(南半球)
yyymm.dddd
经度信息,度、分格式
纬度半球E(东经)或E(西经)
V
判断是否已疋位,疋位为1,未疋位为0
ss
使用的解算卫星的数量一般0-12颗
d.d
HDO水平精度因子
h.h
海拔高度
M
单位米
g.g
WGS-846表面与水平面的差值
M
单位米
a.a
空
xxxx
空
hh
校验及固定包尾
⑵.OLE显示模块
OLED使用的控制器为SSD1305可通过写入不同的命令字来设置对比度、显示开关、电荷泵、页地址等。
OLE被配置为使用I2C的方式。
I2C的地址二进制位为0111100X
16进制为0x78(写地址),0x79(读地址)。
OLE的Reset平时应该拉高,在初始化的时候,应该有一个从低电平到高电平的跳变。
使用的MC端口为
PB6CLKI2C
PB7SDAI2C
PE6RESET(低有效)
(3)距离计算功能公式、原理什么的
(4).串行通信模块
RS232勺电平转换芯片为MAX232CE外部接口为DB9有两个LE[指旨示
灯,TXD用来显示接受到数据,RX用来显示正在发送数据。
对外接口为DB接口,定义为:
2RXD,3TXD,5GND因此,基板可以通过串口线直接连接到PCM,和PC机进行通信。
使用的MC端口为:
PD5UART2_TX(Remap)
PD6UART2_RX(remap)
四、测试结果
1.开机上电后在数据有效的情况下进入定位信息显示模式;
2.进入定位信息显示模式后,OLEL显示出当前位置经度、纬度、海
拔高度、移动速度、移动方向、卫星显示颗数
3.设定中断时间后,数据会自动存储至SD卡;
4.通过RS23串口与PCS讯后可以通过上位机软件打开该位置的谷歌地图显示,并且计算路径长度。
附录
定位测试数据
保存数据如下:
$GPGSV,3,1,10,01,35,047,32,04,30,244,24,08,12,207,27,09,06,318,12*71$GPGSV,3,2,10,11,20,063,36,17,54,320,39,20,54,099,23,27,10,309,26*7F$GPGSV,3,3,10,28,78,225,29,32,34,062,26*75
$GPRMC,071738.50,A,3609.4075,N,12029.3426,E,0.00,302.3,090912,5.8,W,A*15
$GPGGA,071738.50,3609.4075,N,12029.3426,E,1,05,2.0,115.0,M,5.5,M,,*50$PFST,FOM,6*63
$GPGSA,A,3,01,08,11,17,28,,,,,,,,2.9,2.0,2.1*3D$GPGSV,3,1,10,01,35,047,32,04,30,244,24,08,12,207,27,09,06,318,12*71$GPGSV,3,2,10,11,20,063,36,17,54,320,39,20,54,099,23,27,10,309,26*7F
$GPGSV,3,3,10,28,78,225,29,32,34,062,26*75
$GPRMC,071739.50,A,3609.4075,N,12029.3428,E,0.00,302.3,090912,5.8,W,A*1A
$GPGGA,071739.50,3609.4075,N,12029.3428,E,1,07,2.0,115.0,M,5.5,M,,*5D$PFST,FOM,24*53
$GPGSA,A,3,01,04,08,11,17,27,28,,,,,,2.9,2.0,2.1*3C$GPGSV,3,1,10,01,35,047,31,04,30,244,24,08,12,207,27,09,06,318,12*72$GPGSV,3,2,10,11,20,063,36,17,54,320,38,20,54,099,23,27,10,309,25*7D
$GPGSV,3,3,10,28,78,225,27,32,34,062,26*7B
$GPRMC,071740.50,A,3609.4074,N,12029.3429,E,0.00,302.3,090912,5.8,W,A*14
$GPGGA,071740.50,3609.4074,N,12029.3429,E,1,07,1.8,115.0,M,5.5,M,,*58$PFST,FOM,20*57
$GPGSA,A,3,01,04,08,11,17,27,28,,,,,,2.7,1.8,2.0*38$GPGSV,3,1,10,01,35,047,31,04,30,244,24,08,12,207,27,09,06,318,12*72$GPGSV,3,2,10,11,20,063,36,17,54,320,38,20,54,099,23,27,10,308,25*7C
$GPGSV,3,3,10,28,78,225,27,32,34,062,26*7B
$GPRMC,071741.50,A,3609.4074,N,12029.3431,E,0.00,302.3,090912,5.8,W,A*1C
附录二
关键程序代码
Main.c:
#include"includes.h"
#include"led.h"
#include
GPIO_InitTypeDefGPIO_InitStructure;
USART_InitTypeDefUSART_InitStructure;
NVIC_InitTypeDefNVIC_InitStructure;
voidUSART1_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
RCC_APB2Periph_USART1,ENABLE);
//定义UART1TX(PA.09)脚为复用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//IOGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//IOGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//IOGPIO_Init(GPIOA,&GPIO_InitStructure);////定义USART1Rx(PA.10)为悬空输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//IO
口的第九脚
口速度
口复用推挽输出
初始化串口1输出10口
口的第十脚
GPI0_InitStructure.GPI0_Mode=GPI0_Mode_IN_FL0ATING;//I0
口悬空输入
GPI0_Init(GPI0A,&GPI0_InitStructure);//
初始化串口1输入10口
//串口参数配置
USART_InitStructure.USART_BaudRate=4800;115200
//设置波特率为
USART_InitStructure.USART_WordLength位
=USART_WordLength_8b;//
设置数据位为8
设置停止位为1
无奇偶校验
USART_InitStructure.USART_StopBits=USART_StopBits_1;//位
USART_InitStructure.USART_Parity=USART_Parity_No;//
USART_InitStructure.USART_HardwareFlowControl=
USART_HardwareFlowControl_None;//没有硬件流控
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//发送
与接收
//完成串口COM的时钟配置、GPIO配置,根据上述参数初始化并使能
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能串口1接收中断
USART_Cmd(USART1,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
数据模式
0:
缓存数据无效。
NVIC_Init(&NVIC_InitStructure);
}
intmain(void)
{
delay_init(72);
GUI_Init();
GUI_SetBkColor(GUI_BLUE);
GUI_Clear();
USART1_Init();while
(1)
{
gps_display();
}
}
GPS.c:
#include"includes.h"
//GPS数据存储数组//unsignedcharJD[11];
unsignedcharJD_a;
unsignedcharWD[10];
unsignedcharWD_a;
unsignedchartime[10];
unsignedcharspeed[6]={0};//unsignedcharspeed2[6]={0};
unsignedcharhigh[6];
unsignedcharhaiba[6];
unsignedcharangle[6];
unsignedcharuse_sat[3];
unsignedchartotal_sat[3];//unsignedcharlock;
//串口中断需要的变量unsignedcharseg_count;unsignedchardot_count;unsignedcharbyte_count;unsignedcharcmd_number;
unsignedcharmode;
unsignedcharbuf_full;
unsignedcharcmd[5];unsignedcharUSART_END;
unsignedcharnewflag=0;
//经度
//经度方向
//纬度
//纬度方向
//时间
速度
//速度
//高度
//海拔
//方位角
//使用的卫星数天空中总卫星数
//定位状态
//逗号计数器
//小数点计数器
//位数计数器
//命令类型
//0:
结束模式,1:
命令模式,2:
//1:
整句接收完成,相应数据有效。
//命令类型存储数组
//经纬度转换用//doubled;doublef;
unsignedchard_d;doubleD_D;
unsignedchartime_8;//时区转换voidgps_deal(void)
{
u8tmp=0;if(USART_GetITStatus(USART1,
USART_IT_RXNE)!
=RESET)//如果是接收中断
tmp=USART_ReceiveData(USART1);
switch(tmp)
{
case'$':
cmd_number=0;//命令类型清空
mode=1;//接收命令模式
byte_count=0;//接收位
数清空
break;case',':
seg_count++;//逗号计数加1
byte_count=0;break;
case'*':
switch(cmd_number){case1:
newflag|=0x01;//GGAbreak;
case2:
newflag|=0x02;//GSVbreak;
case3:
newflag|=0x04;//RMCbreak;
}mode=0;
break;
default:
if(mode==1)
{
//命令种类判断cmd[byte_count]=tmp;
//接收字符放入类型缓存if(byte_count>=4)
//如果类型数据接收完毕,型
{
if(cmd[0]=='G')
{
if(cmd[1]=='P')
{
if(cmd[2]
'G')
{
if(cmd[3]
=='G')
{
if(cmd[4]=='A')
{
cmd_number=1;
mode=2;
seg_count=0;
byte_count=0;
}
}
else
if(cmd[3]=='S')
{
if(cmd[4]=='V')
{
判断类
cmd_number=2;
seg_count=0;
WD[byte_count]
=tmp;
byte_count=0;
}
}
}
elseif(cmd[2]=='R')
{if(cmd[3]=='M')
{
if(cmd[4]=='C')
{
cmd_number=3;
mode=2;
seg_count=0;
byte_count=0;
}
}
}
}
}
}
}
elseif(mode==2)
{//接收数据处理switch(cmd_number){
case1:
//类型1数据接收。
GPGGA
switch(seg_count)
{
case2:
//纬度处理
WD[byte_count+1]='\0';//解决输出位
数过多
}
break;
case3:
//纬度方向处理
if(byte_count<1)
{
WD_a=tmp;
}
break;
case4:
//经度处理
if(byte_count<
11)
{
JD[byte_count]
=tmp;
JD[byte_count+1]='\0';
}
break;
case5:
//经度方向处理
if(byte_count<1)
{
JD_a=tmp;
}
break;
case7:
//定位使用的卫星
数
if(byte_count<2)
{
use_sat[byte_count]=tmp;
if(byte_count
use_sat[byte_count+1]='\0';
}
10)
break;
{
case9:
//
时间处理
//高度处理if(byte_count<6)
time[byte_count]=tmp;
{
}
break;
high[byte_count]=tmp;
case2:
}
//
定位判断
break;
if(byte_count<1)
case11:
{
//海拔处理
lock=tmp;
if(byte_count<6)
}
{
break;
haiba[byte_count]=tmp;
case7:
}
//
速度处理
break;
if(byte_count<5)
}
{
break;
case2:
//
类
型2数据接收。
GPGSV
speed2[byte_count]=tmp;
switch(seg_count)
//
{
spd_wei=byte_count;
case3:
}
//天空中的卫星总
break;
数
case8:
if(byte_count<2)
//
方位角处理
{
if(byte_count<5)
total_sat[byte_count]=tmp;
1
angle[byte_count]=tmp;
total_sat[byte_count+1]='\0';
}
}
break;
break;
}
}
break;
}
}
break;
case3:
//
类
byte_count++;
//接收数
型3数据接收。
GPRMC
位加1
switch(seg_count)
break;
{
}
case1:
}
if(byte_count
<
//时区转换voidTIME_AREA(void)
{
time_8=(time[0]-0x30)*10+
(time[1]-0x30)+8;
if(time_8>23)
{time_8=time_8-24;
}
time[0]=(time_8/10)+0x30;time[1]=((time_8-(time_8/10)
*10)/1)+0x30;
}
//经纬度转换doubleJWD_AREA(char*jwd)
{
d=atof(jwd)/100.0;//将
JD[]转换为double
d_d=d/1;
f=(d-d_d)/60.0*100;
D_D=d_d+f;
returnD_D;
}
voidgps_display(void)
{
LED0=!
LED0;
if(newflag==0x07){
newflag=0;GUI_SetColor(GUI_GREEN);
GUI_SetFont(&GUI_Font8x16);
GUI_DispStringAt("Longitude
",20,60);
JWD_AREA(JD);//经度转换
GUI_DispFloat(D_D,10);
GUI_DispCharAt(JD_a,120,60);
GUI_DispStringAt("Latitude",20,80);
JWD_AREA(WD);//纬度转换
GUI_DispFloat(D_D,10);
GUI_DispCharAt(WD_a,120,80)
GUI_DispStringAt("use_sat",20,100
);
GUI_DispStringAt(use_sat,140,100)
GUI_DispStringAt("total_sat",20,1
20);
GUI_DispStringAt(total_sat,140,12
0);
GUI_DispStringAt("status",20,20);
GUI_DispCharAt(lock,140,20);
GUI_DispStringAt("Elevation",20,1
40);
GUI_DispStringAt(high,140,140);
TIME_AREA();
GUI_DispStringAt("high",20,160);
GUI_DispStringAt("time",20,40);
GUI_DispStringAt(haiba,140,160);
GUI_DispStringAt(time,140,40);
//printf(”时间:
%c%时%c%c
GUI_DispStringAt("Speed",20,180);
分%c%c%c%c%Cr\n",time[O],time[1].
GUI_DispStringAt(speed2,140,180);