stc51单片机做的GPS定位及轨迹记录器

发布者:自在逍遥最新更新时间:2020-08-31 来源: 51hei关键字:stc51  单片机  GPS定位  轨迹记录器 手机看文章 扫描二维码
随时随地手机看文章

基于C3-370C的GPS定位及轨迹记录仪!

在51hei买了C3-370C的GPS,准备做GPS轨迹记录,因为我一直想在旅游的照片上加上坐标信息……

开始用M48作控制MCU,结果写着写着,发现Flash空间不足,想换个M8或M88的,在常州还不好买,手上正好还有两块STC90C52,8K的,于是就换上C52了。

C52不带AD,那电池检测又成问题,于是从坏的万用表上拆下一个2904运放,做了个简单的电池电压检测。

现在整个设备的供电都由锂电池直接提供,配一块880mah的手机电池,可以用6小时左右;

我用24C64记录轨迹信息,包括日期时间、经纬度在内的一组信息,可存储512条,按1min/条,可存8小时。

数据通过串口传给上位机,上位机软件转换数据,也可直接输出KML文件,在Goole earth中打开。

按键0: 短按(可见卫星信息|坐标数据); 长按(运行|暂停);
按键1: 短按(记录当前坐标数据); 长按(暂停时长按删除所有数据);
按键2: 短按(背光灯); 长按(记录模式切换H/A90s/A60s/A30s/A10s);



视图1



背光灯开启



界面说明



液晶背后的主控板



30S自动记录模式



可见卫星信息



连接电脑上传数据



PC端接收数据



删除数据



背面



左侧



右侧


在GooleEarth打开


运放低电压指示电路


最近想着给它加个壳,费了一些时间,找到了一个东东,感觉做外壳不错,就是ADSL的分频器,不过体积小了不少, 尺寸只有60X44X21!  


于是想做就做吧,为了减小体积,能用贴片的元件都换成贴片的,幸好最近出了Atmega8a这个价格还算合理的AVR片子, 上位机软件也做了调整,将照片匹配软件与上位机软件合成。 主程序文件:

#include "_STC90.h"

#include "_GPS.h"


sbit C_LED = P0^4; //数据通讯指示

sbit Key0 = P3^3;

sbit Key1 = P1^2;

sbit Key2 = P1^0;


bit flg_gsv=0;

bit flg_mode=0;  

bit flg_upload=0; 

bit flg_rx=0;

bit flg_rxf=0;

uchar flg_rmcgga=0;      //1rmc 2gga


void get_gpsmode(void)

{

if(!flg_mode){

if(buf_gps[3]=='M' && buf_gps[4]=='C') flg_rmcgga = 1;     //RMC

else{

if(buf_gps[3]=='G' && buf_gps[4]=='A') flg_rmcgga = 2; //GGA

else flg_rx = 0; 

}

}

else{

if(buf_gps[3]=='S' && buf_gps[4]=='V') flg_rmcgga = 3; //GGA

else flg_rx = 0;

}

}


void UART_RX(void) interrupt 4

uchar tp_rx;

while(!RI); 

tp_rx = SBUF; 

if(!flg_rxf){

if(flg_rx){                       

buf_gps[count_gps] = tp_rx;  

if(count_gps==4) get_gpsmode();

if(tp_rx=='*'){ flg_rx = 0; flg_rxf = 1;} 

else count_gps++;             

}

else{                          

if(tp_rx=='$'){ flg_rx = 1; count_gps = 0; flg_rmcgga = 0;}

}

}

if(tp_rx=='#') flg_upload = 1;

RI = 0;

}


void UART_TX(uchar tp_tx)

{

SBUF = tp_tx;

while(!TI); 

TI = 0; _nus(100);

}


uchar var_js7=36;

uchar var_js5=0;

uchar var_js4=0;

uint var_jsrec=0;

//60ms

void TIMER2_SEV(void) interrupt 5

{

TF2 = 0;

if(var_js7>0) var_js7--;

if(var_js5>0) var_js5--;

if(var_js4>0) var_js4--;

if(var_jsrec>0) var_jsrec--;

}


void initial(void)

{

C_LED  = 0;

GPS_EN = 0; 

EA = 0;

AUXR = 0x01;

IPH = 0x0c; IP = 0x14;

SCON = 0x50;

PCON = 0x00; 

RI = 0; TI = 0; ES = 1;


TCON = 0x00;

TMOD = 0x21;

TH1 = 256-6; TL1 = 256-6; ET1 = 0; TR1 = 1; 

T2CON = 0x00; T2MOD = 0x00;

RCAP2H = (65536-55296)/256; RCAP2L = (65536-55296)%256;

ET2 = 1; TR2 = 1;

I2C_Init();

L5_init();

L5_wrstr_cn(24,2,0,4,4); //卫星定位

L5_wrstr_cn(24,4,4,4,4); //轨迹记录

EA = 1;

while(var_js7>0);

Lgps_disp_init();            

C_LED = 1; 

}


void Key_deal(void)

{

uchar jk=255;

C_LED = 0; EA = 0; flg_rx = 0; flg_rxf = 0;

if(!Key0){

do{ _nms(8); jk--;}while(!Key0 && jk>0);

if(jk>0){

flg_mode = !flg_mode;

L5_setxy(0,1); ofs = 0; line = 0x00; Lwr_icob(336);

if(!flg_mode) Lgps_disp_dt();

}

else{ 

flg_sata = !flg_sata; L5_SATA();

GPS_EN = flg_sata; 

}

do{ while(!Key0); _nms(5);}while(!Key0);

}

if(!Key1){

do{ _nms(20); jk--;}while(!Key1 && jk>0);

if(jk>0){ at_onewr('H'); var_js4 = 10;} 

else at_format();

do{ while(!Key1); _nms(5);}while(!Key1);

}

if(!Key2){

do{ _nms(8); jk--;}while(!Key2 && jk>0);

if(jk>0) L5_LED = !L5_LED;

else{

while(!Key2){

rec_add();

_nms(255); _nms(255); _nms(255); _nms(255);

}

var_jsrec = var_rec*50; var_jsrec/=3;

}

}

C_LED = 1; EA = 1;

}



void main(void) 

{

initial();

while(1){

if(flg_rxf){

if(flg_sign) C_LED = 0;

L5_ComData(1); var_js5 = 6;

get_cama();  

if(!flg_mode){

if(flg_rmcgga==1) L5_RMC();

else if(flg_rmcgga==2) L5_GGA();

}

else{

if(flg_rmcgga==3){ 

if(!flg_gsv){ 

L5_GSV();

if(buf_gps[8]=='3') flg_gsv = 1;

}

else{

if(buf_gps[8]=='2'){ L5_GSV(); flg_gsv = 0;}

}

}

}

for(count_gps=0;count_gps<96;count_gps++) 

buf_gps[count_gps]=0;

C_LED = 1; flg_rxf = 0;

}

if(var_js5==1){ L5_ComData(0); var_js5 = 0;}

if(var_js7==0){ L5_BAT(); var_js7 = 16;}

if(!(Key0&Key1&Key2)){ _nms(5); Key_deal();}

if(var_js4==1){ L5_AtWr(0); var_js4 = 0;}

if(!flg_sata){

if(var_rec>0){

if(var_jsrec==0){

at_onewr('A'); var_js4 = 10; 

var_jsrec = var_rec*50; var_jsrec/=3;

}

}

}

if(flg_upload){

if(flg_sata){

uint k; uchar r;

C_LED = 0; EA = 0; flg_rx = 0; flg_rxf = 0;

for(k=0;k AT24C64_RdPage(k*16);

UART_TX(k/256); UART_TX(k%256); 

for(r=0;r<16;r++) UART_TX(C64_buf[r]);

L5_sch(1,1,k,at_id);

}

EA = 1; L5_sch(0,0,0,0); C_LED = 1; 

}

flg_upload = 0;

}

}

}



_gps.h 文件:

#include "_STC90.h"

#include "_LCD5110.h"

#include "_AT24C64.h"


#define Bat_full   10 //电量满

#define Bat_empt   11 //电量空

#define Signal     12 //信号

#define NoSignal   13 //信号

#define file       14 //文件

#define Sata_run   15 //状态运行

#define Sata_pause 16 //状态暂停

#define Ico_gps    17 //GPS

#define Ico_com    18 //数据通讯

#define Ico_del    19 //删除

#define Ico_upload 20 //上传

#define Ico_wait   21 //等待

#define chr_point  22 //大'.'

#define chr_degree 23 //度

#define chr_min    24 //分

#define Ico_point  25 //小度

#define Ico_degree 26 //小度


sbit Bat_Low = P1^4; //电池0低

sbit GPS_EN = P3^5;  //GPS使能


uchar buf_gps[96]={0};

uchar count_gps=0;

bit flg_sign=0;      

uchar var_seg[20]={0};

uchar ofs=0;          

uchar line=0x00; 


void get_cama(void)

{

  uchar tp_c=0,cj;

for(cj=0;cj<20;cj++) var_seg[cj] = 0;

for(cj=0;cj if(buf_gps[cj]==','){ var_seg[tp_c] = cj; tp_c++;}

}


void Lwr_icob(uint nb){ for(;nb>0;nb--) L5_wrbyte(1,line);}


void Lwr_ico(uchar ic)

{

uchar i0,i1;

  switch(ic){

case '0': case '1': case '2': case '3': case '4':

case '5': case '6': case '7': case '8': case '9':

  i0 = (ic-48)*4; i1 = i0+4; break; 

case 10: i0 = 65;  i1 = 75;  break; //电量满

case 11: i0 = 75;  i1 = 85;  break; //电量空

case 12: i0 = 40;  i1 = 50;  break; //信号有

case 13: i0 = 50;  i1 = 60;  break; //信号无

case 14: i0 = 60;  i1 = 65;  break; //文件

case 15: i0 = 137; i1 = 143; break; //运行图标

case 16: i0 = 143; i1 = 149; break; //暂停图标

case 17: i0 = 85;  i1 = 105; break; //GPS

case 18: i0 = 164; i1 = 173; break; //数据传输

case 19: i0 = 173; i1 = 180; break; //删除×

case 20: i0 = 180; i1 = 187; break; //上传

case 21: i0 = 187; i1 = 194; break; //等待

case 'D': i0 = 131; i1 = 137; break; //'D'

case ':': i0 = 115; i1 = 117; break; //':'

case '/': i0 = 105; i1 = 109; break; //'/'

case '.': i0 = 109; i1 = 111; break; //'.'

case '-': i0 = 111; i1 = 115; break; //'-'

case '%': i0 = 194; i1 = 202; break; //'%'

case 'k': i0 = 117; i1 = 131; break; //'kmh'

case 'm': i0 = 121; i1 = 127; break; //'m'

case 's': i0 = 159; i1 = 164; break; //'s'

case 'A': i0 = 202; i1 = 207; break; //'A'

case 'H': i0 = 207; i1 = 212; break; //'H'

case 'N': i0 = 212; i1 = 217; break; //'N'

case 'S': i0 = 217; i1 = 222; break; //'S'

case 'E': i0 = 222; i1 = 227; break; //'E'

case 'W': i0 = 227; i1 = 232; break; //'N'

case 22: i0 = 149; i1 = 152; break; //大'.'

case 23: i0 = 152; i1 = 156; break; // °

case 24: i0 = 156; i1 = 159; break; //'

case 25: i0 = 232; i1 = 235; break; //中点

case 26: i0 = 235; i1 = 238; break; //小度

default: i0 = ic*4; i1 = i0+4; break; //数字

}

for(;i0}


void Lwr_icos(uchar cs,uchar cl)

{

  uchar k;

for(k=0;k}


void Lwr_icoh(uchar *hs){ while(*hs){ Lwr_ico(*hs); hs++;}}


void L5_wr_chr(uchar nc)

{

uchar l,n;

switch(nc){

case 'N': n = 19; break;

case 'S': n = 22; break;

case 'E': n = 16; break;

case 'W': n = 24; break;

case 'H': n = 18; break;

case 'A': n = 14; break;

case 'G': n = 17; break;

case 'P': n = 20; break;

case 'R': n = 21; break;

case 'M': n = 18; break;

case 'C': n = 15; break;

case ',': n = 11; break;

case '.': n = 13; break;

case '-': n = 12; break;

case '*': n = 10; break;

case 'V': n = 23; break;

default: n = nc-48; break;

}

for(l=0;l<6;l++) L5_wrbyte(1,ASCII326[n][l]);

}


void L5_wr_chrs(uchar ch,uchar lc)

{

  uchar k;

for(k=0;k}


void L5_wr_chrh(uchar *hr){ while(*hr){ L5_wr_chr(*hr); hr++;}}


uchar chrtodec(uchar cd){return buf_gps[cd]-48;}

uchar chr_dec(uchar cf){ return chrtodec(cf)*10+chrtodec(cf+1);}

/void Lwr_dec(uchar dec){ Lwr_ico(dec/10); Lwr_ico(dec%10);}


void L5_RMC(void)

{

uchar tp_h,tp_y,tp_m,tp_d; 

bit flg_d=0;              

  L5_setxy(56,5); ofs = 3; line = 0x02;

tp_h = chr_dec(6)+8;

if(tp_h>23){ tp_h%=24; flg_d = 1;}   

Lwr_dec(tp_h); Lwr_ico(':');              

Lwr_icos(8,2); Lwr_ico(':'); Lwr_icos(10,2);

L5_CE = 1;

C64_buf[3] = tp_h;

C64_buf[4] = chr_dec(8); C64_buf[5] = chr_dec(10); 


L5_setxy(32,5);

tp_m = chr_dec(var_seg[8]+3);          

tp_d = chr_dec(var_seg[8]+1); 

if(flg_d){

switch(tp_m){

case 4: case 6: case 9: case 11:

[1] [2]
关键字:stc51  单片机  GPS定位  轨迹记录器 引用地址:stc51单片机做的GPS定位及轨迹记录器

上一篇:51单片机驱动CT1642数码管显示源程序
下一篇:L298N+AT89C52+BT-04A蓝牙控制遥控小车

推荐阅读最新更新时间:2024-11-13 09:12

一种基于低功耗单片机SN8P2711A的移动电源设计
随着3G移动互联网和智能终端的日益普及,随身可携带移动式电子产品越来越多、越来越普及。大屏幕智能手机、平板电脑、笔记本电脑、数码相机等便携式电子产品一般都使用可充电的锂离子供电,但是当电池没电时,就无法使用了。目前数码产品功能日益多样化,使用也更加频繁,如何延长移动电子产品使用时间,发挥其最大功用的问题就尤为重要了。为了保证外出时能让电子产品随时拥有充足的电能,一些用户开始选择移动电源给电子产品充电川。移动电源可以看成一种集储电、供电和充电功能于一体的便携电池充电器,可以给手机、平板电脑、相机等数码产品随时随地充电或待机供电,对移动电源的研究和开发也越来越多。移动电源技术可以说是固定电源技术的一种延伸和发展,本文结合充电器及单片机设
[单片机]
一种基于低功耗<font color='red'>单片机</font>SN8P2711A的移动电源设计
从零开始学单片机(六)键盘接口
键盘工作原理还是使用都是比较简单的。下面是4 4的阵列键盘,行分别接P3.0-P3.3,列接P3.4-P3.7,没有接电源。 采用查询法判断那一个按键被按下。例如,令P3=0xFE,然后在将P3跟0xFE比较,如果相等,说明S6-S9没有被按下,否则在判断P3高四位哪一位等于0。例如P3.4=0 则说明S6被按下。 注意: 手工按下键盘到释放这个过程大概50ms左右,在按下开始到弹簧片稳定接触这段时间为5-10ms,从释放到弹簧片完全分开也是5-10ms,在到达稳定接触和完全分开的微观过程中,电平是时高时低的,因为单片机的速度相对比较快,所以人感觉到只按下一次,单片机却检测到按下多次。如果在单片机首次检测到键盘按下时延时10ms左
[单片机]
从零开始学<font color='red'>单片机</font>(六)键盘接口
基于单片机的温度采集系统设计
摘要:本系统是以89C51单片机为控制核心技术的温度采集控制系统,介绍了与DS18B20温度传感器组成温度采集系统的设计方案。本温度采集系统的下位机采用89C51单片机为主控制器,利用DS18B20温度传感器进行溫度测量,采用数码管进行显示,并通过串口将采集的数据传送到上位机(PC机),通过上位机对温度进行集中监视和管理,解决了温度测量通常比较繁琐的问题,此测温系统实现了对温度数据的远程采集、处理、实时显示以及对溫度报表的管理。 随着时代的进步和发展,单片机已经普及到我们生活、工作、科研各个领域,而且温度是工业控制中主要的被控参数之一,特别是在冶金、化工、建材、食品、机械、石油等工业中具有举足轻重的作用。所以,温度测控在工业领
[单片机]
基于<font color='red'>单片机</font>的温度采集系统设计
单片机小白学习之路(十七)---计算初值
目标:学会计算初值 1.为什么要初值? 给单片机的定时器赋初值是为了取得准确的自己需要的定时时间,比如我想定时100秒 ,你数0--255要256秒(最大定时长),你赋个初值155,你就从156开始数了,数到255用100秒,实现了定时 初值就是为了定时存在的,相当于从头部剪裁,余下的长度 是你想要的 2.计算初值 初值 = 最大定时时间 - 定时时间 实例1 已知单片机的晶振是6Mhz,定时0.5ms,计算T0在方式1和方式2的初值。 (1)计算机器周期:T = 1/6Mhz * 12 = 2us  最小定时长:2us  最大定时时长:方式1:2^16 * 2us = 131.072ms         方式
[单片机]
如何设置51单片机的串行口来实现与PC机通信
一、原理简介 51单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。 与之前一样,首先我们来了解单片机串口相关的寄存器。 SBUF寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。从而控制外部两条独立的收发信号线RXD(P3.0)、TXD(P3.1),同时发送、接收数据,
[单片机]
如何设置51<font color='red'>单片机</font>的串行口来实现与PC机通信
STM8S105系列单片机管脚复用配置(选项字节的配置)
以STM8S105K4T6C为例,实现PB0管脚复用成TIM1_CH1N (1)STM8S复用功能(芯片引脚加 的功能):通过配置flash中的选项字节来实现 除了ROP(读出保护)字节,每个选项字节必须被保存两次,一个通常的格式(OPTx)和一个用来备份的互补格式(NOPTx) 参见STM8S105xx数据手册(如下图),可知备选功能重映射选项5(AFR5)负责管理PB0端口的重映射功能,将其设置为1即实现PB0重映射为TIM1_CH1N 相关代码: void Flash_Init() { FLASH_DeInit();
[单片机]
STM8S105系列<font color='red'>单片机</font>管脚复用配置(选项字节的配置)
ST iMOTION™ IMC300赋予Arm® MCU最佳灵活性
英飞凌科技股份公司(FSE: IFX / OTCQX: IFNNY)发布IMC300全新电机驱动控制器系列。该系列将iMOTION™运动控制引擎(MCE)和新增的基于Arm® Cortex®-M0内核的微控制器整合在一起。该系列是对IMC100系列的提升,主要针对有着非常高的应用灵活性需求的变频驱动。这两个系列都采用了MCE 2.0,能助力驱动电机,可选PFC控制功能。通过使用MCE进行电机控制,客户将能把精力集中在完全独立运行于嵌入式Arm®微控制器的系统应用上。 英飞凌经实践验证的MCE 2.0实现了永磁同步电机(PMSM)的高效的FOC(Field Oriented Control)控制。MCE集成了所需的所有硬件和软件
[工业控制]
基于单片机的通用测试仪的设计与实现
1 引言 在许多工业控制和数据采集系统中,为了实现系统的小型化和便携化,通常采用上下位机形式的主从式结构。 由于MCU(微控制器)成本低,编程灵活、方便,实时性强,且具有一定的智能,因而通常使用它作为下位机的主控芯片,负责对现场数据的采集与传输,并控制相应的执行机构。上位机一般使用普通的PC机、笔记本电脑或工控机,负责对下位机传来的数据进行分析处理, 并根据处理结果控制下位机的操作。上下位机之间的数据通信接口目前一般使用RS-232和USB总线接口标准,相对于RS-232,USB 具有高速传输、热插拔、即插即用等优点。在本系统中,为了保证下位机高速采样数据能及时传送给上位机进行分析处理,我们采用USB总线来实现上下位机的数据
[单片机]
基于<font color='red'>单片机</font>的通用测试仪的设计与实现
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved