Serial.c
#include "Serial.h"
char rxdatabufer;
u16 point1 = 0;
_SaveData Save_Data;
uint8_t Serial_RxData;
uint8_t Serial_RxFlag;
char USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
u16 USART_RX_STA=0; //接收状态标记
void Serial_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1,ENABLE);
CLR_Buf();
}
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{
uint16_t i;
for (i = 0;i < Length;i ++)
{
Serial_SendByte(Array[i]);
}
}
void Serial_SendString(char *String)
{
uint8_t i;
for (i = 0;String[i] != '\0';i ++)
{
Serial_SendByte(String[i]);
}
}
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{
uint32_t Result = 1;
while (Y --)
{
Result *= X;
}
return Result;
}
void Serial_SendNumber(uint32_t Number,uint8_t Length)
{
uint8_t i;
for (i = 0;i < Length;i ++)
{
Serial_SendByte(Number / Serial_Pow(10,Length - i - 1) % 10 + 0x30 );
}
}
int fputc(int ch,FILE *f)
{
Serial_SendByte(ch);
return ch;
}
void Serial_Printf(char *format,...)
{
char String[100];
va_list arg;
va_start(arg,format);
vsprintf(String,format,arg);
va_end(arg);
Serial_SendString(String);
}
uint8_t Serial_GetRxFlag(void)
{
if (Serial_RxFlag == 1)
{
Serial_RxFlag = 0;
return 1;
}
return 0;
}
uint8_t Serial_GetRxData(void)
{
return Serial_RxData;
}
void USART1_IRQHandler(void)
{
u8 Res;
if (USART_GetFlagStatus(USART1,USART_IT_RXNE) == SET)
{
Res = USART_ReceiveData(USART1);
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, GPS_Buffer_Length); //清空
memcpy(Save_Data.GPS_Buffer, USART_RX_BUF, point1); //保存数据
Save_Data.isGetData = true;
point1 = 0;
memset(USART_RX_BUF, 0, USART_REC_LEN); //清空
}
}
if(point1 >= USART_REC_LEN)
{
point1 = USART_REC_LEN;
}
USART_ClearFlag(USART1,USART_IT_RXNE);
}
}
void CLR_Buf(void) // 串口缓存清理
{
memset(USART_RX_BUF, 0, USART_REC_LEN); //清空
point1 = 0;
}
void clrStruct(void)
{
Save_Data.isGetData = false;
Save_Data.isParseData = false;
Save_Data.isUsefull = false;
memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length); //清空
memset(Save_Data.UTCTime, 0, UTCTime_Length);
memset(Save_Data.latitude, 0, latitude_Length);
memset(Save_Data.N_S, 0, N_S_Length);
memset(Save_Data.longitude, 0, longitude_Length);
memset(Save_Data.E_W, 0, E_W_Length);
}
Serial.h
#ifndef _SERIAL_H
#define _SERIAL_H
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>
#include "string.h"
#define USART_REC_LEN 200 //定义最大接收字节数 200
#define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
extern char USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
#define false 0
#define true 1
//定义数组长度
#define GPS_Buffer_Length 200
#define UTCTime_Length 20
#define latitude_Length 20
#define N_S_Length 2
#define longitude_Length 20
#define E_W_Length 2
typedef struct SaveData
{
char GPS_Buffer[GPS_Buffer_Length];
char isGetData; //是否获取到GPS数据
char isParseData; //是否解析完成
char UTCTime[UTCTime_Length]; //UTC时间
char latitude[latitude_Length]; //纬度
char N_S[N_S_Length]; //N/S
char longitude[longitude_Length]; //经度
char E_W[E_W_Length]; //E/W
char isUsefull; //定位信息是否有效
} _SaveData;
void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array,uint16_t Length);
void Serial_SendString(char *String);
void Serial_Printf(char *format,...);
void Serial_SendNumber(uint32_t Number,uint8_t Length);
uint8_t Serial_GetRxFlag(void);
uint8_t Serial_GetRxData(void);
void USART1_IRQHandler(void);
extern char rxdatabufer;
extern u16 point1;
extern _SaveData Save_Data;
void CLR_Buf(void);
void clrStruct(void);
#endif
main.c
#include "stm32f10x.h" // Device header
#include "LED.h"
#include "Delay.h"
#include "Serial.h"
#include <ctype.h>
#include <stdlib.h>
//声明
void errorLog(int num);
void parseGpsBuffer(void);
void printGpsBuffer(void);
double latitude_degrees,longitude_degrees;
char hours[3];
char minute[3];
char seconds[6]; // 分别用于存储时、分、秒及小数秒部分的字符串
int main(void)
{
LED_Init();
Serial_Init();
clrStruct();
Serial_Printf("Welcome to use!\r\n");
Serial_Printf("DRG Board.com!\r\n");
while(1)
{
// LED_Turn();
// Delay_ms(500);
parseGpsBuffer();
printGpsBuffer();
}
}
void errorLog(int num)
{
while (1)
{
Serial_Printf("ERROR%d\r\n",num);
}
}
void parseGpsBuffer()
{
char *subString;
char *subStringNext;
char i = 0;
if (Save_Data.isGetData)
{
Save_Data.isGetData = false;
Serial_Printf("**************\r\n");
Serial_Printf(Save_Data.GPS_Buffer);
for (i = 0 ; i <= 6 ; i++)
{
if (i == 0)
{
if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
errorLog(1); //解析错误
}
else
{
// 跳过前面的逗号以及可能存在的空格等空白字符,确保准确指向字段起始位置
while (*subString == ',' || isspace(*subString))
{
subString++;
}
if ((subStringNext = strstr(subString, ",")) != NULL)
{
char usefullBuffer[2];
char degrees_str[4]; // 用于临时存储度的字符串,经度度数可能有三位数,所以大小设为4
char minutes_str[12];
double degrees, minutes;
switch(i)
{
case 1:
{
size_t length = subStringNext - subString;
if (length > sizeof(Save_Data.UTCTime) - 1)
{
length = sizeof(Save_Data.UTCTime) - 1;
}
memcpy(Save_Data.UTCTime, subString, length);
Save_Data.UTCTime[length] = '\0';
// 提取小时部分
strncpy(hours, Save_Data.UTCTime, 2);
hours[2] = '\0';
// 提取分钟部分
strncpy( minute, Save_Data.UTCTime + 2, 2);
minute[2] = '\0';
// 提取秒及小数秒部分
strcpy(seconds, Save_Data.UTCTime + 4);
break; //获取UTC时间
}
case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break; //获取UTC时间
case 3:
{
memcpy(Save_Data.latitude, subString, subStringNext - subString);
// 提取度的值
strncpy(degrees_str, Save_Data.latitude, 2);
degrees_str[2] = '\0';
degrees = atof(degrees_str);
// 提取分的值
strcpy(minutes_str, Save_Data.latitude + 2);
minutes = atof(minutes_str);
// 转换为度
latitude_degrees = degrees+(minutes/60);
break; //获取纬度信息
}
case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break; //获取N/S
case 5:
{
memcpy(Save_Data.longitude, subString, subStringNext - subString);
// 提取度的值
strncpy(degrees_str, Save_Data.longitude, 3);
degrees_str[3] = '\0';
degrees = atof(degrees_str);
// 提取分的值
strcpy(minutes_str, Save_Data.longitude + 3);
minutes = atof(minutes_str);
// 转换为度
longitude_degrees = degrees + (minutes / 60);
break; //获取经度信息
}
case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break; //获取E/W
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()
{
if (Save_Data.isParseData)
{
Save_Data.isParseData = false;
Serial_Printf("Save_Data.UTCTime = ");
Serial_Printf("%s:%s:%s",hours,minute,seconds);
Serial_Printf("\r\n");
if(Save_Data.isUsefull)
{
Save_Data.isUsefull = false;
Serial_Printf("latitude = ");
Serial_Printf("%lf",latitude_degrees);
Serial_Printf("\r\n");
Serial_Printf("Save_Data.N_S = ");
Serial_Printf(Save_Data.N_S);
Serial_Printf("\r\n");
Serial_Printf("Save_Data.longitude = ");
Serial_Printf("%lf",longitude_degrees);
Serial_Printf("\r\n");
Serial_Printf("Save_Data.E_W = ");
Serial_Printf(Save_Data.E_W);
Serial_Printf("\r\n");
}
else
{
Serial_Printf("GPS DATA is not usefull!\r\n");
}
}
}