Files
ManGoWalk_STM32/fun/gps.c

194 lines
4.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "gps.h"
/**
提示: 虽然 BLE 以及 GPS都是DMA+ UART接收但是它们都有所不同
BLE --- DMA + IDLE 中断 循环 DMA + 空闲中断触发处理 UART IDLE
GPS --- DMA +固定长度 + TC中断 设置固定长度 DMA DMA传输完成中断
**/
//外部引入
extern UART_HandleTypeDef huart2;
extern DMA_HandleTypeDef handle_GPDMA1_Channel3;
//全局数据变量定义
uint8_t GPS_DMA_RX_BUF[GPS_DMA_RX_BUF_LEN]; //用于DMA接收缓冲
_GPSData GPS;
// TEST 是进行逻辑测试时候的代码else之后的是加入到Thread X的实际控制代码
#ifdef TEST
//void GPS_DMA_Start(void)
//{
// HAL_UART_Receive_DMA(&huart2,GPS_DMA_RX_BUF,GPS_DMA_RX_BUF_LEN);
// __HAL_DMA_ENABLE_IT(huart2.hdmarx,DMA_IT_HT); //半传输中断
// __HAL_DMA_ENABLE_IT(huart2.hdmarx,DMA_IT_TC); //全传输中断
//}
void GPS_Init(void)
{
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, GPS_DMA_RX_BUF, GPS_DMA_RX_BUF_LEN);
__HAL_DMA_DISABLE_IT(&handle_GPDMA1_Channel3, DMA_IT_HT); // 禁用半传输
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance == USART2)
{
// 根据 Size 拷贝接收到的数据
memcpy(GPS.GPS_Buffer,GPS_DMA_RX_BUF,Size);
GPS.GPS_Buffer[Size] = '\0';
GPS.isGetData = 1; //数据接收标志位置为1
//重新开启接收
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,GPS_DMA_RX_BUF,GPS_DMA_RX_BUF_LEN);
__HAL_DMA_DISABLE_IT(&handle_GPDMA1_Channel3,DMA_IT_HT);
}
}
// 串口数据清除
void GPS_Data_CLR(void)
{
memset(GPS_DMA_RX_BUF,0,GPS_DMA_RX_BUF_LEN);
}
#ifdef parse
// GPS数据解析
void parseGpsBuffer()
{
char *subString;
char *subStringNext;
char i = 0;
if(GPS.isGetData)
{
GPS.isGetData = 0; // 把标志位置为1
char usefullBuffer[2] = {0};
for(i = 0; i <= 6; i++)
{
if(i == 0)
{
subString = strstr(GPS.GPS_Buffer,",");
if(!subString)return;
}
else
{
subString++;
subStringNext = strstr(subString,",");
if(!subStringNext)return;
switch(i)
{
case 1:
memcpy(GPS.UTCTime,subString,subStringNext - subString);
break;
case 2:
memcpy(usefullBuffer,subString,subStringNext - subString);
break;
case 3:
memcpy(GPS.latitude,subString,subStringNext - subString);
break;
case 4:
memcpy(GPS.N_S,subString,subStringNext - subString);
break;
case 5:
memcpy(GPS.longitude,subString,subStringNext - subString);
break;
case 6:
memcpy(GPS.E_W,subString,subStringNext - subString);
break;
default:break;
}
subString = subStringNext;
}
}
GPS.isParseData = 1;
GPS.isUsefull = (usefullBuffer[0] == 'A') ? 1 : 0;
}
}
#else // 这里是对于改进后的parse 解析 两个都需要进行测试
void parseGpsBuffer()
{
char *fields[7];
char *token;
int fieldIndex = 0;
if (GPS.isGetData)
{
GPS.isGetData = 0; // 把标志位置为0
token = strtok(GPS.GPS_Buffer, ",");
while (token != NULL && fieldIndex < 7)
{
fields[fieldIndex++] = token;
token = strtok(NULL, ",");
}
if (fieldIndex == 7)
{
memcpy(GPS.UTCTime, fields[1], sizeof(GPS.UTCTime) - 1);
GPS.UTCTime[sizeof(GPS.UTCTime) - 1] = '\0';
memcpy(GPS.latitude, fields[3], sizeof(GPS.latitude) - 1);
GPS.latitude[sizeof(GPS.latitude) - 1] = '\0';
memcpy(GPS.N_S, fields[4], sizeof(GPS.N_S) - 1);
GPS.N_S[sizeof(GPS.N_S) - 1] = '\0';
memcpy(GPS.longitude, fields[5], sizeof(GPS.longitude) - 1);
GPS.longitude[sizeof(GPS.longitude) - 1] = '\0';
memcpy(GPS.E_W, fields[6], sizeof(GPS.E_W) - 1);
GPS.E_W[sizeof(GPS.E_W) - 1] = '\0';
GPS.isParseData = 1;
GPS.isUsefull = (fields[2][0] == 'A') ? 1 : 0;
}
}
}
/*
改进点总结
使用 strtok 进行分隔:
更加简洁地分割字符串。
数组存储字段:
使用数组存储每个字段的指针,减少重复代码。
边界检查:
确保字段数量足够,避免数组越界。
字符串截断:
确保复制的字符串以 null 结尾,避免潜在的字符串处理问题。
*/
#endif
// 转换角度
double Convert_to_degrees(char *data)
{
double temp = atof(data);
int deg = (int)(temp / 100);
double min = temp - deg * 100;
return deg + (min / 60.0);
}
#else // 这部分是留给后续的 Thread X
#endif