STM32H743+ATGM332D调试记录

最近在做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')
    {
        gnss = bd;
    }
    else if (pData[1] == 'G' && pData[2] == 'P')
    {
        gnss = gp;
    }
    else if (pData[1] == 'G' && pData[2] == 'L')
    {
        gnss = gl;
    }
    else if (pData[1] == 'G' && pData[2] == 'N')
    {
        gnss = gn;
    }
    else
    {
        return;
    }
    if (pData[3] == 'G' && pData[4] == 'G' && pData[5] == 'A')
    {
        switch (gnss)
        {
        case bd:
            Gps_gga(pData, pDataLength, &gps2can.atgm332d.bd.gga);
            break;
        case gp:
            break;
        case gl:
            Gps_gga(pData, pDataLength, &gps2can.atgm332d.gl.gga);
            break;
        case gn:
            break;
        default:
            break;
        }
    }
    else if (pData[3] == 'G' && pData[4] == 'L' && pData[5] == 'L')
    {
    }
    else if (pData[3] == 'G' && pData[4] == 'S' && pData[5] == 'A')
    {
    }
    else if (pData[3] == 'G' && pData[4] == 'S' && pData[5] == 'V')
    {
    }
    else if (pData[3] == 'R' && pData[4] == 'M' && pData[5] == 'C')
    {
    }
    else if (pData[3] == 'V' && pData[4] == 'T' && pData[5] == 'G')
    {
    }
    else if (pData[3] == 'Z' && pData[4] == 'D' && pData[5] == 'A')
    {
    }
}

至于为什么这样处理,感兴趣的小伙伴可以去看一下对应的NEMA协议~

我这里只给出了GGA的处理,目前我只需要用到GGA语句解析:

unsigned char AsciiToHex(uint8_t *str, uint8_t size, uint8_t *result)
{
    unsigned char temp;

    for (*result = 0; size; size--, str++)
    {
        if (('9' >= *str) && (*str >= '0'))
            temp = *str - '0';
        else if (('F' >= *str) && (*str >= 'A'))
            temp = *str - 'A' + 10;
        else if (('f' >= *str) && (*str >= 'a'))
            temp = *str - 'a' + 10;
        else
            return 1;
        *result |= temp << ((size - 1) * 4);
    }

    return 0;
}

uint8_t MMEA_CheckSum(uint8_t *buf)
{
    unsigned char i;
    unsigned char chk, result;

    for (chk = buf[1], i = 2; (buf[i] != '*') && (i < 255); i++)
    {
        chk ^= buf[i];
    }

    if (AsciiToHex(&buf[i + 1], 2, &result))
        return 3;
    if (i >= 255)
        return 2;
    if (chk != result)
        return 1;

    return 0; // 校验成功
}

void Gps_gga(uint8_t pData[], uint16_t pDataLength, nema_gga *pGGA)
{
    // next must be ,
    uint8_t index = 6;
    uint8_t count = 0;
    uint8_t hex_data = 0;
    // count ,
    for (int i = 0; i < pDataLength; i++)
    {
        if (pData[i] == ',')
        {
            count++;
        }
    }

    if (count != 14)
    {
        return;
    }

    if (MMEA_CheckSum(pData) != 0)
    {
        return;
    }

    if (pData[index] != ',')
    {
        return;
    }
    index++;
    // utc_time
    if (pData[index] == ',')
    {
        pGGA->utc_time_flag = 0;
        index++;
    }
    else
    {
        pGGA->utc_time_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->utc_time = hex_data * 10000000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->utc_time += hex_data * 1000000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->utc_time += hex_data * 100000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->utc_time += hex_data * 10000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->utc_time += hex_data * 1000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->utc_time += hex_data * 100;
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // lat
    if (pData[index] == ',')
    {
        pGGA->lat_flag = 0;
        index++;
    }
    else
    {
        pGGA->lat_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat = hex_data * 10000000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat += hex_data * 1000000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat += hex_data * 100000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat += hex_data * 10000;
        index++;
        if (pData[index] == '.')
        {
            index++;
        }
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat += hex_data * 1000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat += hex_data * 100;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat += hex_data * 10;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lat += hex_data;
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // ulat
    if (pData[index] == ',')
    {
        pGGA->ulat_flag = 0;
        index++;
    }
    else
    {
        pGGA->ulat_flag = 1;
        if (pData[index] == 'N')
        {
            pGGA->ulat = 0;
        }
        else if (pData[index] == 'S')
        {
            pGGA->ulat = 1;
        }
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // lon
    if (pData[index] == ',')
    {
        pGGA->lon_flag = 0;
        index++;
    }
    else
    {
        pGGA->lon_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon = hex_data * 100000000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data * 10000000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data * 1000000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data * 100000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data * 10000;
        index++;
        if (pData[index] == '.')
        {
            index++;
        }
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data * 1000;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data * 100;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data * 10;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->lon += hex_data;
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // ulon
    if (pData[index] == ',')
    {
        pGGA->ulon_flag = 0;
        index++;
    }
    else
    {
        pGGA->ulon_flag = 1;
        if (pData[index] == 'E')
        {
            pGGA->ulon = 0;
        }
        else if (pData[index] == 'W')
        {
            pGGA->ulon = 1;
        }
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // FS
    if (pData[index] == ',')
    {
        pGGA->fs_flag = 0;
        index++;
    }
    else
    {
        pGGA->fs_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->fs = hex_data;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // numSv
    if (pData[index] == ',')
    {
        pGGA->numsv_flag = 0;
        index++;
    }
    else
    {
        pGGA->numsv_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->numsv = hex_data * 10;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->numsv += hex_data;
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // HDOP
    if (pData[index] == ',')
    {
        pGGA->hdop_flag = 0;
        index++;
    }
    else
    {
        pGGA->hdop_flag = 1;

        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->hdop = hex_data * 100;
        index++;
        if (pData[index] == '.')
        {
            index++;
        }
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->hdop += hex_data * 10;
        index++;
        if (pData[index] == '.')
        {
            index++;
        }
        if (pData[index] != ',')
        {
            AsciiToHex(&pData[index], 1, &hex_data);
            pGGA->hdop += hex_data;
            index++;
        }
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // msl
    if (pData[index] == ',')
    {
        pGGA->msl_flag = 0;
        index++;
    }
    else
    {
        pGGA->msl_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->msl = hex_data * 100;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->msl += hex_data * 10;
        index++;
        if (pData[index] == '.')
        {
            index++;
        }
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->msl += hex_data;
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // M
    if (pData[index] == ',')
    {
        pGGA->msl_flag = 0;
        index++;
    }
    else
    {
        if (pData[index] != 'M')
        {
            pGGA->msl_flag = 0;
        }
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // sep
    if (pData[index] == ',')
    {
        pGGA->sep_flag = 0;
        index++;
    }
    else
    {
        pGGA->sep_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->sep = hex_data * 100;
        index++;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->sep += hex_data * 10;
        index++;
        if (pData[index] == '.')
        {
            index++;
        }
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->sep += hex_data;
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // M
    if (pData[index] == ',')
    {
        pGGA->sep_flag = 0;
        index++;
    }
    else
    {
        if (pData[index] != 'M')
        {
            pGGA->sep_flag = 0;
        }
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // diffage
    if (pData[index] == ',')
    {
        pGGA->diffage_flag = 0;
        index++;
    }
    else
    {
        pGGA->diffage_flag = 1;
        AsciiToHex(&pData[index], 1, &hex_data);
        pGGA->diffage = hex_data;
        index++;
        while (pData[index] != ',')
        {
            index++;
        }
        index++;
    }
    // diffsta * cs
    if (pData[index] != '*')
    {
        // pGGA->diffsta_flag = 1;
        index++;
        while (pData[index] != '*')
        {
            index++;
        }
        index++;
    }
    else
    {
        // pGGA->diffage_flag = 0;
    }
}

我这边处理上是将多个字符合并成一个大数据来处理了,可以根据需要自行选用合适的处理方案~

希望能够帮到你。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值