/*
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); //取数据到环形缓冲区
}
}
BLE CC2541 DMA串口查询方式环形缓冲区的建立 与函数指针 回掉函数的使用
最新推荐文章于 2022-09-13 10:40:33 发布