全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 通信网络 >

GPS模块与ATmega16接口查找位置坐标的方式

时间:2022-08-24 15:19

人气:

作者:admin

标签: GPS模块  ATmega16 

导读:GPS 模块广泛用于电子应用中,以根据经度和纬度坐标跟踪位置。车辆跟踪系统、 GPS 时钟、 事故检测警报系统、交通导航、监控系统等是 GPS 功能必不可少的几个例子。GPS 提供海拔、纬...

GPS 模块广泛用于电子应用中,以根据经度和纬度坐标跟踪位置。车辆跟踪系统、 GPS 时钟、 事故检测警报系统、交通导航、监控系统等是 GPS 功能必不可少的几个例子。GPS 提供海拔、纬度、经度、UTC 时间和有关特定位置的许多其他信息,这些信息来自多颗卫星。要从 GPS 读取数据,需要一个微控制器,因此我们将GPS 模块与 AVR 微控制器Atmega16 连接,并在16x2 LCD 显示屏上打印经度和纬度。

所需组件

Atmega16/32

GPS 模块(uBlox Neo 6M GPS)

长线天线

16x2 液晶

2.2k电阻

1000uf电容

10uF电容

连接线

LM7805

直流插孔

12v 直流适配器

小贴士

PCB或通用PCB

Ublox Neo 6M 是一个串行 GPS 模块,通过串行通信提供位置详细信息。它有四个引脚。

poYBAGMFz5qADR-JAAANUuzQlaw213.png

pYYBAGMFz5aAe776AASEYC2YTxs225.png

Ublox neo 6M GPS 模块与 TTL 兼容,其规格如下。

pYYBAGMFz5KAR1jAAAATN2wb8yU524.png

从 GPS 获取位置数据

GPS 模块将以 9600 波特率在多个字符串中传输数据。如果我们使用波特率为 9600 的 UART 终端,我们可以看到 GPS 接收到的数据。

这是以 9600 波特率连接时 GPS 接收到的数据。

$GPRMC,141848.00,A,2237.63306,N,08820.86316,E,0.553,,100418,,,A*73 
$GPVTG,,T,,M,0.553,N,1.024,K,A*27 
$GPGGA,141848.00, 2237.63306,N,08820.86316,E,1,03,2.56,1.9,M,-54.2, M,,*74 
$GPGSA,A,2,06,02,05,,,,,,,,,,2.75, 2.56,1.00*02 
$GPGSV,1,1,04,02,59,316,30,05,43,188,25,06,44,022,23,25,03,324,*76 
$GPGLL,2237.63306,N,08820.86316,E,141848.00 ,A,A*65

当我们使用 GPS 模块跟踪任何位置时,我们只需要坐标,我们可以在 $GPGGA 字符串中找到它。只有 $GPGGA(全球定位系统固定数据)字符串主要用于程序中,其他字符串被忽略。

$GPGGA,141848.00,2237.63306,N,08820.86316,E,1,03,2.56,1.9,M,-54.2,M,,*74

所以我们需要 5 号和 6 号来收集有关模块位置或它所在位置的信息。在这个项目中,我们使用了一个 GPS 库,它提供了一些函数来提取纬度和经度,所以我们不必担心这一点。

电路原理

GPS与AVR Atemga16微控制器接口的电路图如下:

poYBAGMF0F-AMQokAAFGaL7_f6Y614.png

整个系统由 12v 直流适配器供电,但电路工作在 5v 上,因此电源由 LM7805 稳压器调节至 5v。16x2 LCD 配置为 4 位模式 ,其引脚连接如电路图所示。GPS 也由 5v 供电,其 tx 引脚直接连接到Atmega16 微控制器的 Rx 。一个 8MHz 晶体振荡器用于为微控制器提供时钟。

pYYBAGMF0FuAEvkUAATThw4d-Ec447.png

将 GPS 与 AVR 微控制器连接的步骤

设置微控制器的配置,包括振荡器配置。

设置 LCD 的所需端口,包括 DDR 寄存器

使用 USART 将 GPS 模块连接到微控制器。

在 ISR 模式下初始化系统 UART,波特率为 9600,LCD 为 4 位模式。

根据纬度和经度的长度取两个字符数组。

每次接收一个字符位,并检查它是否从 $ 开始。

如果接收到$,那么它是一个字符串,我们需要检查$GPGGA,这6个字母包括$。

如果是 GPGGA,则接收完整的字符串并设置标志。

然后用两个数组中的方向提取纬度和经度。

最后在 LCD 中打印经纬度数组。

poYBAGMF0FeAFMT6AASpFAtumz8141.png

代码说明

最后给出了完整的代码和演示视频,这里解释了代码的一些重要部分。

首先在代码中包含一些必需的标头,然后为 LCD 和 UART 配置编写位掩码的 MACROS

#define F_CPU 8000000ul 
#include  
#include  
#include 

/***MACROS*/ 
#define USART_BAUDRATE 9600 
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

#define LCDPORTDIR DDRB 
#define LCDPORT PORTB 
#define rs 0 
#define rw 1 
#define en 2

#define RSLow (LCDPORT&=~(1<

现在声明并初始化一些变量和数组,用于存储 GPS 字符串、纬度经度和标志。

字符缓冲区[100];
volatile char ind、flag、stringReceived;
char gpgga[]={'$','G','P','G','G','A'};

字符纬度[12];
字符对数[12];

之后我们有一些 LCD Driver 函数来驱动 LCD。

无效 lcdwrite(char ch,char r) 
{ 
     LCDPORT=ch & 0xF0; 
     RW 低;
     如果(r == 1)
     RSHigh;
     否则
     RS低;
     EN高;
     _delay_ms(1); 
     低; 
     _delay_ms(1); 
     LCDPORT=ch<<4 & 0xF0; 
     RW 低;
     如果(r == 1)
     RSHigh;
     否则
     RS低;
     EN高;
     _delay_ms(1); 
     低; 
     _delay_ms(1); 
}

void lcdprint(char *str) 
{ 
     while(*str) 
     { 
          lcdwrite(*str++,DATA); 
          //__delay_ms(20); 
     } 
}

无效 lcdbegin() 
{ 
     char lcdcmd[5]={0x02,0x28,0x0E,0x06,0x01}; 
     for(int i=0;i<5;i++) 
     lcdwrite(lcdcmd[i], CMD); 
}

之后,我们初始化了与 GPS的串行通信,并将接收到的字符串与 "GPGGA" 进行比较:

void serialbegin() 
{ 
     UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); 
     UBRRH = (BAUD_PRESCALE >> 8); 
     UBRRL = BAUD_PRESCALE;
     UCSRB=(1<=50) 
           stringReceived=1; 
}

void serialwrite(char ch) 
{ 
     while ((UCSRA & (1 << UDRE)) == 0); 
     UDR = 通道;
}

现在如果接收到的字符串与 GPGGA 匹配成功,则在main函数中提取并显示该位置的经纬度坐标:

液晶写入(0x80,0);
                lcdprint("纬度:"); 
                serialprint("纬度:"); 
                for(int i=15;i<27;i++) 
                {
                     纬度[i]=buf[i]; 
                     lcdwrite(纬度[i],1); 
                     串行写入(纬度 [i]);
                     if(i==24) 
                     { 
                          lcdwrite(' ',1); 
                          我++;
                     } 
                } 
                serialprintln(""); 
                液晶写入(192,0);
                lcdprint("日志:"); 
                serialprint("Logitude:");
                for(int i=29;i<41;i++) 
                { 
                     logitude[i]=buf[i]; 
                     lcdwrite(logitude[i],1); 
                     串行写入(logitude [i]);
                     if(i==38) 
                     { 
                           lcdwrite(' ',1); 
                           我++;
                     } 
                }

这就是GPS 模块如何与 ATmega16 接口以查找位置坐标的方式。

/*

* GPS_interfacing.c

*

* 创建时间:2019 年 8 月 26 日晚上 10:17:24

* 作者:埃文

*/





#define F_CPU 8000000ul

#include

#include

#include



/***宏*/



#define USART_BAUDRATE 9600

#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)



#define LCDPORTDIR DDRB

#define LCDPORT PORTB

#定义rs 0

#define rw 1

#define en 2



#define RSLow (LCDPORT&=~(1<
#define RSHigh (LCDPORT|=(1<
#define RWLow (LCDPORT&=~(1<
#define ENLow (LCDPORT&=~(1<
#define ENHigh (LCDPORT|=(1<




枚举

{

CMD=0,

数据,

};



字符缓冲区6be48a06f25293df2b9b68987ad63bd86ac0ac266c52593311734a736c236d74QzpcVXNlcnNcQWRtaW5pc3RyYXRvclxBcHBEYXRhXFJvYW1pbmdcRGluZ1RhbGtcZGVmRW1vdGlvblxlbW90aW9uXzEwOC5wbmc=

volatile char ind、flag、stringReceived;

char gpgga[]={'$','G','P','G','G','A'};



字符纬度[12];

字符对数[12];



无效串行写入(字符 ch);



无效 lcdwrite(char ch,char r)

{

LCDPORT=ch & 0xF0;

RW 低;

如果(r == 1)

RS高;

别的

RS低;

EN高;

_delay_ms(1);

低;

_delay_ms(1);



LCDPORT=ch<<4 & 0xF0;

RW 低;

如果(r == 1)

RS高;

别的

RS低;

EN高;

_delay_ms(1);

低;

_delay_ms(1);

}



无效液晶打印(字符 *str)

{

而(*str)

{

lcdwrite(*str++,DATA);

//__delay_ms(20);

}

}



无效液晶开始()

{

字符 lcdcmd[5]={0x02,0x28,0x0E,0x06,0x01};

for(int i=0;i<5;i++)

lcdwrite(lcdcmd[i], CMD);

}



无效序列开始()

{

UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);

UBRRH = (BAUD_PRESCALE >> 8);

UBRRL = BAUD_PRESCALE;

UCSRB=(1<
}



ISR(USART_RXC_vect)

{

字符 ch=UDR;

buf[ind]=ch;

IND++;

如果(指数<7)

{

if(buf[ind-1] != gpgga[ind-1]) // $GPGGA

指数=0;

}

如果(指数>=50)

字符串接收=1;

}



无效串行写入(字符 ch)

{

而 ((UCSRA & (1 << UDRE)) == 0);

UDR = 通道;

}



无效序列打印(字符 *str)

{

而(*str)

{

串行写入(*str++);

}

}



无效串行打印(字符 *str)

{

序列打印(str);

串行写入(0x0d);

串行写入(0x0a);

}



主函数()

{

LCDPORTDIR=0xFF;

序列开始();

serialprint("萨达姆汗");

液晶开始();

lcdprint("GPS 接口");

液晶写入(192,CMD);

lcdprint("使用 Atmega16");

_delay_ms(2000);

液晶写入(1,0);

lcdprint("正在等待 GPS");

_delay_ms(2000);

sei();

而(1)

{

如果(字符串接收 == 1)

{

cli();

serialprint("收到的字符串:");

for(int i=0;i
串行写入(buf[i]);

指数=0;

字符串接收=0;

串行打印(“”);

液晶写入(0x80,0);

lcdprint("纬度:");

serialprint("纬度:");

for(int i=15;i<27;i++)

{

纬度[i]=buf[i];

lcdwrite(纬度[i],1);

串行写入(纬度 [i]);

如果(我==24)

{

lcdwrite('',1);

我++;

}

}

串行打印(“”);

液晶写入(192,0);

lcdprint("日志:");

serialprint("Logitude:");

for(int i=29;i<41;i++)

{

对数[i]=buf[i];

lcdwrite(logitude[i],1);

串行写入(logitude [i]);

如果(我==38)

{

lcdwrite('',1);

我++;

}



}

串行打印(“”);

串行冲洗();

_delay_ms(2000);

sei();

}

}

返回0;

}

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信