AT6558R 驱动
数据手册这是官方文档如有需要在这里查看。
一. 简介
-
支持 BDS/GPS/GLONASS 多系统联合定位和单系统独立定位。
-
功耗:BDS/GPS 双模连续运行:23mA@3.3V。待机:8uA(@3.3V)。
-
技术参数

二. 关键参数
-
波特率默认9600bps
-
实时时钟(RTC)位于电池供电区域,并且配备有一块备份 RAM。使用独立的低功耗 LDO进行供电。RTC 在主电源供电消失的情况下能够正常工作,同时保证备份 RAM 中的数据不丢失。
-
包含两个独立的全双工 UART 模块,其中 UART0 默认输出 NMEA 格式定位数据,波特率最大支持 256000bps,并且具有自动波特率检测功能。
-
芯片有多种工作模式:全工作模式、休眠模式和电池备份模式。
-
全工作模式:所有电源正常供电,且 ON_OFF 管脚为高电平时,芯片处于全工作模式,进行正常的信号接收和解算。
-
休眠模式:所有电源正常供电,ON_OFF 管脚拉低,将关闭 DCDC 和内置 LDO,射频电路和基带电路停止工作,进入低功耗休眠状态。当 ON_OFF 管脚拉高后,芯片将自动恢复全工作模式(相当于热启动)。
-
电池备份模式:关闭除 VDD_BK 之外的所有电源,这时只需要极小的电流维持 RTC 时钟和备份 RAM 即可。电源恢复后,导航程序可以从备份 RAM 恢复,以实现快速的热启动。

-
-
通过 UART 发命令,可以将系统模式切换为 BDS/GPS/ GLONASS 的组合,比如 BDS+GPS双模,或者 GPS+GLONASS 双模,或者 GPS 单模等。
-
发送消息

-
设置更新频率

-
设置输出 NMEA 语句
后面设置的是只输出RMC语句(推荐的最少专用导航数据)

-
接收机重启

-
RMC 信息格式

三. 代码
1. usart
usart.c
static UART_HandleTypeDef *s_uartMap[] =
{
[UART_NUM_1] = &huart1,
[UART_NUM_2] = &huart2,
[UART_NUM_3] = &huart3,
};
/**
* @brief 串口发送数据
*
* @param uart_num 串口编号
* @param tx_data 发送的数据
* @param tx_data_len 发送的数据长度
*
* @retval 返回是否发送成功
*/
com_status_t uart_send_data(uint8_t uart_num,
const uint8_t* tx_data,
const uint16_t tx_data_len)
{
/* 检查参数 */
if (NULL == tx_data || 0 == tx_data_len)
{
return COM_ERROR;
}
if (UART_MAX_NUM <= uart_num || NULL == s_uartMap[uart_num])
{
return COM_ERROR;
}
/* 发送数据 */
if(HAL_OK == HAL_UART_Transmit(s_uartMap[uart_num],
tx_data,
tx_data_len,
1000))
{
return COM_OK;
}
else
{
return COM_ERROR;
}
}
/**
* @brief 串口接收数据
*
* @param uart_num 串口编号
* @param rx_buf 接收缓冲区
* @param rx_buf_len 接收缓冲区长度
* @param rx_data 接收数据长度
*
* @retval 返回是否接收成功
*/
com_status_t uart_recv_data(uint8_t uart_num,
uint8_t* rx_buf,
size_t rx_buf_len,
size_t* rx_data_len)
{
static uint16_t rx_buffer_len = 0;
/* 检查参数 */
if (NULL == rx_buf || NULL == rx_data_len)
{
return COM_ERROR;
}
if (UART_MAX_NUM <= uart_num || NULL == s_uartMap[uart_num])
{
return COM_ERROR;
}
/* AT6558R 接收数据 */
if(uart_num == UART_NUM_2)
{
HAL_UARTEx_ReceiveToIdle(s_uartMap[uart_num],
rx_buf,
rx_buf_len,
(uint16_t*)rx_data_len,
1000);
}
/* QS100 接收数据 */
if(uart_num == UART_NUM_3 && UART_RX_OK == uart_rx_flag)
{
uart_rx_flag = UART_RX_IDLE;
rx_buffer_len = rt_ringbuffer_data_len(&ringbuffer);
if(rx_buffer_len > 0)
{
rt_ringbuffer_get(&ringbuffer, rx_buf, rx_buffer_len);
*rx_data_len = rx_buffer_len;
// debug_println("uart_recv:%s, %d", rx_data, *rx_data_len);
// HAL_Delay(200);
return COM_OK;
}
}
return COM_TIMEOUT;
}
usart.h
typedef enum
{
UART_NUM_1 = 1, /* 串口1 */
UART_NUM_2 = 2, /* 串口2 */
UART_NUM_3 = 3, /* 串口3 */
UART_MAX_NUM /* 最大串口数量 */
} uart_num_t;
/**
* @brief 串口发送数据
*
* @param uart_num 串口编号
* @param tx_data 发送的数据
* @param tx_data_len 发送的数据长度
*
* @retval 返回是否发送成功
*/
com_status_t uart_send_data(uint8_t uart_num,
const uint8_t* tx_data,
const uint16_t tx_data_len);
/**
* @brief 串口接收数据
*
* @param uart_num 串口编号
* @param rx_buf 接收缓冲区
* @param rx_buf_len 接收缓冲区长度
* @param rx_data 接收数据长度
*
* @retval 返回是否接收成功
*/
com_status_t uart_recv_data(uint8_t uart_num,
uint8_t* rx_buf,
size_t rx_buf_len,
size_t* rx_data_len);
2. AT6558R
Int_AT6558R.c
#include "Int_AT6558R.h"
/**
* @brief AT6558R 发送消息
*
* @param cmd 命令类型
* @param params 参数指针
*
* @return 是否发送成功
*/
com_status_t Int_AT558R_send_msg(cas_cmd_t cmd,
const void* params)
{
uint8_t checksum = 0; /* 校验和 */
uint16_t len = 0;
uint8_t cmd_buf[256]; /* 命令缓冲区 */
uint8_t cmd_payload[128]; /* 命令载荷 */
memset(cmd_buf, 0, sizeof(cmd_buf));
memset(cmd_payload, 0, sizeof(cmd_payload));
/* 填充命令内容部分 */
switch (cmd)
{
case CAS00_SAVE_CONFIG:
{
/* $PCAS00*CS */
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"%s",
"PCAS00");
break;
}
case CAS01_SET_BAUDRATE:
{
/* $PCAS01,br*CS */
baudrate_t br = *(baudrate_t*)params;
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"PCAS01,%d",
br);
break;
}
case CAS02_SET_UPDATE_RATE:
{
/* $PCAS02,fixInt*CS */
uint16_t fix_int = *(uint16_t*)params;
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"PCAS02,%d",
fix_int);
break;
}
case CAS03_SET_NMEA_OUTPUT:
{
/* $PCAS03,nGGA,nGLL,...*CS */
const nmea_config_t* config = (nmea_config_t*)params;
len = snprintf((char*)cmd_payload, sizeof(cmd_payload),
"PCAS03,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,,,%d,%d,,,,%d",
config->nGGA, config->nGLL,
config->nGSA, config->nGSV,
config->nRMC, config->nVTG,
config->nZDA, config->nANT,
config->nDHV, config->nLPS,
config->nUTC, config->nGST, config->nTIM);
break;
}
case CAS04_SET_WORKING_SYSTEM:
{
/* $PCAS04,mode*CS */
system_mode_t mode = *(system_mode_t*)params;
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"PCAS04,%d",
mode);
break;
}
case CAS05_SET_NMEA_PROTOCOL:
{
/* $PCAS05,ver*CS */
nmea_version_t ver = *(nmea_version_t*)params;
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"PCAS05,%d",
ver);
break;
}
case CAS06_QUERY_PRODUCT_INFO:
{
/* $PCAS06,info*CS */
query_info_t info = *(query_info_t*)params;
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"PCAS06,%d",
info);
break;
}
case CAS10_SET_STARTUP_MODE:
{
/* $PCAS10,rs*CS */
startup_mode_t mode = *(startup_mode_t*)params;
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"PCAS10,%d",
mode);
break;
}
case CAS12_SET_STANDBY_MODE:
{
/* $PCAS12,stdbysec*CS */
uint16_t standby_sec = *(uint16_t*)params;
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"PCAS12,%d",
standby_sec);
break;
}
case CAS20_ONLINE_UPGRADE:
{
/* $PCAS20*CS */
len = snprintf((char*)cmd_payload,
sizeof(cmd_payload),
"%s",
"PCAS20");
break;
}
default:
return COM_ERROR;
}
/* 计算校验和 */
checksum = calculate_xor_checksum((const uint8_t*)cmd_payload, len);
/* 填充发送命令 */
len = snprintf((char*)cmd_buf,
sizeof(cmd_buf),
"$%s*%02X\r\n",
cmd_payload,
checksum);
debug_println("发送: %s", cmd_buf);
if(len > 0)
return uart_send_data(AT6558R_UART_NUM,
(const uint8_t*)cmd_buf,
len);
else
return COM_ERROR;
}
/**
* @brief AT6558R 接收消息
*
* @param rx_buf 接收缓冲区
* @param rx_buf_size 接收缓冲区大小
* @param rx_len 接收长度
*
* @return 是否接收成功
*/
com_status_t Int_AT558R_recv_msg(uint8_t* rx_buf,
size_t rx_buf_size,
size_t* rx_len)
{
if (NULL == rx_buf
|| 0 == rx_buf_size
|| NULL == rx_len)
return COM_ERROR;
uart_recv_data(AT6558R_UART_NUM,
rx_buf,
rx_buf_size,
rx_len);
debug_println("GPS: %s", rx_buf);
return COM_OK;
}
/**
* @brief 解析 RMC 数据
*
* @param rmc_info rmc 信息
* @param rmc_data RMC 数据结构体指针
*
* @return 是否接收成功
*/
com_status_t Int_AT6558R_parse_rmc(uint8_t* rmc_info,
rmc_data_t* rmc_data)
{
uint8_t checksum_len = 0; /* 校验和长度 */
uint8_t parsed_count = 0; /* 解析计数 */
if (NULL == rmc_info)
return COM_ERROR;
/* 解析定位数据 */
parsed_count = sscanf((const char*)rmc_info,
"%*[^,],%f,%c,%f,%c,%f,%c,%f,%f,%6s,,,%c,%c*%2hx",
&rmc_data->utc_time,
&rmc_data->status,
&rmc_data->latitude,
&rmc_data->lat_direction,
&rmc_data->longitude,
&rmc_data->lon_direction,
&rmc_data->speed,
&rmc_data->course,
(char*)rmc_data->date,
&rmc_data->mode_indicator,
&rmc_data->nav_status,
&rmc_data->checksum);
/* 检查解析结果 */
if (12 != parsed_count)
{
debug_println("解析定位数据失败: %d", parsed_count);
return COM_ERROR;
}
debug_println("rmc_data->utc_time: %f,\n "
"rmc_data->status: %c,\n "
"rmc_data->latitude: %f,\n "
"rmc_data->lat_direction: %c,\n "
"rmc_data->longitude: %f,\n "
"rmc_data->lon_direction: %c,\n "
"rmc_data->speed: %f,\n "
"rmc_data->course: %f,\n "
"rmc_data->date: %s,\n "
"rmc_data->mode_indicator: %c,\n "
"rmc_data->nav_status: %c,\n "
"rmc_data->checksum: %x\n",
rmc_data->utc_time,
rmc_data->status,
rmc_data->latitude,
rmc_data->lat_direction,
rmc_data->longitude,
rmc_data->lon_direction,
rmc_data->speed,
rmc_data->course,
rmc_data->date,
rmc_data->mode_indicator,
rmc_data->nav_status,
rmc_data->checksum);
/* 检查校验和 */
checksum_len = (uint8_t*)strstr((const char*)rmc_info, "*") - rmc_info - 1;
if (rmc_data->checksum != calculate_xor_checksum(&rmc_info[1], checksum_len))
{
debug_println("校验和错误");
return COM_ERROR;
}
debug_println("GPS 解析成功");
return COM_OK;
}
/**
* @brief 开启GPS模块
*
* @param 无
*
* @return 无
*/
void Int_AT6558R_enable(void)
{
GPS_EN_H;
Com_delay_s(3);
}
/**
* @brief 关闭GPS模块
*
* @param 无
*
* @return 无
*/
void Int_AT6558R_disable(void)
{
GPS_EN_L;
Com_delay_s(3);
}
/**
* @brief AT6558R 初始化
*
* @param 无
*
* @return 无
*/
void Int_AT6558R_Init(void)
{
uint8_t startup_mode = 0;
uint16_t update_rate = 0;
uint8_t system_mode = 0;
nmea_config_t config;
startup_mode = STARTUP_HOT;
update_rate = UPDATE_RATE_1HZ;
system_mode = SYSTEM_GPS_BDS;
config.nGGA = 0; /* GGA输出频率 */
config.nGLL = 0; /* GLL输出频率 */
config.nGSA = 0; /* GSA输出频率 */
config.nGSV = 0; /* GSV输出频率 */
config.nRMC = 1; /* RMC输出频率 */
config.nVTG = 0; /* VTG输出频率 */
config.nZDA = 0; /* ZDA输出频率 */
config.nANT = 0; /* ANT输出频率 */
config.nDHV = 0; /* DHV输出频率 */
config.nLPS = 0; /* LPS输出频率 */
config.nUTC = 0; /* UTC输出频率 */
config.nGST = 0; /* GST输出频率 */
config.nTIM = 0; /* TIM输出频率 */
/* 打开GPS模块 */
GPS_EN_H;
/* 热启动 */
Int_AT558R_send_msg(CAS10_SET_STARTUP_MODE, &startup_mode);
Com_delay_s(5);
/* 配置NMEA输出 */
Int_AT558R_send_msg(CAS03_SET_NMEA_OUTPUT, &config);
/* 设置更新频率 */
Int_AT558R_send_msg(CAS02_SET_UPDATE_RATE, &update_rate);
/* 配置工作模式 */
Int_AT558R_send_msg(CAS04_SET_WORKING_SYSTEM, &system_mode);
}
Int_AT6558R.h
#ifndef INT_AT6558R_H
#define INT_AT6558R_H
#include <stdio.h>
#include "stm32f1xx_hal.h"
#include "usart.h"
#include "gpio.h"
#include "Com_Debug.h"
#include "Com_tool.h"
#include "Com_config.h"
/* AT6558R 串口号 */
#define AT6558R_UART_NUM UART_NUM_2
/* CAS 命令枚举类型 */
typedef enum
{
CAS00_SAVE_CONFIG = 0, /* 保存配置到FLASH */
CAS01_SET_BAUDRATE, /* 设置串口波特率 */
CAS02_SET_UPDATE_RATE, /* 设置定位更新率 */
CAS03_SET_NMEA_OUTPUT, /* 设置NMEA语句输出 */
CAS04_SET_WORKING_SYSTEM, /* 设置工作卫星系统 */
CAS05_SET_NMEA_PROTOCOL, /* 设置NMEA协议版本 */
CAS06_QUERY_PRODUCT_INFO, /* 查询产品信息 */
CAS10_SET_STARTUP_MODE, /* 设置启动模式 */
CAS12_SET_STANDBY_MODE, /* 设置待机模式 */
CAS20_ONLINE_UPGRADE /* 在线升级指令 */
} cas_cmd_t;
/* 定位更新率枚举类型 */
typedef enum
{
UPDATE_RATE_1HZ = 1000, /* 每秒输出1个定位点,间隔1000ms */
UPDATE_RATE_2HZ = 500, /* 每秒输出2个定位点,间隔500ms */
UPDATE_RATE_4HZ = 250, /* 每秒输出4个定位点,间隔250ms */
UPDATE_RATE_5HZ = 200, /* 每秒输出5个定位点,间隔200ms */
UPDATE_RATE_10HZ = 100 /* 每秒输出10个定位点,间隔100ms */
} update_rate_t;
/* 串口波特率枚举类型 */
typedef enum
{
BAUDRATE_4800 = 0, /* 4800bps波特率 */
BAUDRATE_9600, /* 9600bps波特率 */
BAUDRATE_19200, /* 19200bps波特率 */
BAUDRATE_38400, /* 38400bps波特率 */
BAUDRATE_57600, /* 57600bps波特率 */
BAUDRATE_115200 /* 115200bps波特率 */
} baudrate_t;
/* CAS04工作系统配置枚举类型 */
typedef enum
{
SYSTEM_GPS = 1, /* 单GPS系统工作模式 */
SYSTEM_BDS = 2, /* 单北斗系统工作模式 */
SYSTEM_GPS_BDS = 3, /* GPS+北斗双模工作模式 */
SYSTEM_GLONASS = 4, /* 单GLONASS系统工作模式 */
SYSTEM_GPS_GLONASS = 5, /* GPS+GLONASS双模工作模式 */
SYSTEM_BDS_GLONASS = 6, /* 北斗+GLONASS双模工作模式 */
SYSTEM_GPS_BDS_GLONASS = 7 /* GPS+北斗+GLONASS三模工作模式 */
} system_mode_t;
/* CAS05 NMEA协议类型枚举 */
typedef enum
{
NMEA_VER_41_ABOVE = 2, /* NMEA 4.1及以上版本协议 */
NMEA_VER_TRANSPORT = 5, /* 交通运输部标准协议 */
NMEA_VER_GPS_ONLY = 9 /* 单GPS NMEA协议 */
} nmea_version_t;
/* CAS06查询信息类型枚举 */
typedef enum
{
QUERY_FIRMWARE_VERSION = 0, /* 查询固件版本信息 */
QUERY_HARDWARE_INFO = 1, /* 查询硬件信息 */
QUERY_WORKING_MODE = 2, /* 查询当前工作模式 */
QUERY_CUSTOMER_ID = 3, /* 查询客户编号 */
QUERY_UPGRADE_INFO = 5 /* 查询升级相关信息 */
} query_info_t;
/* CAS10启动模式枚举类型 */
typedef enum
{
STARTUP_HOT = 0, /* 热启动:保留所有数据,快速启动 */
STARTUP_WARM = 1, /* 温启动:清除星历数据 */
STARTUP_COLD = 2, /* 冷启动:清除除配置外的所有数据 */
STARTUP_FACTORY = 3 /* 出厂启动:清除所有数据,恢复出厂设置 */
} startup_mode_t;
/* CAS03 NMEA语句配置结构体 */
typedef struct
{
uint8_t nGGA; /* GGA输出频率 */
uint8_t nGLL; /* GLL输出频率 */
uint8_t nGSA; /* GSA输出频率 */
uint8_t nGSV; /* GSV输出频率 */
uint8_t nRMC; /* RMC输出频率 */
uint8_t nVTG; /* VTG输出频率 */
uint8_t nZDA; /* ZDA输出频率 */
uint8_t nANT; /* ANT输出频率 */
uint8_t nDHV; /* DHV输出频率 */
uint8_t nLPS; /* LPS输出频率 */
uint8_t res1; /* 保留 */
uint8_t res2; /* 保留 */
uint8_t nUTC; /* UTC输出频率 */
uint8_t nGST; /* GST输出频率 */
uint8_t res3; /* 保留 */
uint8_t res4; /* 保留 */
uint8_t res5; /* 保留 */
uint8_t nTIM; /* TIM输出频率 */
} nmea_config_t;
/* RMC数据 */
typedef struct
{
/* 时间和状态 */
float utc_time; /* UTC时间 */
uint8_t status; /* 位置有效标志:A=有效,V=无效 */
/* 经纬度信息 */
float latitude; /* 纬度 */
uint8_t lat_direction; /* 纬度方向 */
float longitude; /* 经度 */
uint8_t lon_direction; /* 经度方向 */
/* 导航信息 */
float speed; /* 对地速度 */
float course; /* 对地真航向 */
uint8_t date[7]; /* 日期 */
uint8_t mode_indicator; /* 定位模式标志 */
uint8_t nav_status; /* 导航状态标识符 */
/* 校验和 */
uint16_t checksum; /* 校验和 */
} rmc_data_t;
typedef enum
{
RMC_MODE_A = 'A', /* 自主定位 */
RMC_MODE_D = 'D', /* 差分定位 */
RMC_MODE_E = 'E', /* 估算模式 */
RMC_MODE_N = 'N', /* 数据无效 */
RMC_MODE_M = 'M' /* 未定位,但存在外部输入或历史保存的位置 */
} rmc_mode_t;
/**
* @brief AT6558R 初始化
*
* @param 无
*
* @return 无
*/
void Int_AT6558R_Init(void);
/**
* @brief 开启GPS模块
*
* @param 无
*
* @return 无
*/
void Int_AT6558R_enable(void);
/**
* @brief 关闭GPS模块
*
* @param 无
*
* @return 无
*/
void Int_AT6558R_disable(void);
/**
* @brief AT6558R 发送消息
*
* @param cmd 命令类型
* @param params 参数指针
*
* @return 是否发送成功
*/
com_status_t Int_AT558R_send_msg(cas_cmd_t cmd,
const void* params);
/**
* @brief AT6558R 接收消息
*
* @param rx_buf 接收缓冲区
* @param rx_buf_size 接收缓冲区大小
* @param rx_len 接收长度
*
* @return 是否接收成功
*/
com_status_t Int_AT558R_recv_msg(uint8_t* rx_buf,
size_t rx_buf_size,
size_t* rx_len) ;
/**
* @brief 解析 RMC 数据
*
* @param rmc_info rmc 信息
* @param rmc_data RMC 数据结构体指针
*
* @return 是否接收成功
*/
com_status_t Int_AT6558R_parse_rmc(uint8_t* rmc_info,
rmc_data_t* rmc_data);
#endif

浙公网安备 33010602011771号