教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 文库大全 > 求职职场 >

协议中UART的两种模式

来源:网络收集 时间:2026-08-15
导读: UART 协议栈中UART有两种模式: 1、中断 2、DMA 对于这两种模式具体运用在哪一步,纠结了很久.通过UART配置结构: typedef struct { uint8 *rxBuf; uint8 rxHead; uint8 rxTail; uint8 rxMax; uint8 rxCnt; uint8 rxTick; uint8 rxHigh; uint8 *txBuf; #if HAL_

UART

协议栈中UART有两种模式:

1、中断

2、DMA

对于这两种模式具体运用在哪一步,纠结了很久.通过UART配置结构: 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;

可以看到协议栈为串口收发分别配置了一块内存空间rxBuf和txBuf,具体在HalUARTOpen()里配置. 而中断与DMA这两种模式具体就运用于

的过程. 串口接收DMA模式:(data) —> U0DBUF —(DMA)—> rxBuf —> HalUARTRead()读取rxBuf数据进行处理 串口接收中断模式:(data) —> U0DBUF —(中断)—> rxBuf —> HalUARTRead()读取rxBuf数据进行处理

串口发送DMA模式:(data) <— U0DBUF <—(DMA)— txBuf

串口发送中断模式:(data) <— U0DBUF <—(中断)— txBuf

我觉得这样理解好像还有问题,本身对DMA不了解,网上又几乎查不到关于协议栈有关UART_DMA模式具体 流程资料,卡在这里很久,所以打算建立个大概印象就跳出来,以后再看.

先记录下中断模式吧~

########################################################################### ###########################################################################

1、中断模式(UART接收)

当1写入UxCSR.RE位时,在UART上数据接收就开始了.然后UART会在输入引脚RXDx中寻找有效起始位,并且设置UxCSR.ACTIVE位为1.当检测出有效起始位时,收到的字节就传入接收寄存器,UxCSR.RX_BUTE位

UART

设置为1.该操作完成时,产生接收中断。通过寄存器UxBUF提供收到的数据字节。当UxBUF读出时,UxCSR.RX_BUTE位由硬件清零.当产生中断时,自然进入中断程序,看下UART0接收中断函数: *************************************** #if HAL_UART_0_ENABLE HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR ) {

cfg0->rxBuf[cfg0->rxHead] = U0DBUF; if ( cfg0->rxHead == cfg0->rxMax ) { cfg0->rxHead = 0; } else { cfg0->rxHead++; } }

#endif

/**************************************

中断函数完成了把U0DBUF里一字节的数据传送到rxBuf[ ]存储空间去.这里rxHead是指向rxBuf[ ]的指针,看单词像是指在数组的头,其实应理解为rxBuf[ ]接收数据的个数(以字节为单位).rxMax是rxBuf[ ]可以存储最大字节数,为128.而后面当用HalUARTRead()来读取rxBuf[ ]时,rxTail应理解为rxBuf[]转移出去数据的个数(同样以字节为单位).那数据传送到rxBuf[ ]存储空间去后呢?先看下pollISR() *****************************************************************************/

//大概每200ms调用pollISR()函数.当串口UxDBUF接收到一字节数据产生中断,在中断

//程序中把UxDBUF中数据传送到rxbuf[ ]中(这有个坎要跨过来,pollISR()200ms才被调用一次,而不是每次中断后都调用一次,如果串口接收的是大的数据包,则200ms内rxbuf[ ]已经接收了约48字节(这个后面分析),中断了48次??.当然如果串口没有接收到数据,也就是说没有发生串口接收中断,cfg应为是为空的,则cnt=0).此后pollISR()进行轮询,主要是重置超时时间和计算rxbuf[ ]还有多少数据没有读走(即cnt).然后再跳回到HalUARTPoll()函数进行下一步处理. static void pollISR( uartCfg_t *cfg ) {

uint8 cnt = UART_RX_AVAIL( cfg ); //计算rxBuf[]中还有多少数据没有读出(以字节为单位) if ( !(cfg->flag & UART_CFG_RXF) ) //UART_CFG_RXF:Rx flow is disabled.rx流控制未关闭 { // If anything received, reset the Rx idle timer.

//如果又有新的数据接收到,则重置超时时间 if ( cfg->rxCnt != cnt ) { cfg->rxTick = HAL_UART_RX_IDLE; cfg->rxCnt = cnt;

} /* 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.

*/

UART

//当接收数据超过安全界限的时候,通过硬件流控制停止接收数据 if ( cfg->rxCnt >= (cfg->rxMax - SAFE_RX_MIN) ) { RX_STOP_FLOW( cfg ); } } }

#endif /******************************************************************************

pollISR()函数主要就是设置rxTick和rxCnt,发生接收中断并且接收中断函数处理完后,这些参数都会改变.

pollISR()执行完成后就跳回到HalUARTPoll()中.

看下 HalUARTPoll() /************************************** void HalUARTPoll( void ) { #if ( HAL_UART_0_ENABLE | HAL_UART_1_ENABLE ) static uint8 tickShdw; uartCfg_t *cfg;

uint8 tick;

//---------以下设置cfg #if HAL_UART_0_ENABLE

if ( cfg0 ) //当串口接收到数据时,在中断函数或DMA程序中会改变cfg0值,如果没有接收到数据,cfg0

为空. { cfg = cfg0; } #endif

//--------- #if HAL_UART_1_ENABLE if ( cfg1 ) {

cfg = cfg1;//同上 } #endif

//--------- // Use the LSB of the sleep timer (ST0 must be read first anyway).

//睡眠定时器.ST0为睡眠定时器计数值的低8位 tick = ST0 - tickShdw;

tickShdw = ST0; do

{

UART

//------------------------发送超时时间 if ( cfg->txTick > tick ) { cfg->txTick -= tick; } else { cfg->txTick = 0; }

//------------------------接收超时时间 if ( cfg->rxTick > tick ) { cfg->rxTick -= tick; } else { cfg->rxTick = 0; }

//------------------------ #if HAL_UART_ISR #if HAL_UART_DMA if ( cfg->flag & UART_CFG_DMA ) {

pollDMA( cfg ); //pollDMA( cfg ) } else #endif {

pollISR( cfg ); //pollISR( cfg ) } #elif HAL_UART_DMA pollDMA( cfg );

#endif

/* The following logic makes continuous callbacks on any eligible flag(合法标志) * until the condition corresponding to the flag is rectified. * So even if new data is not received, continuous callbacks are made. */

if ( cfg->rxHead != cfg->rxTail ) //初始化时rxHead=rxTail=0,不相等,rxbuf[ ]中有数据 {

uint8 evt; if ( cfg->rxHead >= (cfg->rxMax - SAFE_RX_MIN) ) {

evt = HAL_UART_RX_FULL; //rxBuf接收[ ]满,则触发事件

}

UART

else if ( cfg->rxHigh && (cfg->rxHead >= cfg->rxHigh) ) {

evt = HAL_UART_RX_ABOUT_FULL; //rxBuf[ ]接收到预设值(默认80字节),则触发事件 } else if ( cfg->rxTick == 0 ) {

evt = HAL_UART_RX_TIMEOUT; //RX接收事件超时,则触发事件 } else { evt = 0;

}

if ( evt && cfg->rxCB ) //有事件并且有回调函数 {

…… 此处隐藏:20125字,全部文档内容请下载后查看。喜欢就下载吧 ……
协议中UART的两种模式.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wenku/1702682.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)