20230731_XiaoFuZi_emb/ZheDaXiaoFuZi/Src/Usr/Driver/Ldrv/WH-GN100/McuWH-GN100Drv.c
Rjh913828050 a8560d741e 类型:重构
内容:重新整理项目文件分类
人员:任家豪
2023-10-08 16:10:23 +08:00

376 lines
12 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.

/********************************************************************
* Copyright (C), 2022, 中天海洋系统有限公司
* 文件名McuBspAdc.c
* 作者:任家豪(ZT-040157)
* 日期2022年5月16日
* 描述关于带FIFO的OV7670的驱动程序
* ******************************************************************/
#include "McuWH-GN100Drv.h"
#include "ZthyToolCheck.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* 延迟函数 */
#define WHGN100_DELAY(x) HAL_Delay(x)
#define WH_GN100_RBUF_LEN 100
#define RESPONSE_HEADER_STRING "$PGKC001" // 设置信息时,对方回应的应答消息的头
#define POSITION_HEADER_STRING "$GNRMC" // 定位信息的头
/* 关键信息ID */
#define RESTART_ID_STRING "030" // 重启的ID
#define OUT_FREQ_ID_STRING "101" // 输出频率ID
#define LOW_POWER_ID_STRING "105" // 低功耗ID
#define SET_GPS_BD_MODE_ID_STRING "115" // GPS或者北斗的工作模式ID
#define MESSAGE_EFFECTIVE_ENABLE 1 // 表示当前数据有效
#define MESSAGE_EFFECTIVE_DISABLE 0 // 表示当前数据无效
#define WHGN100_LON_AND_LAT_EFFECT 0
#define WHGN100_RESTART_ACK_EFFECT 1
#define WHGN100_OUT_FREQ_ACK_EFFECT 2
#define WHGN100_LOW_POWER_ACK_EFFECT 3
#define WHGN100_GPS_AND_BD_ACK_EFFECT 4
#define WHGN100_EFFECT_All 5
static void McuDrvWHGN100Write(uint8_t *buf, uint32_t BufLen);
static void McuDrvWHGN100Recv(uint8_t RecvData);
/* 处理接收的数据 */
static void McuDrvWHGN100RecvDataHandle(void);
/* WGS84坐标系 */
double gMcuDrvWHGN100Time;
int gMcuDrvWHGN100Time1;
double gMcuDrvWHGN100Lon; // 精度
double gMcuDrvWHGN100Lat; // 纬度
uint8_t gMcuDrvWHGN100LonEorW = MCU_DRV_WH_GN100_LON_E;
uint8_t gMcuDrvWHGN100LatNorS = MCU_DRV_WH_GN100_LAT_N;
uint8_t gMcuDrvWHGN100LonAndLatUpdata = 0;
/* 回应信息当前值 */
uint8_t gMcuDrvWHGN100RestartAck = 0;
uint8_t gMcuDrvWHGN100OutFreqAck = 0;
uint8_t gMcuDrvWHGN100LowPowerAck = 0;
uint8_t gMcuDrvWHGN100GpsAndBdAck = 0;
MCU_BSP_CLOCK gMcuDrvWHGN100GpsClock;
static uint8_t gWhgn100Rbuf[WH_GN100_RBUF_LEN] = {0}; // 确保能完成留下一帧数据
static uint16_t gWhgn100RbufLocal = 0;
/* 初始化函数 */
int McuDrvWHGN100Init(void)
{
MCU_BSP_UART_CONF UartConfig = {0};
UartConfig.BaudRate = MCU_DRV_WH_GN100_UART_BAUDRATE;
UartConfig.WordLength = MCU_DRV_WH_GN100_UART_WORDLEN;
UartConfig.StopBits = MCU_DRV_WH_GN100_UART_STOPBITS;
UartConfig.Parity = MCU_DRV_WH_GN100_UART_PARITY;
UartConfig.Mode = MCU_DRV_WH_GN100_UART_MODE;
if (McuBspUartInit(MCU_DRV_WH_GN100_UART_ID, &UartConfig, NULL, McuDrvWHGN100Recv) < 0) {
return -1;
}
McuBspUartStartRecv(MCU_DRV_WH_GN100_UART_ID);
McuBspGpioInit(MCU_DRV_WH_GN100_WAKEUP_GPIO_PORT, MCU_DRV_WH_GN100_WAKEUP_GPIO_PIN,
MCU_DRV_WH_GN100_WAKEUP_GPIO_MODE, MCU_DRV_WH_GN100_WAKEUP_GPIO_SPEED,
MCU_DRV_WH_GN100_WAKEUP_GPIO_PULL, 0, NULL);
McuBspGpioInit(MCU_DRV_WH_GN100_POWER_GPIO_PORT, MCU_DRV_WH_GN100_POWER_GPIO_PIN,
MCU_DRV_WH_GN100_POWER_GPIO_MODE, MCU_DRV_WH_GN100_POWER_GPIO_SPEED,
MCU_DRV_WH_GN100_POWER_GPIO_PULL, 0, NULL);
McuDrvWHGN100LowPower(MCU_DRV_WH_GN100_LOW_POWER_FLAG);
gWhgn100RbufLocal = 0;
return 0;
}
/* 获取经纬度数据 */
int McuDrvWHGN100GetLatAndLon(float *Lat, unsigned char *LatFlag, float *Lon, unsigned char *LonFlag, MCU_BSP_CLOCK *Clock)
{
uint16_t i = 0;
gMcuDrvWHGN100LonAndLatUpdata = 0;
McuDrvWHGN100LowPower(MCU_DRV_WH_GN100_WAKEUP_FLAG);
while (gMcuDrvWHGN100LonAndLatUpdata == 0) {
WHGN100_DELAY(20); // 延迟ms
if (i >= 6000) {
McuDrvWHGN100LowPower(MCU_DRV_WH_GN100_LOW_POWER_FLAG);
return -1; //设置失败
}
i++;
}
McuDrvWHGN100LowPower(MCU_DRV_WH_GN100_LOW_POWER_FLAG);
*Lat = gMcuDrvWHGN100Lat;
*LatFlag = gMcuDrvWHGN100LatNorS;
*Lon = gMcuDrvWHGN100Lon;
*LonFlag = gMcuDrvWHGN100LonEorW;
Clock->Year = gMcuDrvWHGN100GpsClock.Year;
Clock->Month = gMcuDrvWHGN100GpsClock.Month;
Clock->Date = gMcuDrvWHGN100GpsClock.Date;
Clock->Hours = gMcuDrvWHGN100GpsClock.Hours;
Clock->Minutes = gMcuDrvWHGN100GpsClock.Minutes;
Clock->Seconds = gMcuDrvWHGN100GpsClock.Seconds;
return 0;
}
/* 配置NMEA输出频率 freq单位为ms范围为200-10000 */
int McuDrvWHGN100NMEAOutfreq(uint16_t freq)
{
char tbuf[50] = {0};
unsigned char Xor = 0;
unsigned char i = 0;
sprintf(tbuf, "$PGKC101,%d", freq);
i = strlen(tbuf);
ZthyToolCheckXor((unsigned char *)(tbuf + 1), i, &Xor);
sprintf(&tbuf[i], "*%02x\r\n", Xor);
i = 0;
gMcuDrvWHGN100OutFreqAck = 0;
McuDrvWHGN100Write((uint8_t *)tbuf, strlen(tbuf));
/* 等待是否收到消息回复 */
while (gMcuDrvWHGN100OutFreqAck == 0) {
WHGN100_DELAY(10); // 延迟ms
if (i >= 100) {
return -1; //设置失败
}
i++;
}
return 0;
}
/* 设置重启指令 */
int McuDrvWHGN100NMEASetRestart(uint8_t type)
{
char tbuf[50] = {0};
unsigned char Xor = 0;
unsigned char i = 0;
if (type != MCU_DRV_WH_GN100_RESTART_TYPE_HOT &&
type != MCU_DRV_WH_GN100_RESTART_TYPE_WARM &&
type != MCU_DRV_WH_GN100_RESTART_TYPE_COLD) {
return -1;
}
sprintf(tbuf, "$PGKC030,%d,1", type);
i = strlen(tbuf);
ZthyToolCheckXor((unsigned char *)(tbuf + 1), i, &Xor);
sprintf(&tbuf[i], "*%02x\r\n", Xor);
i = 0;
gMcuDrvWHGN100RestartAck = 0;
McuDrvWHGN100Write((uint8_t *)tbuf, strlen(tbuf));
/* 等待是否收到消息回复 */
while (gMcuDrvWHGN100RestartAck == 0) {
WHGN100_DELAY(10); // 延迟ms
if (i >= 100) {
return -1; //设置失败
}
i++;
}
return 0;
}
/* 设置定位模式 */
int McuDrvWHGN100NMEASetPositioningMode(uint8_t mode)
{
char tbuf[50] = {0};
unsigned char Xor = 0;
unsigned char i = 0;
sprintf(tbuf, "$PGKC115,%d,%d,%d,%d", (mode & MCU_DRV_WH_GN100_POSITION_GPS),
(mode & MCU_DRV_WH_GN100_POSITION_GNSS) >> 1,
(mode & MCU_DRV_WH_GN100_POSITION_BD) >> 2,
(mode & MCU_DRV_WH_GN100_POSITION_Gli) >> 3);
i = strlen(tbuf);
ZthyToolCheckXor((unsigned char *)(tbuf + 1), i, &Xor);
sprintf(&tbuf[i], "*%02x\r\n", Xor);
i = 0;
gMcuDrvWHGN100GpsAndBdAck = 0;
McuDrvWHGN100Write((uint8_t *)tbuf, strlen(tbuf));
/* 等待是否收到消息回复 */
while (gMcuDrvWHGN100GpsAndBdAck == 0) {
WHGN100_DELAY(10); // 延迟ms
if (i >= 100) {
return -1; //设置失败
}
i++;
}
return 0;
}
/* 进入或者唤醒低功耗 */
void McuDrvWHGN100LowPower(uint8_t flag)
{
if (flag == MCU_DRV_WH_GN100_WAKEUP_FLAG) {
McuBspGpioSetLevel(MCU_DRV_WH_GN100_WAKEUP_GPIO_PORT,
MCU_DRV_WH_GN100_WAKEUP_GPIO_PIN,
MCU_BSP_GPIO_OUT_HIGH);
McuBspGpioSetLevel(MCU_DRV_WH_GN100_POWER_GPIO_PORT,
MCU_DRV_WH_GN100_POWER_GPIO_PIN,
MCU_BSP_GPIO_OUT_HIGH);
} else {
McuBspGpioSetLevel(MCU_DRV_WH_GN100_POWER_GPIO_PORT,
MCU_DRV_WH_GN100_POWER_GPIO_PIN,
MCU_BSP_GPIO_OUT_LOW);
McuBspGpioSetLevel(MCU_DRV_WH_GN100_WAKEUP_GPIO_PORT,
MCU_DRV_WH_GN100_WAKEUP_GPIO_PIN,
MCU_BSP_GPIO_OUT_LOW);
}
}
/* 发送数据给定位模块 */
static void McuDrvWHGN100Write(uint8_t *buf, uint32_t BufLen)
{
McuBspUartSend(MCU_DRV_WH_GN100_UART_ID, buf, BufLen);
}
/* 处理接收的数据 */
static void McuDrvWHGN100RecvDataHandle(void)
{
char *p = NULL;
char *q = NULL;
/* 判断这一帧数据中是否存在GNRMC */
if (NULL != strstr((const char *)gWhgn100Rbuf, POSITION_HEADER_STRING)) {
/* 找到内容中的第二个逗号与第三个逗号之间的值 */
p = strchr((const char *)gWhgn100Rbuf, ','); // 第一个逗号
if (p == NULL) {
return;
}
p++;
q = strchr((const char *)p, ','); // 第二个逗号
if (q == NULL) {
return;
}
*q = 0;
if (strlen(p) == 0) {
return;
}
gMcuDrvWHGN100Time = atof(p);
gMcuDrvWHGN100GpsClock.Hours = ((uint32_t)gMcuDrvWHGN100Time) / 10000;
gMcuDrvWHGN100GpsClock.Minutes = (((uint32_t)gMcuDrvWHGN100Time) / 100) % 100;
gMcuDrvWHGN100GpsClock.Seconds = ((uint32_t)gMcuDrvWHGN100Time) % 100;
q++;
p = strchr((const char *)q, ','); // 第三个逗号
if (p == NULL) {
return;
}
*p = 0;
if (strlen(q) == 0 || *q != 'A') { // 判断数据是否为空或者定位是否已经处于差分定位
return;
}
p++;
q = strchr((const char *)p, ','); //找到纬度值所在位置
if (q == NULL) {
return;
}
*q = 0;
if (strlen(p) == 0) { // 判断数据是否为空
return;
}
gMcuDrvWHGN100Lat = atof(p); // 将纬度值赋值给接收变量
q++;
p = strchr((const char *)q, ','); // 找到北纬南纬
if (p == NULL) {
return;
}
*p = 0;
if (strlen(q) == 0) { // 判断数据是否为空
return;
}
if (*q == 'N') {
gMcuDrvWHGN100LatNorS = MCU_DRV_WH_GN100_LAT_N;
} else {
gMcuDrvWHGN100LatNorS = MCU_DRV_WH_GN100_LAT_S;
}
p++;
q = strchr((const char *)p, ','); //找到经度值所在位置
if (q == NULL) {
return;
}
*q = 0;
if (strlen(p) == 0) { // 判断数据是否为空
return;
}
gMcuDrvWHGN100Lon = atof(p); // 将经度值赋值给接收变量
q++;
p = strchr((const char *)q, ','); // 找到东经西经
if (p == NULL) {
return;
}
*p = 0;
if (strlen(q) == 0) { // 判断数据是否为空
return;
}
if (*q == 'E') {
gMcuDrvWHGN100LonEorW = MCU_DRV_WH_GN100_LON_E;
} else {
gMcuDrvWHGN100LonEorW = MCU_DRV_WH_GN100_LON_W;
}
p++;
q = strchr((const char *)p, ',');
if (q == NULL) {
return;
}
q++;
p = strchr((const char *)q, ',');
if (p == NULL) {
return;
}
p++;
q = strchr((const char *)p, ',');
if (q == NULL) {
return;
}
*q = 0;
if (strlen(p) == 0) {
return;
}
gMcuDrvWHGN100Time1 = atoi(p);
gMcuDrvWHGN100GpsClock.Date = gMcuDrvWHGN100Time1 / 10000;
gMcuDrvWHGN100GpsClock.Month = (gMcuDrvWHGN100Time1 / 100) %100;
gMcuDrvWHGN100GpsClock.Year = 2000 + (gMcuDrvWHGN100Time1 % 100);
gMcuDrvWHGN100LonAndLatUpdata = 1;
} else if (NULL != strstr((const char *)gWhgn100Rbuf, RESPONSE_HEADER_STRING)) {
/* 判断这一帧数据中是否存在 */
p = strchr((const char *)gWhgn100Rbuf, ','); // 第一个逗号
if (p == NULL) {
return ;
}
p++;
q = strchr((const char *)p, ','); // 第二个逗号
if (q == NULL) {
return ;
}
*q = 0;
if (NULL != strstr((const char *)p, RESTART_ID_STRING)) {
q++;
if (*q == '3') {
gMcuDrvWHGN100RestartAck = 1;
}
} else if (NULL != strstr((const char *)p, OUT_FREQ_ID_STRING)) {
q++;
if (*q == '3') {
gMcuDrvWHGN100OutFreqAck = 1;
}
} else if (NULL != strstr((const char *)p, LOW_POWER_ID_STRING)) {
q++;
if (*q == '3') {
gMcuDrvWHGN100LowPowerAck = 1;
}
} else if (NULL != strstr((const char *)p, SET_GPS_BD_MODE_ID_STRING)) {
q++;
if (*q == '3') {
gMcuDrvWHGN100GpsAndBdAck = 1;
}
}
}
}
static void McuDrvWHGN100Recv(uint8_t RecvData)
{
gWhgn100Rbuf[gWhgn100RbufLocal] = RecvData;
gWhgn100RbufLocal++;
if (RecvData == '\n') {
gWhgn100Rbuf[gWhgn100RbufLocal] = 0; // 给最后一帧
McuDrvWHGN100RecvDataHandle();
gWhgn100RbufLocal = 0;
}
// 取余,容错处理,防止串口数据乱流导致部分逻辑错误
gWhgn100RbufLocal = gWhgn100RbufLocal % WH_GN100_RBUF_LEN;
}