0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

科技观察员 来源:circuitdigest 作者:萨达姆 2022-08-24 15:19 次阅读

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;

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ATmega16
    +关注

    关注

    5

    文章

    154

    浏览量

    45558
  • GPS模块
    +关注

    关注

    0

    文章

    85

    浏览量

    16142
  • AVR微控制器
    +关注

    关注

    0

    文章

    11

    浏览量

    6786
收藏 人收藏

    评论

    相关推荐

    Atmega16用progisp下载报错

    Atmega16用progisp下载报错flash verify error at :0h 一番辛苦查找原因,终于找到一个解决方案,可以参考一下。首先,确保ATmega16单片机没有一直被复位,并且
    发表于 07-13 08:23

    单片机atmega16的一些技术参数

    单片机atmega16的一些技术参数,方便大家查找
    发表于 01-05 16:35 14次下载

    关于ATmega16知识教程教程分享

    ATmega16教程11-4
    的头像 发表于 07-04 09:47 4469次阅读

    ATmega16教程:键盘原理与应用(1)

    ATmega16教程5-1
    的头像 发表于 07-11 00:21 2862次阅读

    ATmega16教程:键盘原理与应用(2)

    ATmega16教程5-2
    的头像 发表于 07-11 00:18 3039次阅读

    ATmega16教程视频讲解(6)

    ATmega16教程第6讲
    的头像 发表于 07-11 00:25 2794次阅读

    ATmega16教程:DA,AD (1)

    ATmega16教程8-1
    的头像 发表于 07-11 00:46 4188次阅读

    ATmega16教程:DA,AD (2)

    ATmega16教程8-2
    的头像 发表于 07-11 00:49 3654次阅读

    ATmega16教程:中断,定时器(1)

    ATmega16教程第7-1讲
    的头像 发表于 07-11 00:50 4848次阅读

    ATmega16教程:串行TWI(I2C) (2)

    ATmega16教程9-2
    的头像 发表于 07-11 00:35 4569次阅读

    ATmega16教程:UART(2)

    ATmega16教程10-2
    的头像 发表于 07-11 00:29 3824次阅读

    ATmega16教程:UART (1)

    ATmega16教程10-1
    的头像 发表于 07-11 00:22 3916次阅读

    ATmega16教程:TWI(I2C) (1)

    ATmega16教程9-1
    的头像 发表于 07-11 00:19 4886次阅读

    ATmega16单片机教程之ATmega16单片机定时器的分析与设计应用概述

    本文档的主要内容详细介绍的是ATmega16单片机教程之ATmega16单片机定时器的分析与设计应用概述主要内容包括了:1、单片机定时器的基本应用、原理及要素2、ATmega 1 6单片机定时器
    发表于 12-07 08:00 13次下载
    <b class='flag-5'>ATmega16</b>单片机教程之<b class='flag-5'>ATmega16</b>单片机定时器的分析与设计应用概述

    如何使用STM32F103C8的GPS模块获取位置坐标

    在本教程中,我们将GPS 模块与 STM32F103C8 微控制器连接,以查找位置坐标并将其显示在16
    的头像 发表于 09-08 15:03 7167次阅读
    如何使用STM32F103C8的<b class='flag-5'>GPS</b><b class='flag-5'>模块</b>获取<b class='flag-5'>位置</b><b class='flag-5'>坐标</b>