Files
GPS-Navigator-/ETH/UdpServer/User/interface_uart.c
2025-09-05 21:09:02 +08:00

654 lines
22 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.

/*
* eth_drive.c
*
* Created on: 2023年1月5日
* Author: Administrator
*/
#include "interface_uart.h"
#include "interface_config.h"
#include <string.h>
#include <ctype.h>
Timer nmea_timer;
static RingBuffer nmea_rx_buf;
#define DMA_BUF_SIZE 1400
uint8_t dma_rx_buffer[DMA_BUF_SIZE] __attribute__((aligned(4)));
//__attribute__((aligned(4))) uint8_t dma_buffer[2048]; // GCC语法
//void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART8_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA2_Channel3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA1_Channel3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA2_Channel9_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn USART3_IRQHandler
*
* @brief This function handles USART3 global interrupt request.
*
* @return none
*/
uint8_t state = 0;
uint8_t char_data[100] = {0};
unsigned char UART3_RX_cnt = 0;
void USART3_IRQHandler(void)
{
//----------------------------------------------------------
enter_critical_section();
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)
{
imu_buffer1.buf_len = IMU_LEN - DMA_GetCurrDataCounter(IMU_RX_CH);
if( (imu_buffer1.dma_buffer[imu_buffer1.active_buf][0] == IMU_IIM46234_HEADER1) && //适配两个传感器
(imu_buffer1.dma_buffer[imu_buffer1.active_buf][1] == IMU_IIM46234_HEADER2) )
{
imu_buffer1.type = IIM46234;
publishMessage(&imu_buffer1, 1);
}
else if( (imu_buffer1.dma_buffer[imu_buffer1.active_buf][0] == IMU_YIS321_HEADER1) &&
(imu_buffer1.dma_buffer[imu_buffer1.active_buf][1] == IMU_YIS321_HEADER2) )
{
imu_buffer1.type = YIS321;
publishMessage(&imu_buffer1, 1);
}
else{}
imu_buffer1.active_buf ^= 1;
DMA_Cmd(IMU_RX_CH, DISABLE);
DMA_SetCurrDataCounter(IMU_RX_CH, IMU_LEN);
// Switch buffer
IMU_RX_CH->MADDR = (uint32_t)(uintptr_t)&(imu_buffer1.dma_buffer[imu_buffer1.active_buf][0]);
DMA_Cmd(IMU_RX_CH, ENABLE);
USART_ReceiveData(USART3); // clear IDLE flag
}
exit_critical_section(0);
}
void UART4_IRQHandler(void)
{
enter_critical_section();
if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET)
{
RTCM_Buffer1.buf_len = RX_BUFFER_LEN - DMA_GetCurrDataCounter(RTCM_RX_CH);
RTCM_Buffer1.active_buf ^= 1;
DMA_Cmd(RTCM_RX_CH, DISABLE);
DMA_SetCurrDataCounter(RTCM_RX_CH, RX_BUFFER_LEN);
// Switch buffer
RTCM_RX_CH->MADDR = (uint32_t)(uintptr_t)&(RTCM_Buffer1.dma_buffer[RTCM_Buffer1.active_buf][0]);
DMA_Cmd(RTCM_RX_CH, ENABLE);
printf("rtcm receive\n");
USART_ReceiveData(UART4); // clear IDLE flag
publishMessage(&RTCM_Buffer1, 1);
}
exit_critical_section(0);
}
void UART8_IRQHandler(void)
{
enter_critical_section();
if(USART_GetITStatus(UART8, USART_IT_RXNE) != RESET)
{
uint8_t UART_temp = 0;
UART_temp = USART_ReceiveData(UART8);
// printf("USART8:%d\n", UART_temp); // 数据
}
exit_critical_section(0);
}
void UART6_IRQHandler(void)
{
enter_critical_section();
if(USART_GetITStatus(UART6, USART_IT_RXNE) != RESET)
{
char ch = USART_ReceiveData(UART6);
}
exit_critical_section(0);
}
void UART7_IRQHandler(void)
{
enter_critical_section();
if(USART_GetITStatus(UART7, USART_IT_IDLE) != RESET)
{
DMA_Cmd(UM982_RX_CH, DISABLE);
uint16_t received_len = DMA_BUF_SIZE - DMA_GetCurrDataCounter(UM982_RX_CH);
// 3. 将数据拷贝到环形缓冲区
for(uint16_t i = 0; i < received_len; i++)
{
uint16_t next_head = (nmea_rx_buf.head + 1) % RING_BUF_SIZE;
if(next_head != nmea_rx_buf.tail)
{
nmea_rx_buf.buffer[nmea_rx_buf.head] = dma_rx_buffer[i];
nmea_rx_buf.head = next_head;
}
else
{
nmea_rx_buf.overflow = 1;
}
}
DMA_SetCurrDataCounter(UM982_RX_CH, DMA_BUF_SIZE);
DMA_Cmd(UM982_RX_CH, ENABLE);
USART_ReceiveData(UART7); // clear IDLE flag
}
exit_critical_section(0);
}
/*********************************************************************
* @fn DMA1_Channel5_IRQHandler
*
* @brief This function handles DMA1 Channel 5 global interrupt request.
*
* @return none
*/
void DMA1_Channel3_IRQHandler(void)
{
enter_critical_section();
imu_buffer1.buf_len = RX_BUFFER_LEN;
DMA_ClearITPendingBit(DMA1_IT_TC3);//清零中断
exit_critical_section(0);
}
/*********************************************************************
* @fn DMA2_Channel3_IRQHandler
*
* @brief This function handles DMA1 Channel 5 global interrupt request.
*
* @return none
*/
void DMA2_Channel3_IRQHandler(void)
{
enter_critical_section();
RTCM_Buffer1.buf_len = RX_BUFFER_LEN;
DMA_ClearITPendingBit(DMA2_IT_TC3);//清零中断
exit_critical_section(0);
}
/*********************************************************************
* @fn DMA2_Channel3_IRQHandler
*
* @brief This function handles DMA1 Channel 5 global interrupt request.
*
* @return none
*/
void DMA2_Channel9_IRQHandler(void)
{
enter_critical_section();
DMA_ClearITPendingBit(DMA2_IT_TC9);//清零中断
exit_critical_section(0);
}
/*********************************************************************
* @fn DMA_INIT
*
* @brief Configures the DMA for USART1.
*
* @return none
*/
void dmaInit(void)
{
DMA_InitTypeDef DMA_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2|RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(RTCM_RX_CH);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&RTCM_UART->DATAR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(uintptr_t)&(RTCM_Buffer1.dma_buffer[0][0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = RX_BUFFER_LEN;
DMA_Init(RTCM_RX_CH, &DMA_InitStructure);
DMA_ITConfig(RTCM_RX_CH, DMA_IT_TC, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = RTCM_RX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Cmd(RTCM_RX_CH, ENABLE);
USART_DMACmd(RTCM_UART, USART_DMAReq_Rx, ENABLE);
//IMU DMA接收
DMA_DeInit(IMU_RX_CH);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&IMU_UART->DATAR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(uintptr_t)&(imu_buffer1.dma_buffer[0][0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = IMU_LEN;
DMA_Init(IMU_RX_CH, &DMA_InitStructure);
DMA_ITConfig(IMU_RX_CH, DMA_IT_TC, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = IMU_RX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Cmd(IMU_RX_CH, ENABLE);
USART_DMACmd(IMU_UART, USART_DMAReq_Rx, ENABLE);
//982 DMA接收
DMA_DeInit(UM982_RX_CH);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&UM982_UART->DATAR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(uintptr_t)(dma_rx_buffer);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = DMA_BUF_SIZE;
DMA_Init(UM982_RX_CH, &DMA_InitStructure);
DMA_ITConfig(UM982_RX_CH, DMA_IT_TC, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = UM982_RX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Cmd(UM982_RX_CH, ENABLE);
USART_DMACmd(UM982_UART, USART_DMAReq_Rx, ENABLE);
}
void initUart(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStructure1 = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
//----------------------------------------------------------------------------
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3 | RCC_APB1Periph_UART4 | RCC_APB1Periph_UART6 | RCC_APB1Periph_UART7 | RCC_APB1Periph_UART8, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
/* USART3 TX-->D.8 RX-->D.9 */
GPIO_PinRemapConfig( GPIO_FullRemap_USART3, ENABLE);//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
USART_InitStructure1.USART_BaudRate = 921600;
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
USART_InitStructure1.USART_Parity = USART_Parity_No;
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART3, &USART_InitStructure1);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART3, ENABLE);
/* USART4 TX-->B.0 RX-->B.1 */
GPIO_PinRemapConfig( GPIO_PartialRemap_USART4, ENABLE);//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure1.USART_BaudRate = 115200;
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
USART_InitStructure1.USART_Parity = USART_Parity_No;
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(UART4, &USART_InitStructure1);
USART_ITConfig(UART4, USART_IT_IDLE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(UART4, ENABLE);
/* UART6 TX-->C.0 RX-->C.1 */ //接的982的com1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
USART_InitStructure1.USART_BaudRate = 115200;
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
USART_InitStructure1.USART_Parity = USART_Parity_No;
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(UART6, &USART_InitStructure1);
USART_ITConfig(UART6, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = UART6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(UART6, ENABLE);
/* UART7 TX-->C.2 RX-->C.3 *///接的982的com2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
USART_InitStructure1.USART_BaudRate = 115200;
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
USART_InitStructure1.USART_Parity = USART_Parity_No;
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(UART7, &USART_InitStructure1);
USART_ITConfig(UART7, USART_IT_IDLE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = UART7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(UART7, ENABLE);
/* UART8 TX-->C.4 RX-->C.5 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
USART_InitStructure1.USART_BaudRate = 115200;
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
USART_InitStructure1.USART_Parity = USART_Parity_No;
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(UART8, &USART_InitStructure1);
USART_Cmd(UART8, ENABLE);
dmaInit();
}
void uartSendto(USART_TypeDef *USARTx, uint8_t * ucData, uint16_t len)//串口2发送函数
{
for(uint16_t i = 0; i<len; i++)
{
USART_SendData(USARTx,ucData[i]);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET) /* waiting for sending finish */
{
}
}
}
void rtcmProcess(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
uartSendto(UART6, (uint8_t *)&(RTCM_Buffer1.dma_buffer[RTCM_Buffer1.active_buf^1][0]), RTCM_Buffer1.buf_len);//直接发送非激活内存
printf("rtcm forwarding\n");
}
void setDataProcess(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
uartSendto(USART3, set_output_data, 20);
}
void setRateProcess(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
uartSendto(USART3, set_rate, 20);
}
void setSaveProcess(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
uartSendto(USART3, save_cmd, 20);
}
void setSteamProcess(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
uartSendto(USART3, stream_cmd, 20);
}
/* /?**?
* @brief 计算NMEA语句的校验和XOR异或校验
* @param nmea_str 完整的NMEA语句包含$和*但不含结尾的CRLF
* @return 计算出的8位校验和0x00~0xFF
*/
uint8_t nmea_checksum(const char *nmea_str)
{
uint8_t checksum = 0;
// 跳过起始符'$'(如果存在)
if (*nmea_str == '$') nmea_str++;
// 逐字符异或,直到遇到'*'或字符串结束
while (*nmea_str && *nmea_str != '*') {
checksum ^= (uint8_t)*nmea_str++;
}
return checksum;
}
/*
* @brief 验证NMEA语句的校验和
* @param nmea_str 完整的NMEA语句如"$GPGGA,...*2A\r\n"
* @return 校验成功返回1失败返回0
*/
bool nmea_validate_checksum(const char *nmea_str)
{
const char *p = nmea_str;
uint8_t computed_cs, received_cs;
// 查找校验和起始位置'*'
while (*p && *p != '*') p++;
if (*p != '*') return 0; // 无校验和字段
// 提取接收到的校验和2位十六进制
if (!isxdigit(p[1]) || !isxdigit(p[2])) return 0;
received_cs = (uint8_t)strtol(p+1, NULL, 16);
// 计算实际校验和
computed_cs = nmea_checksum(nmea_str);
return (computed_cs == received_cs);
}
void ProcessNMEAFrames(void *signal_id)
{
static uint8_t parsing_buf[1024];
static uint16_t parse_idx = 0;
bool frame_complete = false;
static uint8_t debug1s_cnt = 0;
debug1s_cnt ++;
if(debug1s_cnt >= 20)
{
debug1s_cnt = 0;
printf("nmea_buf tail:%d head:%d\n",
nmea_rx_buf.tail, nmea_rx_buf.head);
}
while(nmea_rx_buf.tail != nmea_rx_buf.head && !frame_complete)
{ // 缓冲区非空且未完成一帧解析
uint8_t ch = nmea_rx_buf.buffer[nmea_rx_buf.tail];
nmea_rx_buf.tail = (nmea_rx_buf.tail + 1) % RING_BUF_SIZE;
if(nmea_rx_buf.overflow) {
nmea_rx_buf.tail = nmea_rx_buf.head;
// 3. 重置溢出标志
nmea_rx_buf.overflow = 0;
// 4. 触发错误恢复流程(如重发请求)
printf("Overflow recovery\n");
}
// 帧头检测
if(ch == '$') {
if(parse_idx > 0 && parsing_buf[parse_idx-1] == '\n')
{
if (nmea_validate_checksum((char *)parsing_buf)) //校验代码
{
memcpy(&nema_output1.buffer[0],parsing_buf,parse_idx);
publishMessage(&nema_output1, 1);
frame_complete = true; // 标记帧处理完成
}
else
{
printf("nmea crc error");
frame_complete = true; // 标记帧处理完成
}
}
parse_idx = 0;
}
// 存储数据
if(parse_idx < RING_BUF_SIZE-1 && !frame_complete)
{
parsing_buf[parse_idx++] = ch;
// 帧尾检测
if(parse_idx >= 2 &&
parsing_buf[parse_idx-2] == '\r' &&
parsing_buf[parse_idx-1] == '\n')
{
if (nmea_validate_checksum((char *)parsing_buf)) //校验代码
{
memcpy(&nema_output1.buffer[0],parsing_buf,parse_idx);
publishMessage(&nema_output1, 1);
frame_complete = true; // 标记帧处理完成
}
else
{
printf("nmea buf error");
frame_complete = true; // 标记帧处理完成
}
parse_idx = 0;
}
}
else if(!frame_complete)
{
parse_idx = 0; // 防止溢出
}
}
timerStart(&nmea_timer, 50, 1); // 100ms后再次触发
}
void navigationRs232Process(void *signal_id)
{
uartSendto(UART8, (uint8_t *)&navigation_rs232_output, sizeof(navigation_rs232_output));
}
// APP模块的初始化
void interfaceUartInit(void)
{
subscribe(&set_output_data, setDataProcess);
subscribe(&set_rate, setRateProcess);
subscribe(&save_cmd, setSaveProcess);
subscribe(&stream_cmd, setSteamProcess);
subscribe(&RTCM_Buffer1, rtcmProcess);
subscribe(&nmea_timer, ProcessNMEAFrames);
subscribe(&navigation_rs232_output, navigationRs232Process);
timerStart(&nmea_timer, 50,1);//50ms
printf("interface uart: initial OK %d\n",getCurrentTime());
}