论坛风格切换切换到宽版
  • 9582阅读
  • 19回复

自制GPS轨迹记录仪的讲解!! [复制链接]

上一主题 下一主题
离线wb4916
 
发帖
213
只看楼主 倒序阅读 0楼 发表于: 2008-02-19
写在前面:

自我介绍:
在一家做gps模块的小公司打杂:www.skylab.com.cn。公司使用unav的主ic。喜欢出去玩。于是想做一个记录gps轨迹的东西,使用公司现成的

模块!硬件出问题,就找工程师了,软件就得自己打理了!

当时分为:电源、gps模块(gm10/gb10/……)、mcu(51/stc89c54ad+)、u盘、ch375a/sl811:u盘的驱动ic。

由于公司做gps的,gps部分不着急。公司有个硬件工程师以前做电源的,可以请教,就是存储部分就成为最难的了!

电源当时选择了ni-mh电池,u盘需要5v电压,stc89c54ad+也是5v的,于是要升压,从1.8v-2.4v(0.9v*2-1.2v*2)升压到5v。考虑到u盘需要

500ma的电流,到处找升压ic。在电源网站发帖子,留mail。现在mail里还保留了一些做电源ic发过来的pdf。不过这个不是重点!留意一下!



u盘的驱动ic开始就淘汰了sl811,价格和其它的问题。不过sl811的keil c文档在网上到处都是,加锁了,不让修改,还有些文件还是已经编译

了的。代码也很长,要吸收,得很长时间!!

于是就碰到了ch375a。在华强北的电子商场里,从js手里用25¥/片分2次买了5片ch375a,配套的还有10片issi的62c256(5.5¥/片),最后检

验,有2片62c256竟然是坏的,js。其它还有74hc573和74hc138各1管。

也许许多工程师,有公司的支持,肯定就买demo板了。板要400¥左右,舍不得,就自己琢磨了。学protel 99se,还花了380¥打了10片板。最

后收获:知道画板是怎么回事了。但是板是失败,和u盘通讯不了!!最后,还有花99¥在赛博前面的地摊前面买的kinston的1g的u盘竟然是假

的!!js。中国人能够做出来的东西,就直接找代理买吧!!


考虑了93c46(1k位)大容量的也没有多少,可是我得存储1周的gps的经纬度、日期、时间、高度数据,初步估计:起码得10m!!当时推荐了

93c46(1k位),大容量的也没有多少,可是我得存储1周的gps的经纬度、日期、时间、高度数据,初步估计:起码得10m!!也有人说直接使

用flash。我看了看flash的pdf,那要多少i/o脚呀!!51肯定不行了,得换arm或者其它高档的mcu。想想当时因为2个串口,曾经考虑过日立的

mcu,虽然是鬼子的!一个串口分配给ch375a,一个给gps模块。这样硬件简单。当时甚至考虑了一个串口分多个串口的ic。

最后,在网络搜索u盘的读写时候,有人提到一本书《硬盘扇区读写技术━━修复硬盘与恢复文件》,介绍fat文件系统的。还有说存储部分可

以用sd卡。当时用u盘卡壳了,也是转向sd卡。还搜索到了一些使用cf卡与mmc卡的资料!!

就这样,选定了使用sd卡。找它的资料,电压3.3v,有sd模式和spi模式。网上有人说共享avr下读写sd卡的代码,它是使用spi模式的。于是就

参照它,修改为51的。于是,在去年一年里,做出了些特别简单的东西。如果,新手能够学习点什么,是对我最大的鼓励!!
离线wb4916
发帖
213
只看该作者 1楼 发表于: 2008-02-19
http://www.hellocq.net/forum/showthread-t-168821.%d7%d4%d6%c6gps%b9%ec%bc%a3%bc%c7%c2%bc%d2%c7%a3%a1.html

自制gps轨迹记录仪!

做的过程中,也参照了以下本帖子!
http://www.hellocq.net/forum/showthread-t-139534.gps%a1%a1oem%b0%e5%a3%ab%b5%a5%c6%ac%bb%fa%a3%ab%d2%ba%be%a7%cf%d4%ca%be.html

gps oem板+单片机+液晶显示




讲解开始,首先介绍串口程序:helloworld

c语法问题,请参考《c语言程序设计》 谭浩强。可以了解turbo c2.0。

请默认安装keil c。

昨天忘记了生成hex文件!!抱歉!!
附件: HelloWorld.zip (0 K) 下载次数:259
离线bd7rf
发帖
10148
只看该作者 2楼 发表于: 2008-02-20
做完这个,你的技术水平肯定会来个飞跃,我们也顺便偷点艺。支持!!!
离线BG4UVR
发帖
11287
只看该作者 3楼 发表于: 2008-02-21
我佩服楼主的这种“钻”劲,这种学习精神值得我去学习
离线wb4916
发帖
213
只看该作者 4楼 发表于: 2008-02-21
//2008-2-19 16:26
//by redfe
//wb4916 at sohu dot com
//qq群:19504537 交流sd卡/gps模块/……的使用。也可以谈天。^_^

//11.0592mhz的晶振,使用4800波特率
//不停地发送 hello world! 并且换行

#include <at89x52.h>
#include <stdio.h>

void main(void)
{
  [indent]scon = 0x50;   //设置为串口方式1,允许接受
  tmod = 0x20;   //设置为定时器1定时方式2
  tcon = 0x40;   //设置为定时器1开始计数
  th1 = 0xfa;   //11.0592mhz的晶振下4800波特率
  tl1 = 0xfa;   //
  ti   = 1;
  tr1 = 1;     //启动定时器
 
  while(1)
  {
    [indent]printf("hello world!\n");   //显示“hello world!”[/indent]
  }[/indent]
}



由于几乎所有的程序教程都是从hello world!开始的!我们也从这里开始!

本程序我是从网络上面找到的,除了波特率由1200改为4800之外!!所有的语句可以理解为规定!!(keil的人这么设计的!!^_^)

nmea0183规定的波特率为4800,不过现在使用9600的越来越多了。我在公司的时候,曾经成批地把一些模块修改为9600波特率。公司的模块默认使用4800。由于unav提供的orion analyzer没有考虑到这一点,我们修改的时候,每片要点13次鼠标,这还是在默认输出4条语句的情况下,如果只需要$gprmc或者$gpgga或者$gprmc+$gpgga的时候,得点更多的次数。(去掉其它不要的语句前面的勾!!)想想修改1k要点多少鼠标?1天的工作就是这样!!下班的时候你会心疼你的右手拇指!!

年前,也就是快过年的时候,写了个程序,发一条命令,将4800自动改为9600,然后在evb的led上面显示修改成功(判断是否在9600波特率下接收到$)。现在修改的速度是以前的2倍了,手也不是那么累了!!(《懒人推动社会进步》,还是有一定道理的!!)

还有就是nmea2000定义了38400波特率。holux的m-241 wireless gps logger和pc连接的时候,默认使用38400波特率,它的内部难道也采用38400波特率吗?不过它使用了cp210x,也就是把内部的串口虚拟为usb口。也许只是这个虚拟串口通讯使用的波特率。但是为什么不使用115200呢?就不得而知了!!这样会更快呀!!

注意:4800波特率的时候,屏幕显示不过来!!关电源或者停止串口接收,就会看见显示的“hello world!”了!!不过是1200波特率的话,由于速度比较慢,可以看见“hello world!”的字母一个一个地显示!!也许原文是为了这个效果,特意选取的1200波特率!!^_^

串口软件:使用stc-isp3.5,它可以通过isp的方式烧录stc89c54ad+,它自带串口接收程序!!
离线BD7LM
发帖
1367
只看该作者 5楼 发表于: 2008-02-21
支持一下!
离线wb4916
发帖
213
只看该作者 6楼 发表于: 2008-02-21
现在介绍一个串口发送的例子。由于串口发送已经在前面介绍了,这里主要是介绍使用512字节的变量的方法。使用了一个大数组buffer[512]。由于sd卡规定,写数据的最小单位为一个扇区512字节,你一次写多个扇区也没有人介意!!^_^。不过读,可以是任意字节!!但是为了简便,下文只介绍一次读取一个扇区512字节的方法!!读取其它数量字节的方法请读者自行研究了!!

附件为rs232send,编译,结果出问题!!错误如下图所示!!
附件: RS232SEND.zip (0 K) 下载次数:181
离线wb4916
发帖
213
只看该作者 7楼 发表于: 2008-02-21
编译器告诉我们,你申请的内存太大,mcu没有这么大的内存,不像我们的电脑,动不动几g的内存!!^_^

at89c52的描述:(keil)
8051-based fullly static 24mhz cmos controller with 32 i/o lines,
3 timers/counters, 8 interrupts/2 priority levels, uart,
three-level program memory lock, 8k bytes flash memory,
128 bytes on-chip ram

只有128字节的片上ram,512肯定不行啦!!

于是,按照下面的步骤,告诉编译器,我们扩展了外存(电脑上面就是硬盘了!!^_^)实际上,stc89c54ad+自带1024字节的ram,但是keil没有收录它,宏晶也没有开发自己的编译器,实际上,它的mcu就是兼容atmel的,只不过加入了isp功能,这个好,不用买烧录器。不过,当时自己在玩stc89c52的时候,琢磨了好久,又不好问老工程师!!舍不得花50¥买宏晶的烧录器,自己搭的板,出问题后,当然得自己找了!忽然有一天,通了!!那也是一个月后的事情了!!

修改完成后,再次编译,可以看到它通过了!附录2张接收的图片。一张为16进制的,一张为字符的。请大家自行体会啦。(研究一下acsⅡ就知道了!!)
离线wb4916
发帖
213
只看该作者 8楼 发表于: 2008-02-21
//2008-2-21 11:51
//by redfe
//wb4916 at sohu dot com
//qq群:19504537 交流sd卡/gps模块/……的使用。也可以谈天。^_^

//11.0592mhz 4800波特率 发送a 空格 换行。
//1200波特率 看的清楚
#include <at89x52.h>

#define uchar unsigned char     //one byte
#define uint unsigned int       //two bytes
#define ulong unsigned long     //four bytes
#define slong signed long       //four bytes

uchar buffer[512] = {
0x57,0x45,0x4e,0x59,0x55,0x41,0x4e,0x42,0x4f,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
};

void main(void)
{
  [indent]//uchar i;//2007-11-8 9:09 超过255会发生溢出,导致死循环!!
  uint i;

  scon = 0x50;   //串口方式1,允许接收
 
  tmod = 0x20;   //定时器1定时方式2
 
  //tcon = 0x40;   //设定时器1开始计数
 
  th1 = 0xfa;   //11.0592mhz 4800波特率
  tl1 = 0xfa;
 
  tr1 = 1;     //启动定时器
 
 
  //如果i类型不对,发生溢出,导致死循环!!
  for(i=0;i<512;i++)
  {    
    [indent]sbuf = buffer;
   
    while(!ti) //判断是否发送完
        [indent];[/indent]
    ti = 0;[/indent]
  }
 
 
  while(1)
    [indent];[/indent][/indent]
}

如果有兴趣,可以把变量i的定义有uint修改为uchar,然后编译,看看什么结果!!

编译当然没有问题。当时发觉512个字节,老发不完。关机的时候,串口接收到很多字符,远远大于512字节。后来发现i溢出了!uchar的范围为0-255!!搞明白已经是一天后的事情了!!^_^

(如果使用stc-isp来接收的话,请选择一下接收模式:16进制/字符)
离线红猪
发帖
4980
只看该作者 9楼 发表于: 2008-02-21
我也支持一下,放张板凳。
离线wb4916
发帖
213
只看该作者 10楼 发表于: 2008-02-22
介绍了2个发送的例子,现在介绍一个接收的!!如果mcu接收到发送的字符a,就改变led灯d1的状态。明/灭!!



//2008-2-22 15:37
//by redfe
//wb4916 at sohu dot com
//qq群:19504537 交流sd卡/gps模块/……的使用。也可以谈天。^_^

#include <at89x52.h>

#define uchar unsigned char     // one byte
sbit leddisplay = p2^0;

void main(void)
{
  [indent] uchar temp;
   
  scon = 0x50;   //串口方式1,允许接收
 
  tmod = 0x20;   //定时器1定时方式2
 
  //tcon = 0x40;   //设定时器1开始计数
 
  th1 = 0xfa;   //11.0592mhz 4800波特率
  tl1 = 0xfa;
 
  tr1 = 1;     //启动定时器
 
  p2 = 0x00;
 
  while(1)
  {
    [indent] if(ri)     //接受中断处理
    {
[indent]         temp = sbuf;
        if('a' == temp)
        //if(65 == temp)   //!!!!不能够为"a"
          leddisplay = !leddisplay;   //逻辑非
       
        p1 = ~temp;   //按位非
        ri = 0;[/indent]
    }[/indent]
  }[/indent]
}
附件: RS232RECEIVE.zip (0 K) 下载次数:174
离线wb4916
发帖
213
只看该作者 11楼 发表于: 2008-02-22
现在开始介绍软件中最重要的部分:读写sd卡!!gps模块的输出的nmea数据,在网络上可以找到大量的资料!!51的串口资料也不少。但是51读写sd卡的到是没有人贡献一个简易的!!对于初学者,肯定不需要fat全兼容,既fat12/fat16/fat32全部支持!!16m或者以下的卡使用fat12,它的fat表比较特别,当时有2张16m的卡,从网络上面搜索了一阵子,才明白它的fat表是如此这般!!^_^有兴趣的网络的自己找资料!!32m到2g的都推荐使用fat16,这个也是本文所要介绍的了!!现在能够买到的sd卡,小于512m的不多了,大于2g的也有了,比如4g,不过还是比较少!!主流为1g、2g!!我当时为了研究sd卡,专门去买小容量的卡,16m的10¥,32m的15¥,买了一些,也坏了一个32m的,掉了一个16m的。还剩下2个32m的,32m的好处是每个簇正好只有一个扇区,不用考虑一个簇有其它扇区的情况!!本文不介绍一个簇有多于一个扇区的情况!!至少最近不会!!^_^将来完善的时候补上了!!如果理解了fat16,其实也是很容易自己修改的!!至于fat32,用在4g或者4g以上的卡上面的,也不介绍了!!因为现在我也不会,同样要等待^将来完善的时候补上了!!



附件:
德国人做的avr读写sd卡的资料.zip

在一个德国网站上面下载的资料,网络地址:http://www.ulrichradig.de/home/index.php/avr/mmc-sd
年前,上面有一个使用atmel的一个mcu播放sd卡上面的mp3的的版本还是2.5(sourcecode),我刚刚去下载就变成了2.7,他们还是很勤劳的!!对技术的追求还是很执作的!!他们的软件使用gpl协议发布。相信在网络上面流传的很多使用avr读写sd卡的程序都参照它改写的,或者说直接一点,抄袭别人的!!里面的mmcsdtimming.pdf,画了sd卡在spi模式下的时序图,很值得参考!!我打印了之后,研究了几个小时!!


sd卡规范.zip

包括:
part1,硬件定义。翻译了spi模式的那部分
part2,fat的定义。全部翻译。
part3,安全的那部分。至今没有研究,也不需要。

翻译的部分,发表在:http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=422617&bbs_id=1000
去这个网站可以找到一些其它的关于sd卡的资料!!

avr_51读写sd卡的代码.zip

请有一定编程功底的人阅读,不建议初学者阅读。我当时参照:avr下使用software spi操作mmc sd代码,依照mmc.c的代码写51下的,因为里面的一行语句,把我折磨得够呛,大约花了一周的时间才搞明白,同时得到了网友瓢老猫的帮助,对此深表谢意!!不过,不知道那人为什么这么写,是avr下要求这么写,还是他写错了!现在还不得而知!!
附件: 德国人做的AVR读写SD卡的资料.zip (0 K) 下载次数:4946
附件: SD卡规范.zip (0 K) 下载次数:1111
附件: AVR_51读写SD卡的代码.zip (0 K) 下载次数:1069
离线bellstudio
发帖
2820
只看该作者 12楼 发表于: 2008-02-23
赞一下,搬个凳子看
离线bd7rf
发帖
10148
只看该作者 13楼 发表于: 2008-02-23
感谢楼主!
离线BG7RKR
发帖
16
只看该作者 14楼 发表于: 2008-11-03
楼主你们那里的gps模块多少钱?
离线dianziwg
发帖
1040
只看该作者 15楼 发表于: 2008-11-03
用户被禁言,该主题自动屏蔽!
离线bg5sbj
发帖
386
只看该作者 16楼 发表于: 2008-12-23
好资料,做个记号!改天用得着!!!
离线bg7ida
发帖
2636
只看该作者 17楼 发表于: 2008-12-26
copy下来慢慢学习.......谢谢分享...........
离线庄乾章
发帖
1047
只看该作者 18楼 发表于: 2009-03-23
jh11111111111
离线承诺
发帖
16
只看该作者 19楼 发表于: 2009-03-25
大家好,请多多指教,我是做微波器件的,产品应用于微波直放站分别为cdma(800mhz)、gsm(900mhz)、pcs(1800mhz,1900mhz)、wcdma(2100mhz)、3g信号发射、光纤天线接收、电台、电力、通信系统、数据传输等设备。
   主要产品有:射频大小功率管(motorola、fujistu、philips、infineon、freescale),功放模块(800mhz、900mhz、1900mhz、2.5ghz),隔离器、环型器、混频器、耦合器、负载电阻、光纤连接线、vcos等。同时经销进口松下(nais)、欧姆龙(omron)、高见泽(takamisawa)等继电器。