zstack 串口使用指南
它到底有什么意义。 cfg->rxHead = cfg->rxTail = 0; 在打开串口中有这么赋值,把它初始化为 0. 其实从上面那个中断函数就已经把这个参数的功能体现的淋漓尽致了: 就是串口接收数据,这个参数始终指向像一个参数被存放到 rxBuf 的位置。因为硬件串口缓 存器 U0DBUF 只能存放一个字节,如果不及时把这个接收到的转移出去,那么就会被下一个到 来的字节覆盖掉,所以 rxHead 变量就指向了这个存放的地址,当然是基于定义的 rxBuf 存储 空间。相当于一个数组赋值,那么必然有个变量会指向该数组的下一个赋值的参数,当然这 个变量的最终值也能在一定程度上体现这个被赋值数组的大小。所以 rxHead 在这里起到了类 似的作用,而 if ( cfg0->rxHead == cfg0->rxMax )这一句判断也说明的很清楚,一旦这个 计数达到了定义的最大接收数量,也就是说已经把 rxBuf 存储空间占满了,那么就不能在继 续存放了,否则存放的位置就未知,而且有可能造成程序中其他变量的损坏,那么这个时候 如果串口还有数据怎么办?那就需要把 rxBuf 清空在接收了,否则就会丢失数据。 3、uint8 rxTail; 这个变量就与上面提到的清空 rxBuf 密切相关了。 while ( (cfg->rxTail != cfg->rxHead) && (cnt < len) ) {
}
/* It is necessary to stop Rx flow in advance of a full Rx buffer because
* bytes can keep coming while sending H/W fifo flushes.
*/
if ( cfg->rxCnt >= (cfg->rxMax - SAFE_RX_MIN) )
还是藏的很隐蔽就是了,呵呵!!!!关于这个 128 我是做个实验的,在串口互发的实验也是定
义的 128.多了就会丢掉!这个下次有机会在说。
5、uint8 rxCnt ;
static void pollISR( uartCfg_t *cfg )
{
uint8 cnt = UART_RX_AVAIL( cfg );
cfg0->rxHead = 0; } else {
cfg0->rxHead++; } } 这个是串口 0 中断函数:其中 cfg0->rxBuf[cfg0->rxHead] = U0DBUF,显然是把 U0DBUF 中 的数据转移到存储区去。 从这个函数中还能看出两个问题: rxHead 是否用作了串口接收计数,而 rxMax 代表最大的接收数据长度。 2、uint8 rxHead 字面理解为接收头,但是上面已经提到了似乎起到了串口接收计数的功能。那下面就来看看
走的数据。首先从字面理解 avail 为“效用”的意思,那么扩展下为 available,那么意思
就是“有用的”“有空的”,呵呵!只有理解其实也很有意思哈。
再从后面的判断语句,cfg->rxHead - cfg->rxTail,由于有上面的讲解,理解这个就很容易 了,有的数据数量-已经取走的数据数量,那么就省还有多少各有用的数据量。 而 cfg->rxMax - cfg->rxTail + cfg->rxHead +1 理解就需要转个弯了,因为此时 cfg->rxHead > cfg->rxTail,那么什么情况下才满足这种条件呢,只有一种情况,rxHead 已经是第二轮 接收计数了,而 rxTail 还在上一轮取数。cfg->rxMax - cfg->rxTail,也就是第一轮把 rxBuf 填满的数据取走 cfg->rxTail,那么就是第一轮剩下又有的数据,那么在+ cfg->rxHead 这个, 就 是 加 上 cfg->rxHead 第 二 轮 接 收 的 数 据 , 至 于 后 面 +1 的 理 解 为 cfg->rxBuf = osal_mem_alloc( cfg->rxMax+1) , 分 配 存 储 空 间 本 来 就 比 rxMax 多 分 了 一 个 。 ------------------------------这里我仍然有疑惑,谁有深刻的理解欢迎交流! 而 if ( cfg->rxCnt >= (cfg->rxMax - SAFE_RX_MIN) )这里理解就更微妙了,表明接收缓 存空间已经满了,所以下面就 RX_STOP_FLOW( cfg ); #define RX_STOP_FLOW( cfg ) { \ if ( !(cfg->flag & UART_CFG_U1F) ) \ {\
{
RX_STOP_FLOW( cfg );
ቤተ መጻሕፍቲ ባይዱ
}
}
}
就这个函数使用这个参数最典型了。
关心的第一句不 if ( cfg->rxCnt != cnt )一开始就与 cnt 变量有关系,而且更加过分的是
在里面直接 cfg->rxCnt = cnt,所以不得不关系下 cnt 了。
uint8 cnt = UART_RX_AVAIL( cfg );这个函数的第一句,而:
if ( !(cfg->flag & UART_CFG_RXF) )
{
// If anything received, reset the Rx idle timer.
if ( cfg->rxCnt != cnt )
{
cfg->rxTick = HAL_UART_RX_IDLE;
cfg->rxCnt = cnt;
zstack 串口使用指南.txt 如果不懂就说出来,如果懂了,就笑笑别说出来。贪婪是最真实 的贫穷,满足是最真实的财富。幽默就是一个人想哭的时候还有笑的兴致。转载 zstack 串 口使用指南 2009-05-04 02:00Z-STACK 问题之串口结构 uartCfg_t 乱说
typedef struct { uint8 *rxBuf;//接收缓存 uint8 rxHead;//头 uint8 rxTail;//尾 uint8 rxMax;//接收最大长度 uint8 rxCnt;//计数 uint8 rxTick;//时间 uint8 rxHigh;//高位 uint8 *txBuf; #if HAL_UART_BIG_TX_BUF uint16 txHead; uint16 txTail; uint16 txMax; uint16 txCnt; #else uint8 txHead; uint8 txTail; uint8 txMax; uint8 txCnt; #endif uint8 txTick; uint8 flag;//标志位 halUARTCBack_t rxCB; } uartCfg_t; 有个朋友问我上面的问题,说句老实话,我可是第一次见这个东东,拿到手之后比我那朋友 还迷糊,那位朋友至少还知道大概是什么功能,仅仅是不清楚每个参数的具体含义和功能。 为了解决这个问题,我可是遍寻名家,最终结果是人家也不是很清楚,因为平常大家只管用, 哪管那么多这些具体细节?没办法,我只有自己解决了,希望我的努力能给大家一点点启示! 首先说说这个结构的应用范畴,它是直接面向串口的应用层,也就是与客户接触的还是比较 紧密的一个结构,一般是在串口接收数据和发送数据的时候使用。而串口有两种方式,一种 是普通的串口,一种是 DMA 方式。这里我只针对普通串口来分析这个结构。 首先来看看这个结构在什么地方用到了? static void pollDMA( uartCfg_t *cfg ) static void pollISR( uartCfg_t *cfg ) 这两个函数直接就用到了这个结构作为参数,应该说是联系最紧密的了,是我们重点剖析的 对象了,但是这里不看 DMA,因为这个俺很外行----------哈哈!!!! uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len ) uint8 HalUARTOpen( uint8 port, halUARTCfg_t *config )
*buf++ = cfg->rxBuf[cfg->rxTail]; if ( cfg->rxTail == cfg->rxMax ) {
cfg->rxTail = 0; } else {
cfg->rxTail++; } cnt++; } 这里是在 uint16 HalUARTRead( uint8 port, uint8 *buf, uint16 len )函数中调用的,实 际上把 rxBuf 空间的数据读走,然后 rxBuf 可以继续串口数据的接收了。可以看到*buf++ = cfg->rxBuf[cfg->rxTail]这个是在转移数据,而转移多少的计数是以 rxTail 来计数的。一 旦计数达到 rxMax,那么该计数归 0,因为 rxMax 定义了 rxBuf 的最大的数据量。 这里需要强调一点:rxTail 和 rxHead 的区别。 我第一眼看到这个两个变量的反应是:rxHead 为串口数据串接收的头,而 rxTail 为串口数 据串接收的尾(结束),因为这样理解符合我们平常编写串口通信协议习惯,有头有尾。但是 仔细看了只有,虽然也是头与尾的概念,但是却不应该这么理解。 rxTail 和 rxHead 应该是针对 rxBuf 来说的。rxHead 是往 rxBuf 装数据的计数,而 rxTail 是从 rxBuf 取走数据的计数。希望这个一定要注意。所以我们就不难理解:rxHead 是在串口 接收中断的时候强调使用,而 rxTail 是在 HalUARTRead 函数中使用了。这里还需要注意一点 点,HalUARTRead 并不是读取 UxBUF 数据,而是读取 rxBuf 中数据。 其实仔细想想,这两个参数还是与串口的头和尾有关的。头又名开始,串口接收数据开始存 放数据的指向;尾又名结束,是把串口数据取走用作他用的指向。rxHead=0,标示串口接收 数据新的起点,新的开始;而 rxTail=0,标示把串口接收到的数据全部取走用作他用,-----结束。体现了串口数据从接收到被使用的整个过程。