最近在做GPS相关的功能,主控芯片使用的是STM32H7系列的,遂做个记录留念~
CUBEMX配置底层驱动
ST芯片驱动用cuber来配置还是相当方便的,这里就简单配置一下UART,因为ATGM芯片是通过串口来通讯的,就是简单的配置了一下串口:
首先配置RCC:
根据需要配置一下时钟树,这里就不多做赘述~
这里简单选个异步通讯,其他全默认即可,然后我们生成工程。
串口接收队列
为了方便解析GPS数据,我这边写了一个队列来处理这个问题:
#define MAX_SIZE 10000
typedef struct
{
uint8_t data[MAX_SIZE];
int front, rear;
} Queue;
void initQueue(Queue *q)
{
q->front = 0;
q->rear = 0;
}
int isFull(Queue *q)
{
return (q->rear + 1) % MAX_SIZE == q->front;
}
int isEmpty(Queue *q)
{
return q->front == q->rear;
}
int queueSize(Queue *q)
{
return (q->rear - q->front + MAX_SIZE) % MAX_SIZE;
}
void enqueue(Queue *q, uint8_t item)
{
if (!isFull(q))
{
q->data[q->rear] = item;
q->rear = (q->rear + 1) % MAX_SIZE;
}
else
{
// todo :: if full
}
};
uint8_t dequeue(Queue *q)
{
uint8_t item = q->data[q->front];
q->front = (q->front + 1) % MAX_SIZE;
return item;
}
uint8_t getLastValidData(Queue *q)
{
int size = queueSize(q);
if (size == 0)
{
return 0;
}
else
{
return q->data[(q->rear - 1 + MAX_SIZE) % MAX_SIZE];
}
}
uint8_t getDataAtPosition(Queue *q, int position)
{
int size = queueSize(q);
if (size == 0 || position >= size || position < 0)
{
return 0;
}
else
{
return q->data[(q->front + position) % MAX_SIZE];
}
}
随后在回调函数中接收数据:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
// SCB_InvalidateDCache_by_Addr((uint32_t *)uart_rxdata, 128);
for (int i = 0; i < 200; i++)
{
enqueue(&gps2can_q, uart_rxdata[i]);
}
HAL_UART_Receive_DMA(&huart1, uart_rxdata, 200);
}
}
在主循环中处理数据:
void Gps_Poll(Queue *q)
{
uint8_t data[300] = {0};
uint16_t size = 0;
// judge empty
if (isEmpty(q))
{
return;
}
// get datalength
size = queueSize(q);
if (size < 3)
{
return;
}
// judge front
if (0x24 != dequeue(q))
{
return;
}
else
{
data[0] = 0x24;
}
// judge rear
for (int i = 1; i < size; i++)
{
if (getDataAtPosition(q, i) == 0x0A)
{
for (int j = 1; j <= (i + 1); j++)
{
data[j] = dequeue(q);
}
Gps_process(data, (i + 2));
return;
}
}
}
void Gps_process(uint8_t pData[], uint16_t pDataLength)
{
uint8_t gnss = 0;
if (pData[0] != '$')
{
return;
}
if (pData[1] == 'B' && pData[2] == 'D')
{