论坛风格切换切换到宽版
  • 3852阅读
  • 5回复

纯粹的GPS芯片多少钱?可以通过单片机读出相关信息吗? [复制链接]

上一主题 下一主题
离线antforum
 
发帖
218
只看楼主 倒序阅读 0楼 发表于: 2008-02-24
请教! 如题! 是否可以直接读出经纬度和高度。
离线yuhang
发帖
1803
只看该作者 1楼 发表于: 2008-02-24
'
请教! 如题! 是否可以直接读出经纬度和高度。
'


能读出信息的叫gps模块
离线cctvcctv
发帖
412
只看该作者 3楼 发表于: 2008-03-07
淘宝上有2手的100元左右,转贴个汇编的程序,

   

gps卫星定位导航系统 51单片机资料

一、gps接受的数据(在pc串口上的显示)(3月1日)
$gpgga,000002.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*7d
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gprmc,000002.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*0f
$gpgga,000003.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*7c
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gprmc,000003.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*0e
$gpgga,000004.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*7b
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gprmc,000004.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*09
$gpgga,000005.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*7a
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gprmc,000005.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*08
$gpgga,000006.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*79
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gpgsv,1,1,01,03,00,000,00*4b
$gprmc,000006.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*0b
$gpgga,000007.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*78
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gprmc,000007.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*0a
$gpgga,000008.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*77
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gprmc,000008.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*05
$gpgga,000009.999,0000.0000,n,00000.0000,e,0,00,50.0,0.0,m,0.0,m,0.0,0000*76
$gpgsa,a,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$gprmc,000009.999,v,0000.0000,n,00000.0000,e,0.00,,270920,,*04
*******************************************************************二、文中涉及gprmc特定精简资料信息的采集,分析如下:
$gprmc、 <1>、 <2>、<3>、<4>、<5>、<6>、<7>、<8>、<9>、<10>、<11>、*hh<cr><lf>
$gprmc,204700,a,3403.868,n,11709.432,w,001.9,336.9,170698,013.6,e*6e

例:$gprmc,112720.000,a,3639.2868,n,11659.8396,e,,,200305,,*12
$gprmc,235958.999,v,0000.0000,n,00000.0000,e,0.00,,260920,,*0c

区域   名称   例   单位   说明
1   信息id   $gprmc   rmc协议开始
2   utc时间   112720.000   格林威治  
3   状态   a (资料有效)  
4   纬度   3639.2868   纬度信息
5   南/北半球指示   n   n为北半球
6   经度   11659.8396   经度信息
7   东/西半球指示   e   东半球
8   速度      
9   方向      
10   日期   200305  
11   磁极变量度      
三.串口工作原理
stc89c51单片机只有一个uart异步串行通信接口,而在此设计中,不但要求系统提供一个工作在9600bps的串行口与gtm-900进行数据的交换,而且还需要一个串行口工作在4800bps采集gps设备传送回来的数据和一个串行口工作在9600bps发送内码给语音芯片xf-s3011。根据上述需要,除了单片机的串行口与gtm-900连接进行高速稳定的数据交换进行控制外,还需要用单片机的i/o口模拟一个工作在4800bps的串行口和一个工作在9600bps的串行口。
我在编程时,应用了中断口线0模拟了一个接受串口。应用了定时器t0进行了一位的等待时间。
异步通信是字符的同步传输技术。在异步通讯中,传输的数据以字符(character)为单位。当发送一个字符代码时,字符前面要加一个“起始”信号,其长度为一位,极性为“0”,即空号(space)状态;规定在线路不传输数据时全部为“1”,即传号(mark)状态。字符后面要加一个“停止”信号,其长度为1,1.5,或2位,极性为“1”。字符本身的长度为5~8位数据,视传输的数据格式而定。
例如:  
  起始位占用一位(低电平0),表示字符开始,传送的数据(或字符)用ascii码表示时,其长度为8位,最后为停止位(高电平1),用来表示字符传送结束,上述字符格式通常作为一个串行帧,属于“n,8,1”帧格式。起始位和停止位用来区分字符,传送时,字符可以连续发送,也可以断续发送。不发送字符时线路保持“1” 状态。字符发送的顺序为先低位后高位。



串行通信中,波特率(band rate)定义为每秒钟传送二进制码的位数(亦称比特数),单位是bps(bit per second),即 位/秒 。波特率是串行通信的重要指标,用于表示数据传输的速度。波特率越高,数据传输速度越快,但和字符的实际传输速率不同,字符的实际传输速率是指每秒钟内所传字符帧的帧数,与字符帧格式有关,如果数据传送的波特率为4800bps,采用n,8,1帧格式(10位),则每秒传送字节为480个字,而字节中每一位传送时间即为波特率的倒数。
t=1/4800=0.208ms
在此,必须强调 “时序” 和 “格式” ,这两者决定rs-232通信的关键。无论是发送还是接收,其传输的数据都要符合这两项规定。所谓的rs-232通信,实际就是一些规定格式的高低电平的传递,而单片机正是处理这些电平的有利工具,这就是为单片机使用i/o端口模拟串口提供了基本的依据。
3.3 nmea-0183协议
gr-85模块支持nmea-0183输出格式,波特率默认值为4800bps,1个起始位,8个数据位,1个停止位,无奇偶校验,数据代码为ascii码字符。nmea-0183是美国海洋电子协会为海用电子设备制定的标准格式,目前广泛使用v2.0版本。由于该格式为ascii码字符串,比较直观和易于处理,在许多编程语言中都可以直接进行判别、分离,以提取用户所需要的数据。gm-305系列接收机可输出6句语句,其中较常用的4种为gga, gsv, rmc, vtg,不同的语句传送不同的信息:

gga位置测定系统定位资料(global positioning system fix data)
gsv 导航卫星资料(gnss satellites in view)
rmc导航卫星特定精简资料(recommended minimum specific gnss data)
vtg 方向及速度等相关资料(course over ground and ground speed)
文中涉及gprmc特定精简资料信息的采集,详细的分析如下:
$gprmc、<1>、<2>、<3>、<4>、<5>、<6>、<7>、<8>、<9>、<10>、<11>、*hh<cr><lf>
例:$gprmc,112720.000,a,3639.2868,n,11659.8396,e,,,200305,,*12

区域   名称   例   单位   说明
1   信息id   $gprmc   rmc协议开始
2   utc时间   112720.000   格林威治  
3   状态   a (资料有效)  
4   纬度   3639.2868   纬度信息
5   南/北半球指示   n   n为北半球
6   经度   11659.8396   经度信息
7   东/西半球指示   e   东半球
8   速度      
9   方向      
10   日期   200305  
11   磁极变量度      
上面例子中我们可读出位置信息:
北纬36度39.2868分,东经116度59.8396分
        格林威治时间:11点27分20秒
        日期:2005年3月20日
四、 gps数据的接收
gps接收机只要处于工作状态就会源源不断地把接收并计算出的gps导航定位信息通过串口传送到单片机中。其发送到单片机的数据主要由帧头、帧尾和帧内数据组成,根据数据帧的不同,帧头也不相同,主要有"$gpgga"、"$gpgsa"、"$ gpgsv"以及"$gprmc"等。这些帧头标识了后续帧内数据的组成结构,各帧均以回车符和换行符作为帧尾标识一帧的结束。对于通常的情况,用户所需要的定位数据如经纬度、速度、时间等均可以从“$gprmc”帧中获取得到。
;检测到$gprmc,字符串---------------------
判断完我们所需要的帧头,其帧头后面的信息就是我们所需要的数据,单片机要将其接收并存放在ram中,以便后面的程序调用。
4.3gps数据的提取
gps接收到的数据存放在ram中,它只是一长串字节流,这些信息在没有经过分类提取之前是无法加以利用的。因此,必须通过程序将各个字段的信息从缓存字节流中提取出来,将其转化成有实际意义的数据,为后面的程序提供卫星定位信息。
例如,接收到的gps数据为:
$gprmc,112720.000,a,3639.2868,n,11659.8396,e,,,200305,,*12
将其存放于30h开始的单元中:
$gprmc,235958.999,v,0000.0000,n,00000.0000,e,0.00,,260920,,*0c
$gprmc,204700,a,3403.868,n,11709.432,w,001.9,336.9,170698,013.6,e*6e
20h   21h   22h   23h   24h   25h   26h   27h   28h   29h   2ah   2bh   2ch   2dh   2eh   2fh   30h
2   3   5   9   5   8   .   9   9   9   v   0   0   0   0   .   0
utc时间   无效   纬度信息
31h   32h   33h   34h   35h   36h   37h   38h   39h   3ah   3bh   3ch   3dh   3eh   3fh   40h   41h
0   0   0   ,   n   0   0   0   0   .   0   0   0   0   ,   e   ,
纬度信息   南/北半球指示   经度信息   东/西半球指示  
42h   43h   44h   45h   46h   47h   48h   49h   4ah   4bh   4ch   4dh   4eh   4fh   50h   51h   52h
0   0   1   .   9   ,   3   3   6   .   9   ,   1   7   0   6   9
速度信息   方向   日期

53h
8
程序代码:
;*******************************************************************************************
;单位:山东源浩信息技术有限公司
;功能:gps接受、数据存储程序
;日期:2006年3月3日
;********************************************************************************************
;数据存储在了30h-63h中
;*********************标志位定义*****************************************************
fg_receive_frame   bit   00h   ; 帧头接受完毕标志位
fg_receive_over     bit   01h   ;数据接受完成的标志位
;*******************标志位定义完成***************************************************

;********************寄存器定义******************************************************
receive_frame_count   data   64h   ;接受帧头中字符的计数器
receive_data_adress   data   65h   ;接受数据的存储地址单元
;*****************寄存器定义完成*****************************************************

;********************口线定义********************************************************
a_rxd   bit     p3.2     ;定义a_rxd为外部中断int0(引脚p3.2);
;******************口线定义完成******************************************************

;********************程序开始***************************************************
  org 0000h
reset: ajmp main
  org 0003h ;外部中断int0的入口地址
  ajmp i0_gps4800;
  nop;
  nop;
  ;org 000bh;定时器t0的中断入口地址
  ;org 0013h;外部中断int1的入口地址
  ;org 001bh;定时器t1的中断入口地址
  ;org 0023h;串口的中断入口地址
  org 0100h

;*********************gps4800接收的中断处理**************************************
i0_gps4800:
    clr ex0             ;关中断int0
    lcall gps4800           ;调用gps4800子程序
      jb   fg_receive_over,i0_gps4800_next;判断fg_receive_over,当数据接收完标志为1时跳到i0_gps4800_next
                      ;否则,开中断int0
      setb   ex0
      jmp   i0_gps4800_reti
i0_gps4800_next:
    clr   ex0
i0_gps4800_reti:
      reti               ;中断返回
;*********************int0中断口处理完成*****************************************

;***********************gps接受子程序***********************************************
gps4800:

l_rec_frame_0:
  jb fg_receive_frame,start1;判断帧头接收标志位,若为1,则开始接收数据(start1)
  mov a,receive_frame_count ;将帧头接收到的正确字节个数给a
  cjne a,#0,l_rec_frame_1   ;判断a是否为0,若是,则接收第1个字节;否则跳入l_rec_frame_1
  lcall r_byte       ;模拟串口接收一个字节
    cjne a,#24h,start0   ;判断是否是'$',若是则继续接收帧头;否则跳入start0
  inc receive_frame_count   ;将帧头接收字节个数加1
  ljmp gps4800_ret     ;程序返回
l_rec_frame_1:
  cjne a,#1,l_rec_frame_2   ;判断a是否为1,若是,则接收第2个字节;否则跳入l_rec_frame_2
    lcall r_byte
  cjne a,#47h,start0   ;判断是否是'g',若是则继续接收帧头;否则跳入start0
  inc receive_frame_count
  ljmp gps4800_ret
l_rec_frame_2:
    cjne a,#2,l_rec_frame_3   ;判断a是否为2,若是,则接收第3个字节;否则跳入l_rec_frame_3
    lcall r_byte
    cjne a,#050h,start0   ;判断是否是'p',若是则继续接收帧头;否则跳入start0
    inc receive_frame_count
    ljmp gps4800_ret
l_rec_frame_3:
    cjne a,#3,l_rec_frame_4   ;判断a是否为3,若是,则接收第4个字节;否则跳入l_rec_frame_4
    lcall r_byte
    cjne a,#052h,start0   ;判断是否是'r',若是则继续接收帧头;否则跳入start0
    inc receive_frame_count
    ljmp gps4800_ret
l_rec_frame_4:
    cjne a,#4,l_rec_frame_5   ;判断a是否为4,若是,则接收第个5字节;否则跳入l_rec_frame_5
    lcall r_byte
    cjne a,#04dh,start0     ;判断是否是'm',若是则继续接收帧头;否则跳入start0
    inc receive_frame_count
    ljmp gps4800_ret
l_rec_frame_5:
    cjne a,#5,l_rec_frame_6   ;判断a是否为5,若是,则接收第6个字节;否则跳入l_rec_frame_6
    lcall r_byte
    cjne a,#043h,start0   ;判断是否是'c',若是则继续接收帧头;否则跳入start0
    inc receive_frame_count
    ljmp gps4800_ret
l_rec_frame_6:
    cjne a,#6,start0       ;判断a是否为6,若是,则接收第7个字节;否则跳入start0
    lcall r_byte
    cjne a,#02ch,start0   ;判断是否是',',若是则继续接收帧头;否则跳入start0
    setb fg_receive_frame   ;置fg_data_rec为1,表示'$gprmc,'已经接收完毕
    mov receive_frame_count,#0   ;将帧头接收计数器清零
    mov receive_data_adress,#30h ;将存储接收数据的地址给receive_data_adress
    ljmp gps4800_ret       ;程序返回
start1:
    mov r0,   receive_data_adress
    lcall r_byte
    mov @r0,a           ;将数据放入ram对应单元中去
    inc receive_data_adress   ;将数据地址加1,为存储下一个数据做好准备
    mov a,receive_data_adress
    cjne a,#64h,gps4800_ret   ;判断数据是否接收完成
    clr   fg_receive_frame     ;
    setb fg_receive_over     ;若接收完成,则将帧头标志清零,将数据接收完成标志置1
    ljmp gps4800_ret
start0:   mov receive_frame_count,#00h ;若没有接收完'$gprmc,'则将帧头接收字节数清零
gps4800_ret:
      ret
;***********************************************************************************************************

;********************模拟串口接受一个字节的程序r_byte*******************************************************
r_byte:
clr   tf0
  jb   a_rxd,$
  mov   tl0,#35h
setb   tr0     ;打开定时器t0
jnb   tf0,$   ;等待起始位结束
mov   r7,#08h   ;起始位结束后开始接收串行的数据
r_loop:
  jnb   tf0,$
clr   tf0
mov   c,a_rxd   ;将a_rxd的状态读到a中
rrc   a
mov   tl0,#3bh   ;定时器置初值
djnz   r7,r_loop   ;循环接收八位字节
jnb   a_rxd,$   ;   等待停止位
  clr   tr0
ret
;**************************模拟串口接受一个字节的程序完成*****************************************************

main:
  mov   sp,   #70h;
  anl   tmod,   #0f0h
  orl   tmod,   #02h   ;设置定时器t0工作在方式2
  anl   tcon,   #0feh;
  orl   tcon,   #01h     ;设置外部中断int0为跳沿触发方式;
  mov   receive_frame_count,#0 ;对帧头接收字节个数计数器清零
  clr   fg_receive_frame   ;对帧头接收标志清零
  clr   fg_receive_over   ;对数据接收完标志清零
  mov   th0,#40h
  mov   tl0,#40h
                ;每一位的延续时间t=1/4800=2.08*(10-4)s;定时器记数次数n=t/t=192
                ;t=1/(11059200/12)s,所以定时器初值=256-192=64=40h
  setb   ex0       ;打开外部中断int0
  setb   ea       ;打开中断
next1: jmp $

  end
离线aluu2005
发帖
40
只看该作者 4楼 发表于: 2008-03-08
我有2块全新的sif3代模块,上次要搞汽车gps防盗时候买的,后来项目取消而没有用到。具体应用则研究过一段时间,基本上如楼上所述。
离线BD8NCF
发帖
2079
只看该作者 5楼 发表于: 2008-03-10
前段时间.com上卖的天宝gps模块,70多元一只,我买过2只