本次使用STM32F4的USART1对GPS模块进行驱动,并且将GPS的时间、经纬度通过串口打印出来。
gps模块与接线图 注意:GPS 模块需放到窗户边/阳台,否则可能收不到 GPS 信号。
1、GPS驱动配置(gps.c)
#include "includes.h"
struct GPS_Data Save_Data;
void clrStruct(void)
{
Save_Data.isGetData = false;
Save_Data.isParseData = false;
Save_Data.isUsefull = false;
memset(Save_Data.GPS_Buffer, 0, 200);
memset(Save_Data.UTCTime, 0, 20);
memset(Save_Data.latitude, 0, 20);
memset(Save_Data.N_S, 0, 2);
memset(Save_Data.longitude, 0, 20);
memset(Save_Data.E_W, 0, 2);
}
void parseGpsBuffer(void)
{
char *subString=NULL;
char *subStringNext=NULL;
char i = 0;
if (Save_Data.isGetData)
{
Save_Data.isGetData = false;
for (i = 0 ; i <= 9 ; i++)
{
if (i == 0)
{
if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
errorLog(1);
}
else
{
subString++;
if ((subStringNext = strstr(subString, ",")) != NULL)
{
char usefullBuffer[2];
switch(i)
{
case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break;
case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break;
case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break;
case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;
case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break;
case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;
case 7:break;
case 8:break;
case 9:memcpy(Save_Data.UTCDay, subString, subStringNext - subString);break;
default:break;
}
subString = subStringNext;
Save_Data.isParseData = true;
if(usefullBuffer[0] == 'A')
Save_Data.isUsefull = true;
else if(usefullBuffer[0] == 'V')
Save_Data.isUsefull = false;
}
else
{
errorLog(2);
}
}
}
}
}
void printGpsBuffer(void)
{
u8 year,month,day,hour,minute,second,week;
double latitude,longitude;
if (Save_Data.isParseData)
{
Save_Data.isParseData = false;
hour =(Save_Data.UTCTime[0]-'0')*10+(Save_Data.UTCTime[1]-'0')+8;
minute =(Save_Data.UTCTime[2]-'0')*10 +(Save_Data.UTCTime[3]-'0');
second =(Save_Data.UTCTime[4]-'0')*10 +(Save_Data.UTCTime[5]-'0');
if(Save_Data.isUsefull)
{
Save_Data.isUsefull = false;
latitude= atof( Save_Data.latitude);
latitude/=100;
longitude= atof( Save_Data.longitude);
longitude/=100;
year =(Save_Data.UTCDay[4]-'0')*10+(Save_Data.UTCDay[5]-'0');
month =(Save_Data.UTCDay[2]-'0')*10 +(Save_Data.UTCDay[3]-'0');
day =(Save_Data.UTCDay[0]-'0')*10 +(Save_Data.UTCDay[1]-'0');
printf("当前时间: 20%d-%d-%d %d:%d:%d\r\n",year,month,day,hour,minute,second);
printf("当前纬度 %s:%f°\r\n",Save_Data.N_S,latitude);
printf("当前经度 %s:%f°\r\n",Save_Data.E_W,longitude);
}
else
{
printf("GPS DATA is not usefull!\r\n");
}
}
}
void errorLog(int num)
{
while (1)
{
printf("ERROR%d\r\n",num);
}
}
2、GPS函数声明(gps.h)
#ifndef GPS_H
#define GPS_H
#include "stm32f4xx.h"
#define false 0
#define true 1
struct GPS_Data
{
char GPS_Buffer[200];
char isGetData;
char isParseData;
char UTCTime[20];
char latitude[20];
char N_S[2];
char longitude[20];
char E_W[2];
char isUsefull;
char UTCDay[20];
};
extern struct GPS_Data Save_Data;
void clrStruct(void);
void errorLog(int num);
void parseGpsBuffer(void);
void printGpsBuffer(void);
#endif
3、串口驱动配置(usart1.c)注意串口中断函数
#include "includes.h"
void USART1_init(int boand )
{
int OVER8 =0 ;
float USARTDIV ;
int DIV_Fraction;
int DIV_Mantissa ;
RCC->AHB1ENR |=(1<<0);
GPIOA->MODER &=~(0X3<<18);
GPIOA->MODER |=(0X2<<18);
GPIOA->AFR[1] &=~(0XF<<4);
GPIOA->AFR[1] |=(0X7<<4);
GPIOA->MODER &=~(0X3<<20);
GPIOA->MODER |=(0X2<<20);
GPIOA->AFR[1] &=~(0XF<<8);
GPIOA->AFR[1] |=(0X7<<8);
RCC->APB2ENR |=(1<<4);
USART1->CR1 |=(1<<13);
USART1->CR1 &=~(1<<10);
USART1->CR1 |=(1<<3);
USART1->CR1 |=(1<<2);
USART1->CR1 &=~(1<<0);
#ifdef MY_OVER8
USART1->CR1 &=~(1<<15);
OVER8 =0;
#else
USART1->CR1 |=(1<<15);
OVER8 =1;
#endif
USARTDIV =(float)84000000/(8*(2-OVER8)*boand);
DIV_Mantissa =USARTDIV;
DIV_Fraction =(USARTDIV-DIV_Mantissa)*8*(2-OVER8);
USART1->BRR = DIV_Mantissa<<4 | DIV_Fraction;
USART1->CR1 |=(1<<5);
MY_NVIC_init(7-2,1,1,USART1_IRQn);
}
void USART1_Sendbyte(u8 data)
{
while((USART1->SR &(1<<6))==0)
{
;
}
USART1->DR =data;
}
void USART1_Sendstring(u8 *buf)
{
while(*buf !='\0')
{
USART1_Sendbyte(*buf);
buf++;
}
USART1_Sendbyte('\r');
USART1_Sendbyte('\n');
}
u8 USART1_Receivebyte(void)
{
u8 data;
while((USART1->SR &(1<<5))==0)
{
;
}
data =USART1->DR;
return data;
}
void USART1_Receivestring(u8 *buf)
{
u8 ch;
while(1)
{
ch =USART1_Receivebyte();
if(ch ==' ' || ch =='\r' || ch=='\n')
{
break;
}
*buf =ch;
buf++;
}
*buf ='\0';
}
#pragma import(__use_no_semihosting_swi)
struct __FILE { int handle; };
FILE __stdout;
int fputc(int ch, FILE *f) {
USART1_Sendbyte(ch);
return (ch);
}
int ferror(FILE *f) {
return EOF;
}
void _ttywrch(int ch) {
USART1_Sendbyte(ch);
}
u16 point1 = 0;
char USART_RX_BUF[200];
void USART1_IRQHandler(void)
{
u8 Res;
Res =USART1->DR;
if(Res == '$')
{
point1 = 0;
}
USART_RX_BUF[point1++] = Res;
if(USART_RX_BUF[0] == '$' && USART_RX_BUF[4] == 'M' && USART_RX_BUF[5] == 'C')
{
if(Res == '\n')
{
memset(Save_Data.GPS_Buffer, 0, 100);
memcpy(Save_Data.GPS_Buffer, USART_RX_BUF, point1);
Save_Data.isGetData = true;
point1 = 0;
memset(USART_RX_BUF, 0, 200);
}
}
if(point1 >= 200)
{
point1 = 200;
}
}
4、串口函数声明(usart1.h)
#ifndef USART1_H
#define USART1_H
#include "stm32f4xx.h"
#define MY_OVER8
void USART1_init(int boand );
void USART1_Sendbyte(u8 data);
void USART1_Sendstring(u8 *buf);
u8 USART1_Receivebyte(void);
void USART1_Receivestring(u8 *buf);
#endif
5、主函数(main.c)
#include "includes.h"
int main()
{
USART1_init(9600);
clrStruct();
while(1)
{
parseGpsBuffer();
printGpsBuffer();
}
return 0;
}
整个程序代码与使用手册上传至:https://download.csdn.net/download/qq_37619128/84225570
|