BLE CC2541 DMA串口查询方式环形缓冲区的建立 与函数指针 回掉函数的使用

/*
CC2541 DMA串口查询方式环形缓冲区的建立  


GPS模块上电默认一秒钟发送以下数据 QQ群: 376066563
无效数据
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGLL,,,,,,V,N*64


或者有效数据
$GPRMC,034230.00,A,2231.36386,N,11402.87302,E,0.039,,310516,,,A*7E
$GPVTG,,T,,M,0.039,N,0.071,K,A*2F
$GPGGA,034230.00,2231.36386,N,11402.87302,E,1,05,1.66,19.4,M,-2.3,M,,*7C
$GPGSA,A,3,23,22,08,27,26,,,,,,,,2.64,1.66,2.05*0C
$GPGSV,2,1,07,03,13,240,11,08,42,201,32,21,07,068,,22,12,215,16*7E
$GPGSV,2,2,07,23,46,304,26,26,37,031,27,27,73,165,22*4A
$GPGLL,2231.36386,N,11402.87302,E,034230.00,A,A*6D


大量的数据需要缓存,确保每时每刻缓存的都是最新的数据,需用到环形缓冲区
rx.head 为存储数据指针。rx.hail为取数据指针,通过调用
void  set_uart_buf(uint16 (*read_len)(void) , uint16 (*read_buf)(uint8 *buf, uint16 len), frx_p *rx)  //取数据到环形缓冲区
函数可以将串口数据存入到  rx_buf[RX_BUF_MAX];  //二级缓冲区环形缓冲区中,
通过rx.hail可以取出来缓冲区中最新的数据


*/
//需要调用的系统函数
//uint16 NPI_RxBufLen(void);  //系统函数--读取系统缓冲区数据长度len
//uint16 NPI_ReadTransport(buf,len);  //系统函数--读取len个系统缓冲区数据到buf缓冲区
//static void UartReadCallback( uint8 port, uint8 events );  //系统回掉函数


#define RX_BUF_MAX                  (512)  //二级缓冲区--存储串口所有数据
#define RX_DAT_MAX                  (100)  //三级缓冲区--存储一组有效数据


typedef struct __frx_p
{
    uint16 head;  //头部
    uint16 hail;  //尾巴
    uint8 *dat;  //数据
    uint8 *buf;  //缓存
} frx_p;  //串口接收缓冲区


frx_p rx;  //声明二级缓冲区指针
uint8 rx_buf[RX_BUF_MAX];  //二级缓冲区
uint8 rx_dat[RX_DAT_MAX];  //三级缓冲区


void  set_uart_buf(uint16 (*read_len)(void) , uint16 (*read_buf)(uint8 *buf, uint16 len), frx_p *rx)  //取数据到环形缓冲区
{
    uint16 len = read_len();  //读取数据长度
    rx->buf = rx_buf;
    
    if(rx->head + len < RX_BUF_MAX)  //头指针未溢出
    {
        read_buf(&rx->buf[rx->head],len);  //更新二级缓存数据
        if((rx->head < rx->hail) && ((rx->head + len) >= rx->hail))  //头指针更新后将覆盖尾指针
        {
            rx->hail = rx->head + len + 1;  //更新尾指针到头指针不能覆盖的临界位置
            if(rx->hail >= RX_BUF_MAX) //尾指针溢出
            {
                rx->hail = 0;  //尾指针回到起始位置
            }
        }
        rx->head += len;  //更新头指针位置
    }
    else  //(rx->head + len >= RX_BUF_MAX)  //头指针溢出了
    {
        read_buf(&rx->buf[rx->head],RX_BUF_MAX - rx->head);  //更新二级缓存数据(缓存尾部)
        read_buf(&rx->buf[0],len - (RX_BUF_MAX - rx->head));  //更新二级缓存数据(超出尾部的数据)
        
        if(((rx->head < rx->hail) && ((rx->head + len) >= rx->hail)) || ((rx->head > rx->hail) && (len - (RX_BUF_MAX - rx->head) >= rx->hail)))  //头指针更新后将覆盖尾指针
        {
            rx->hail = len - (RX_BUF_MAX - rx->head) + 1;  //更新尾指针到头指针不能覆盖的临界位置
            if(rx->hail >= RX_BUF_MAX) //尾指针溢出
            {
                rx->hail = 0;  //尾指针回到起始位置
            }
        }
        rx->head = len - (RX_BUF_MAX - rx->head);  //更新头指针位置
    }
}






static void UartReadCallback( uint8 port, uint8 events )  //系统回掉函数
{ 
    (void)port;  //函数定义有变量,但是在调用的时候有可能其中一个没有传递值,编译器会报的错误。(void)port; 为了消除编译器报的错误。
    
    if (events & (HAL_UART_RX_TIMEOUT | HAL_UART_RX_FULL))  //查询方式接收数据,提取数据,判断数据完整性,处理数据。
    { 
        set_uart_buf(NPI_RxBufLen, NPI_ReadTransport, &rx);  //取数据到环形缓冲区
    } 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值