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

来源:互联网 发布:为什么还原网络设置 编辑:程序博客网 时间:2024/05/17 09:08
/*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);  //取数据到环形缓冲区    } }

1 0
原创粉丝点击