sgsong 发表于 2017-10-16 11:531 g' s' |2 i0 a( U
/** ' m: j- A/ ]. r3 g) E, Q * @brief Sends an amount of data in non blocking mode.8 ]$ M) A% T W; x; G
* @param huart: pointer to a UART_H ...
: b3 D1 B _) u4 f1 C发送状态 和 接收状态 变量是不一样的,发送繁忙不影响设置接收;上锁 设置好数据和大小后就 解锁了,上锁的目的就是避免设置 发送或接收 数据和大小的过程中重复设置(只有在中断函数中才可能打断上锁后的设置过程),一般情况是不会冲突的;一般通信过程,发送和接收时间上不会同时进行。6 v6 H& e) X8 o" c5 Q0 u- h9 Y N
楼主,初次接触,想请教DMA具体如何使用。& X: ^% y$ Y9 F ?/ K
采用HAL_UART_Transmit_DMA()时,是不是不需要再使能传输完成中断等寄存器操作?3 X# ~( N+ l$ x& ~+ t
一次串口传输完成,按照默认的中断处理过程,该串口的状态有恢复到初始状态吗?要不要在回调函数里进行一些配置?或者说,等到下次使用该函数,会自动设置好发送环境?& ~# N' f9 a: s. O4 ?
采用HAL_UART_Receive_DMA(),把它放在串口回调函数里,是不是就自动启动下一次接收?无需再进行相关寄存器操作。
可以参考官方例程。。。如串口DMA的回调函数和串口中断的回调函数是同一个
中断收、发API会自己打开和关闭中断,如果程序前期把串口中断一直打开了,这势必造成问题吧?
* @brief Sends an amount of data in non blocking mode.
* @param huart: pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData: Pointer to data buffer$ s$ g5 U- S4 G$ L2 @
* @param Size: Amount of data to be sent9 M" m+ z- k3 J4 [2 M
* @retval HAL status
*/ 串口中断发送,以中断方式发送指定长度的数据。
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Tx process is not already ongoing */
if(huart->gState == HAL_UART_STATE_READY) 如果 串口空闲,则执行以下语句。
{ v9 H9 T l1 B
if((pData == NULL ) || (Size == 0U)) 如果发送数据为空或者发送长度为0,则返回错误。4 E) `5 |5 M {8 E
{
return HAL_ERROR;4 Y: \8 j& }0 u* ]1 ~" ]& g
}' z4 k7 P+ A8 Z! W/ _' C4 Q
3 K: _! G3 f: ` w+ I, S
/* Process Locked */0 F7 {0 S, q# c3 s7 Q9 Y
__HAL_LOCK(huart); 上锁。
huart->pTxBuffPtr = pData; 结构体变量 huart 的 参数设置。发送缓冲区,发送长度,发送计数器。
huart->TxXferSize = Size;3 x& S1 f% y* [* W+ Q& p% [
huart->TxXferCount = Size;" _/ s4 d) J1 y, z
" G7 D3 ]8 `/ R: I* H3 S& X
huart->ErrorCode = HAL_UART_ERROR_NONE;% g ?4 \: A2 l
huart->gState = HAL_UART_STATE_BUSY_TX; 状态设为 发送繁忙。
4 k4 c k' N' Q- P- u
/* Process Unlocked */# C6 B9 k$ ?% K' W+ b" W
__HAL_UNLOCK(huart); 解锁。
( v- t* b7 g- _ u
/* Enable the UART Transmit data register empty Interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE); 使能UART发送数据寄存器空中断,则会触发串口中断(发送中断)。" v( N5 p% W/ T6 B
return HAL_OK;2 C; O0 t. o5 p7 v
}
else 如果 串口忙,则返回 忙状态。+ M( B% ^3 K( Q+ E
{* V( q0 P" _7 ]& ~/ v
return HAL_BUSY;
}
}
有个疑问,这个代码发送时,给整个串口上锁了(不是串口发送上锁),如果配置为全双工,这时中断接收数据怎么办?数据来时,串口一直处于忙的状态,数据量大时,数据会不会丢失?这种情况应该就不是全双工了。没找到同时收发数据的官方例程,都是一发一收的。
发送状态 和 接收状态 变量是不一样的,发送繁忙不影响设置接收;上锁 设置好数据和大小后就 解锁了,上锁的目的就是避免设置 发送或接收 数据和大小的过程中重复设置(只有在中断函数中才可能打断上锁后的设置过程),一般情况是不会冲突的;一般通信过程,发送和接收时间上不会同时进行。6 v6 H& e) X8 o" c5 Q0 u- h9 Y N
huart->TxXferCount = Size;--这一句不是huart->TxXferCount = Count;?
采用HAL_UART_Transmit_DMA()时,是不是不需要再使能传输完成中断等寄存器操作?3 X# ~( N+ l$ x& ~+ t
一次串口传输完成,按照默认的中断处理过程,该串口的状态有恢复到初始状态吗?要不要在回调函数里进行一些配置?或者说,等到下次使用该函数,会自动设置好发送环境?& ~# N' f9 a: s. O4 ?
采用HAL_UART_Receive_DMA(),把它放在串口回调函数里,是不是就自动启动下一次接收?无需再进行相关寄存器操作。
串口再怎么快页没单片机处理快吧,一般115200的速度够快了
但是用9600波特率就不会丢数据。
我准备改成DMA接收。
对这个HAL库,我是又爱又恨