单片机+北斗模块实现定位
本文原创,转载请注明出处。小编可能以后不会在简书简书地址上更新了,因为这里的markdown 编辑器太不好用了,没有CSDN 上面的好用,也希望粉丝们多多关注本人CSDN(一样的昵称呦)。
导航是继移动通信之后发展最快的信息产业之一,只要是设计到位置、速度、时间信息的领域斗鱼卫星导航技术相关。中国北斗卫星导航系统是我国自主研制的全球导航系统,是继美国定位系统(GPS)、俄罗斯格洛纳斯卫星导航系统之后的第三个成熟的卫星导航系统。随着北斗导航系统的不断完善,基于北斗导航系统的定位也应用的越来越广泛。小编采用的STC12C5A32S2单片机结合卫星接收模块UM220-III设计的北斗导航系统接收机,UM220-III是双模接收模块,能够同时接受GPS、北斗的信号。这次设计主要完成了导航信息接收机的基本设计,实现了获取实时的位置经纬度、标准时间等相关信息的显示功能。
1 原理介绍
采用以单片机为核心,读取北斗导航系统模块的标准数据,并在 LCD 屏幕上显示当前的经纬度信息。具体的系统方案图如下:
1.1北斗 UM220-III 模块简介
(1)接口电路
北斗模块芯片电路由北斗模块UM220-III N 和其附加电子器件组成。其中北斗模块外接4组排针,在芯片与电源之间串联电感的作用是起差模滤波作用,防止电流突变对芯片产生损坏,并联电感的作用是提高芯片运行的稳定性,防止产生噪声。
模块输入端口(UM220-III N 包括:RXD、GPIO、SDA ,SCL 等 如下图)为防止输入端不定态对模块造成影响,模块内置上拉电阻至VCC,因此在模块未加电时,如果上述端口有数据输入,会在模块VCC上形成串电,又可能造成模块上电失败。
case1:设计中使用 nRESET功能
在模块上电后,将nRESET拉低5 ms以上,即可确保模块正常启动。
case2:设计中未使用nRESET
在模块上电之前,保证模块已连接输入端口为高阻态或低电平,以避免串电。使用串口1的典型用户,需要吧RXD1设置为高阻态或低电平,未使用的其他PIN悬空。程序流程图如下:
(2)LCD 液晶显示器
LCD液晶显示器数据由单片机p0口进行控制,p2口进行指令控制操作。LCD1602是一种专门用来显示字母,数字,符号等的点阵型液晶模块。1602:显示的内容主要是16*2,即可以显示两行,每行16个字符液晶显示模块。相应的管教功能,百度上都是可以查阅的,所以小编这里就不赘述了。
(3)UM220-III 通信协议简介
在Unicore 协议中,输入和输出的语句被称为消息。每条消息均为ASCII 字符组成的字符串。
消息的基本格式为:KaTeX parse error: Can't use function '\r' in math mode at position 32: …2,data3,……[*cc]\̲r̲\n 所有的消息都以 '’(0x24)开始,后面紧跟着的就是消息名。之后的跟的就是不定数目的参数和数据。消息名与数据之间均以逗号隔开(0x2c)进行分割。最后一个参数是可选的校验和,以 ‘*’(0x2A)与前面的数据分割最后,输入的消息以 ’ \r\n’ 结束。每条消息的总长度不超过256个字节,消息名和参数,校验和中的字母不区分大小写。
某些输入命令的某些参数可以省略(在命令描述中被标记为可选)。这些参数可以为空,即在两个逗号之间没有任何字符。
2 调试方法
由1.1的原理简介可知,此次课题实现主要由 5 部分组成:系统初始化、设定显示模式、读取预显示内容、送扫描脉冲、送显示数据。
这里对单片机与模块的连接做简要说明。
UM220/um220-3-n 上带有两组 TTL 电平(2.85V),一组标准电平 RS232电平。当单片机的RS232电平接口接到UM220模块上的RS232上,正常通信。UM220模块上的RS232接口是DB9 母头,可以使用公头的连接线与RS230的接口相连,注意的是通信线需要交叉连接,就像TTL电平中的TXD - - RXD,RXD–TXD 一样,RS232电平通信中也是有2根通信电缆,一个是发送端(PCXD),一个是接收端(PCRXD)。若板子上的RS232 的接口是DB9 母头,那么 2 3针就是 PCRXD 和 PCTXD .第五针就是GND,若没有串口线来连接UM220模块的话,可以考虑在DB9下面的2 3 5 针 焊接出3跟线跟单片机的RS232连接。
若单片机是3.3V时,可以将单片机的TTL 接口连接到模块上的TTL接口。连接好后就可以编写程序了。
注意,我们使用的 52 单片机的驱动程序,使用的是11.05926 的晶振,波特率为9600.
#3 程序编写
程序主要是由5部分组成:系统初始化,设定显示模式。读取预显示内容,送扫描脉冲,送显示数据。小编只放主程序部分好了:
定义端口及变量
#include <REG52.H>
#include <stdio.h>
#include <intrins.h>
#include <lcd1602.h>
#include <uart.h>
#include <delay.h>
#include "string.h"
#include <stdlib.h>unsigned char flag_rec=0; //接收数据标志
unsigned char num_rec=0; // 计数标志
//char code TIME_AREA= 8; //时区,我们不需要它
unsigned char flag_data; //date flag
//only displaty cmd $GPGGA information
unsigned char JD[16]; //longitude
unsigned char JD_a; //经度方向
unsigned char WD[15]; //latitude
unsigned char WD_a; // 纬度方向
unsigned char date[6]; //date
unsigned char time[6]; //date
unsigned char time1[6]; //date
unsigned char speed[5]={'0','0','0','0','0'}; // 速度
unsigned char high[6]; // 高度
unsigned char angle[5]; //方位角
unsigned char use_sat[2]; // 卫星计数器
unsigned char total_sat[2]; //卫星总数
unsigned char lock; //位置状态//date handing variable
unsigned char seg_count; // 逗号计数器
unsigned char dot_count; //小数点计数器
unsigned char byte_count; // 位计数器
unsigned char cmd_number; // 命令模式
unsigned char mode; //
unsigned char buf_full;
unsigned char cmd[5]; // 存储命令模式//serial disconnect timer
unsigned long int tt=0;
主函数 系统初始化
//main
void main ()
{ int jd_second,wd_second; // 中间变量init_uart(); //初始化序列号lcd_init() ; // 初始化 lcd1602delay(200);LCD_Write_String(0,0,"Please Waiting..."); // "Please Waiting" when it is boot updelay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200); // 延迟显示write_com(0x01); // 清屏
设置延时函数,以形成视觉暂留
while(1)
{
tt++;
if(tt>10000){tt=10000;write_com(0x01);LCD_Write_String(3,0,"No Data!");LCD_Write_String(3,1,"No Data!");delay(200);delay(200);delay(200);delay(200);delay(200);}
···
读取预显示内容,设置显示格式,转16进制为10进制**
if(flag_rec==1) // 获取gps数据{flag_rec=0; // 清除标志符if (lock==1) // 获取位置信息{ //LCD_Write_String(0,0,"JD :"); // 显示经度LCD_Write_String(6,0,JD); // 显示数据LCD_Write_String(9,0,"."); // 进制转换LCD_Write_String(10,0,JD+3); jd_second=60*atof((char *)(JD+5)); LCD_Write_Char(13,0,jd_second/10+'0'); // 将上一步转换得到浮点数据打印在lcdLCD_Write_Char(14,0,jd_second%10+'0'); // 将上面得到的数据分为两部分,分别打印在LCD 上LCD_Write_Char(15,0,' '); //填充空间delay(200); // 保护lcdLCD_Write_String(0,1,"WD :"); // 显示下一行LCD_Write_String(6,1,WD);LCD_Write_String(8,1,"."); LCD_Write_String(9,1,WD+2); // 小数点wd_second=60*atof((char *)(WD+4));
// 将字符串转换成浮点数LCD_Write_Char(12,1,wd_second/10+'0');LCD_Write_Char(13,1,wd_second%10+'0');LCD_Write_String(14,1," ");delay(200);}}}}
串口中断函数及模式判断
判断的主要依据就是接收端接受消息与预结果匹配,通过设置数组[i,j]和if函数进行判断匹配(发送报文的消息内容见1.3的UM220的通信协议详解)
//serial interruupt service function
void ser_int (void) interrupt 4
{unsigned char tmp;if(RI){tt=0;RI=0;tmp=SBUF; // 从缓冲区接收数据switch(tmp) //if $GPGGA,$GNGSW,$GNRMC,get data then processing it{//date start with $case '$':cmd_number=0; // 清除命令模式mode=1; // 选项命令接收模式byte_count=0; //清除位计数器flag_data=1; // 设置数据标志flag_rec=1; // 设置数据接收标志break;case ',': //Eg:$GNRMC,134645.000,A,2603.964436,N,11912.410232,E,0.000,15.744,030718,,E,A*0Bseg_count++; // 计数器增加byte_count=0;break;case '*':switch(cmd_number){case 1:buf_full|=0x01; //00000001break;case 2:buf_full|=0x02; //00000010break;case 3:buf_full|=0x04; //00000100break;}mode=0; //clear modebreak;default:
// receive date cmdif(mode==1) {cmd[byte_count]=tmp; // 获取数据和存储缓冲区 if(byte_count>=4) //overlook cmd which less 4 bit{ if(cmd[0]=='G') // 第一个字符{if(cmd[1]=='N'){if(cmd[2]=='G'){if(cmd[3]=='G'){if(cmd[4]=='A')//判断$GNGGA{cmd_number=1; //数据类型mode=2; //接收日期seg_count=0; //comma counter clearbyte_count=0; //位计数器清除}}else if(cmd[3]=='S') //命令模式$GNGSV{if(cmd[4]=='V'){cmd_number=2;mode=2; //获取数据seg_count=0;byte_count=0;}}}else if(cmd[2]=='R') //命令模式 $GNRMC{if(cmd[3]=='M'){if(cmd[4]=='C'){cmd_number=3;mode=2; //存储数据seg_count=0;byte_count=0;}}}}}}}
//日期处理
else if(mode==2){switch (cmd_number) //if receive data{case 1: //get and store data,$GPGGA,[],[],[],[],[],[],[],[],[].....switch(seg_count) // comma 计数器{case 2: // 2rd逗号后的纬度if(byte_count<9){WD[byte_count]=tmp; //获取纬度}break;case 3: //纬度方向if(byte_count<1){WD_a=tmp;}break;case 4: //经度if(byte_count<10){JD[byte_count]=tmp; //存储}break;case 5: //经度方向if(byte_count<1){JD_a=tmp;}break;case 6: //locationif(byte_count<1){lock=tmp;}break;case 7: if(byte_count<2){use_sat[byte_count]=tmp;}break;case 9: // 高度if(byte_count<6){high[byte_count]=tmp;}break;}break;case 2: //命令模式 $GPGSVswitch(seg_count){case 3: // 卫星总数if(byte_count<2){total_sat[byte_count]=tmp;}break;}break;
//命令模式3:无SUEcase 3: //$GPRMCswitch(seg_count){case 1: //timeif(byte_count<6){ time[byte_count]=tmp; }break;case 2: // 位置 if(byte_count<1){if (tmp=='V') {lock=0;}else{lock=1;}}break;case 3: //lititude
// if(byte_count<9)
// {
// WD[byte_count]=tmp;//我们只需要一次
// }break;case 4: // if(byte_count<1){WD_a=tmp;}break;case 5: //
// if(byte_count<10)
// {
// JD[byte_count]=tmp; //do not get again
// }break;case 6: // 直线方向 if(byte_count<1){JD_a=tmp;}break;case 7: // 速度处理 if(byte_count<5){speed[byte_count]=tmp;}break;case 8: // 方向角 if(byte_count<5){angle[byte_count]=tmp;}break;case 9: //other if(byte_count<6){date[byte_count]=tmp;}break;}break;}}byte_count++; // 位计数器++break;}}
4 结果显示
单片机+北斗模块实现定位相关推荐
- stm32单片机 北斗GPS 定位 vb上位机显示。 蓝牙主从级通信
stm32单片机 北斗GPS 定位 vb上位机显示. 蓝牙主从级通信. 主单片机获取GPS北斗模块定位信息后,通过蓝牙发送给从模块. 从蓝牙模块,从模块通过串口讲定位信息发送给vb上位机. 上位机实时 ...
- 北斗和GPS定位在室外非常好用,但当手机进入室内时,它们的定位功能就很不准,甚至无法定位。我们可以开启WLAN扫描定位WIFI模块固定编码或者开启手机的A-GPS辅助定位通过基站,A-GPS服务器定位
手机定位已经成为人们生产生活必不可少的工具,但有些人的手机定位又快又准,有些人的手机定位时常又慢又偏差大.那该如何解决呢?可以通过下面两个设置来提高定位速度和精度. 1.A-GPS辅助,提高室外定位速 ...
- 北斗定位导航系统,北斗模块应用领域发展概况_北斗二号模块,北斗三号模块
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.北斗系统概述 1.1 空间段 1.2 地面控制段 1.3 用户段 1.4 坐标系统 1.5 时间系统 二.北斗系统 ...
- GPS北斗模块串口助手输出测试
GPS北斗模块测试 材料:北斗模块.usb转ttl.杜邦线. 1.模块接线如下图所示(可用5v跟3.3v): 2.usb转ttl连接电脑通电指示灯亮: 3.电脑通过串口调试助手可以收到北斗模块发送的数 ...
- GPS/北斗模块小小总结
这次用的是正点原子的ATK-S1216F8-BD模块. 通过看资料,准备从以下几点来研究研究这个模块. 1.它有哪些优点 2.模块引脚的作用 3.与单片机连接 1.优点:首先它的体积小,可通过串口进行 ...
- 北斗GNSS卫星导航定位芯片架构和设计发展趋势
随着北斗卫星系统技术的发展,国内北斗导航定位芯片行业也迅猛发展,芯片技术成为全球各个国家竞争的制高点之一,作为高端制造业的"皇冠明珠",芯片是衡量一个国家综合实力的重要标志之一,是 ...
- 北斗信号服务器解算,北斗导航系统接收机定位解算设计与实现
摘要: 随着北斗导航系统的建设不断推进,其应用范围越来越广,因此北斗接收机需求也越来越大.不同的应用场景的接收机结构和侧重点有所不同,但是其中的定位解算模块都是其关键部分.本文主要对北斗接收机的整体结 ...
- 集成式单片机外部模块驱动编写详解——AD5689为例
集成式单片机外部模块驱动编写详解--AD5689为例 集成式驱动原理 AD5689基本介绍 AD5689驱动抽象及源码解释 源码 参考资料 具体的代码和例程请参照以下GitHub仓库,记得给我star ...
- adc量化单位_单片机外围模块漫谈之二,如何提高ADC转换精度
在此我们简要总结一下ADC的各种指标如何理解,以及从硬件到软件都有哪些可以采用的手段来提高ADC的转换精度. 1. ADC指标 除了分辨率,速度,输入范围这些基本指标外,衡量一个ADC好坏通常会用到以 ...
最新文章
- csharp:Chart
- Visual Studio Code 配置指南
- Java StringBuffer的用法
- git pull 失败 ,提示:fatal: refusing to merge unrelated histories
- JS中SetTimeOut和SetInterval方法的区别?
- sql union 和 union all
- Java提高篇——equals()方法和“==”运算符
- mqtt之C++编译
- C# Winform 自动更新程序实例
- java怎么控制页面打印次数_java – 控制打印页面上面板的大小
- 直播行业迎来多元化发展
- 艾肯micu声卡调试安装教程
- 深信服python开发工程师面试经验,深信服软件工程师面试经验
- java数组和链表查询效率及增删效率比较
- line-height1.5和line-height:150%的区别
- 2020腾讯阅文集团-前端笔试题
- 警用宽窄带融合技术国际学术交流会成功召开
- google chrome插件
- 新版BIOS U盘启动装机
- STM32使用内部RC振荡器作为系统时钟开发项目--内晶振启动模板工程