协议中UART的两种模式
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字,全部文档内容请下载后查看。喜欢就下载吧 ……相关推荐:
- [求职职场]加法运算定律的运用练习题
- [求职职场]大型石油化工工业过程节能新技术
- [求职职场]2015-2020年中国箱纸板行业分析与投资
- [求职职场]NADEX-IWC5A点焊机故障代码
- [求职职场]英语阅读 非常有用
- [求职职场]鲁卫疾控发〔2012〕2号(联合,印发山东
- [求职职场]2014年莆田公务员行测技巧:数字推理的
- [求职职场]基于最近发展区理论的高中数学课堂有效
- [求职职场]与贸易有关的知识产权协议
- [求职职场]【王风范】微演说·职场演说三
- [求职职场]新时代国珍健康大课堂
- [求职职场]群论期末考试复习题
- [求职职场]施工现场消防安全专项施工方案(范本)-
- [求职职场]初中物理光学知识点归纳完美版
- [求职职场]毕业设计总结与体会范文
- [求职职场]江南大学2018年上半年展示设计第1阶段
- [求职职场]景尚乡民兵参战支前保障方案
- [求职职场]【优质】2019年工会职工之家建设工作总
- [求职职场]数据库技术与应用—SQL Server 2008(第
- [求职职场]汽车变速箱构造与工作原理
- 首钢工业区工业遗产资源保护与再利用研
- 第4课 《大学》节选
- 2016程序文件——检验检测结果发布程序
- 2011年高考试题文言文阅读全解释__2011
- 化学是一门基础的自然科学
- 海外做市商制度的借鉴意义
- 外国建筑史复习资料(
- 七年级下思想品德期末综合测试(二)
- 思政课部2013年上学期教学工作总结
- 电大国际公法任务3 0004
- 《圆的认识》教学设计
- 中国轨道交通牵引变流器行业市场发展调
- 中泰证券#定期报告:坚守时代硬科技和
- 浅论企业财务管理与企业经营投资风险的
- 大功率半导体激光器光纤耦合技术调研报
- 中国传统家具的现状与发展探讨
- Broadcom数字电视芯片助海尔扩展高清电
- 新HSK4词汇练习 超全(五)
- 2013届高考数学单元考点复习12
- 雨霖铃精品课件




