串口初始化
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1; //USART1
huart1.Init.BaudRate = 115200; //波特率
huart1.Init.WordLength = UART_WORDLENGTH_8B; //数据位
huart1.Init.StopBits = UART_STOPBITS_1; //停止位
huart1.Init.Parity = UART_PARITY_NONE; //校验位
huart1.Init.Mode = UART_MODE_TX_RX; //收发模式
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; //无硬件控制
huart1.Init.OverSampling = UART_OVERSAMPLING_16; //过采样设置,8倍或者16倍
if (HAL_UART_Init(&huart1) != HAL_OK) //
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
{
/* The hardware flow control is available only for USART1, USART2 and USART3 */
/* assert_param 的定义
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
表示参数expr为false,则执行后面的assert_failed()函数,__FILE__, __LINE__是标准库函数中的宏定义,表示文件名和行号;
如果参数exp为TRUE,则执行((void)0),什么都不做
*/
assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
/*
如果IS_UART_HWFLOW_INSTANCE(huart->Instance)是true,则什么都不做,
表示IS_UART_HWFLOW_INSTANCE(huart->Instance)为false,则执行后面的assert_failed()函数,
*/
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
}
else
{
assert_param(IS_UART_INSTANCE(huart->Instance));
}
/*
如果有硬件控制,则检查 HARDWARE_FLOW_CONTROL 和 IS_UART_HWFLOW_INSTANCE
#define IS_UART_HWFLOW_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2) || \
((INSTANCE) == USART3))
无则检查IS_UART_INSTANCE
#define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2) || \
((INSTANCE) == USART3) || \
((INSTANCE) == UART4) || \
((INSTANCE) == UART5))
*/
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); //检查数据位
/*
#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B) || \
((LENGTH) == UART_WORDLENGTH_9B))
*/
#if defined(USART_CR1_OVER8)
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
#endif /* USART_CR1_OVER8 */
if (huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
//如果串口刚被复位,则锁住串口,并初始化
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) //如果使用寄存器回调
UART_InitCallbacksToDefault(huart);
if (huart->MspInitCallback == NULL)
{
huart->MspInitCallback = HAL_UART_MspInit;
}
/* Init the low level hardware */
huart->MspInitCallback(huart);
#else
/* Init the low level hardware : GPIO, CLOCK */ //否则调用 HAL_UART_MspInit,初始化GPIO和时钟
HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}
huart->gState = HAL_UART_STATE_BUSY; //把串口状态设置为忙
/* Disable the peripheral */
__HAL_UART_DISABLE(huart); // 停用串口
/* Set the UART Communication parameters */
UART_SetConfig(huart); //真正设置串口寄存器的波特率,停止位等
/* In asynchronous mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
/*
在异步模式下,必须清除以下位::
CR2 寄存器中的 LINEN 和 CLKEN 位
LINEN: LIN模式使能 (LIN mode enable)
该位由软件设置或清除。
0:禁止LIN模式;
1:使能LIN模式。
在LIN模式下,可以用USART_CR1寄存器中的SBK位发送LIN同步断开符(低13位),以及检测LIN同步断开符。
CLKEN:时钟使能 (Clock enable)
该位用来使能CK引脚
0:禁止CK引脚;
1:使能CK引脚。
CR3 寄存器中SCEN, HDSEL 和 IREN 位
SCEN: 智能卡模式使能 (Smartcard mode enable)
该位用来使能智能卡模式
0:禁止智能卡模式;
1:使能智能卡模式。
注: UART4和UART5上不存在这一位
HDSEL:半双工选择 (Half-duplex selection)
选择单线半双工模式
0:不选择半双工模式;
1:选择半双工模式。
IREN:红外模式使能 (IrDA mode enable)
该位由软件设置或清除。
0:不使能红外模式;
1:使能红外模式。
*/
CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
/* Enable the peripheral */
/* 使能串口*/
__HAL_UART_ENABLE(huart);
/* Initialize the UART state */
/*初始化串口的状态:无错误/全局状态准备好/接收准备好/发送准备好
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
/* gState:全局处理状态,也包括发送状态
!<
UART state information related to global Handle management
and also related to Tx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef
*/
return HAL_OK;
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
/*
#define __HAL_RCC_USART1_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
/* Delay after an RCC peripheral clock enabling */\
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
UNUSED(tmpreg); \
} while(0U)
#define RCC_APB2ENR_USART1EN 0x1UL <<(14U) 第14位置1
*/
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
/*
#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
/* Delay after an RCC peripheral clock enabling */\
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
UNUSED(tmpreg); \
} while(0U)
#define RCC_APB2ENR_IOPAEN 0x1UL <<(2U) 第2位置1
*/
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*将GPIOA9 推挽模式 ,速度高 50MHz , */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*将GPIOA10 浮空输入模式 */
/* USART1 DMA Init */
/* USART1_RX Init */
hdma_usart1_rx.Instance = DMA1_Channel5; //串口1接收绑定到DMA1_Channel5;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;//外围到内存
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; //地址增加否
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; //内存自增加是
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // 数据BYTE
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //数据BYTE
hdma_usart1_rx.Init.Mode = DMA_NORMAL; //DMA工作模式:普通非循环
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW; //优先级低
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
/*
*/
__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);
/*#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \
do{ \
(__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
(__DMA_HANDLE__).Parent = (__HANDLE__); \
} while(0U)
实际好像没做特别的操作啊?
*/
/* USART1_TX Init */
hdma_usart1_tx.Instance = DMA1_Channel4;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
static void UART_SetConfig(UART_HandleTypeDef *huart)
{
uint32_t tmpreg;
uint32_t pclk;
/* Check the parameters */
assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); //检查波特率
assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); //检查停止位
assert_param(IS_UART_PARITY(huart->Init.Parity)); //检查校验位
assert_param(IS_UART_MODE(huart->Init.Mode)); //检查工作模式,工作模式在前面已设置为UART_MODE_TX_RX;
/*-------------------------- USART CR2 Configuration -----------------------*/
/* Configure the UART Stop Bits: Set STOP[13:12] bits
according to huart->Init.StopBits value */
MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
/*修改寄存器CR2中的停止位
0x3UL <<12U 就是13 12位
#define UART_STOPBITS_1 0x00000000U
将13位、12位置零,就是1个停止位
位13:12 STOP:停止位 (STOP bits)
这2位用来设置停止位的位数
00: 1个停止位;
01: 0.5个停止位;
10: 2个停止位;
11: 1.5个停止位;
注: UART4和UART5不能用0.5停止位和1.5停止位
*/
/*-------------------------- USART CR1 Configuration -----------------------*/
/* Configure the UART Word Length, Parity and mode:
Set the M bits according to huart->Init.WordLength value
Set PCE and PS bits according to huart->Init.Parity value
Set TE and RE bits according to huart->Init.Mode value
Set OVER8 bit according to huart->Init.OverSampling value */
#if defined(USART_CR1_OVER8)
tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
MODIFY_REG(huart->Instance->CR1,
(uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
tmpreg);
#else
tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
MODIFY_REG(huart->Instance->CR1,
(uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
tmpreg);
/*计算并修改CR1寄存器值*/
#endif /* USART_CR1_OVER8 */
/*-------------------------- USART CR3 Configuration -----------------------*/
/* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
/*修改硬件控制位
RTSE: RTS使能 (RTS enable)
0:禁止RTS硬件流控制;
1: RTS中断使能,只有接收缓冲区内有空余的空间时才请求下一个数据。当前数据发送完成
后,发送操作就需要暂停下来。如果可以接收数据了,将nRTS输出置为有效(拉至低电平)。
注: UART4和UART5上不存在这一位。
CTSE: CTS使能 (CTS enable)
0:禁止CTS硬件流控制;
1: CTS模式使能,只有nCTS输入信号有效(拉成低电平)时才能发送数据。如果在数据传输的
过程中, nCTS信号变成无效,那么发完这个数据后,传输就停止下来。如果当nCTS为无效
时,往数据寄存器里写数据,则要等到nCTS有效时才会发送这个数据。
注: UART4和UART5上不存在这一位
nCTS 是芯片上的一个引脚?
*/
#if defined(USART_CR1_OVER8)
/* Check the Over Sampling */
if(huart->Init.OverSampling == UART_OVERSAMPLING_8)
{
/*-------------------------- USART BRR Configuration ---------------------*/
if(huart->Instance == USART1)
{
pclk = HAL_RCC_GetPCLK2Freq();
huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
}
else
{
pclk = HAL_RCC_GetPCLK1Freq();
huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
}
}
else
{
/*-------------------------- USART BRR Configuration ---------------------*/
if(huart->Instance == USART1)
{
pclk = HAL_RCC_GetPCLK2Freq();
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
}
else
{
pclk = HAL_RCC_GetPCLK1Freq();
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
}
}
#else
/*-------------------------- USART BRR Configuration ---------------------*/
if(huart->Instance == USART1)
{
pclk = HAL_RCC_GetPCLK2Freq();
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
//设置波特率,USART1的时钟来源于PCLK2
}
else
{
pclk = HAL_RCC_GetPCLK1Freq();
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
}
#endif /* USART_CR1_OVER8 */
}
DMA 初始化:
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/*
#define __HAL_RCC_DMA1_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
*/ /*置1 RCC AHB外设时钟使能寄存器 (RCC_AHBENR) 中的DMA1EN位,使能DMA1时钟*/
SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\
/* Delay after an RCC peripheral clock enabling */\
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\
/*读取RCC_AHBENR_DMA1EN 位
UNUSED(tmpreg); \
/*unused 属性用于函数和变量,表示该函数或变量可能不使用。*/
} while(0U)
*/
/* DMA interrupt init */
/*设置DMA1通道4和5的中断优先级,并使能中断
/* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}
初始化DMA代码:该函数被HAL_UART_MspInit调用
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
{
uint32_t tmp = 0U;
/* Check the DMA handle allocation */
if(hdma == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
/*检查参数*/
/*
hdma_usart1_rx.Instance = DMA1_Channel5;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
*/
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); //DMA1_Channel5
assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); //DMA_PERIPH_TO_MEMORY
assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); //DMA_PINC_DISABLE
assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); //DMA_MINC_ENABLE
assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));//DMA_PDATAALIGN_BYTE
assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));//DMA_MDATAALIGN_BYTE
assert_param(IS_DMA_MODE(hdma->Init.Mode)); //DMA_NORMAL
assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); //DMA_PRIORITY_LOW
#if defined (DMA2)
/* calculation of the channel index */
/*有DMA2*/
if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
{
/* DMA1 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
计算得到 :hdma->ChannelIndex=0x00000010
hdma->DmaBaseAddress = DMA1; //DMA1= 0x40020000UL
//
}
else
{
/* DMA2 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
hdma->DmaBaseAddress = DMA2;
}
#else
/* DMA1 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
hdma->DmaBaseAddress = DMA1;
/*
没有定义DMA2
*/
#endif /* DMA2 */
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_BUSY; //将hdma状态设置为忙
/* Get the CR register value */
tmp = hdma->Instance->CCR; //读取CCR寄存器值
/* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
/*把 DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
DMA_CCR_DIR 取反,然后再与运算,将这些位全部置0了 */
tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
DMA_CCR_DIR));
/* Prepare the DMA Channel configuration */
tmp |= hdma->Init.Direction |
hdma->Init.PeriphInc | hdma->Init.MemInc |
hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
hdma->Init.Mode | hdma->Init.Priority;
/* Write to DMA Channel CR register */
hdma->Instance->CCR = tmp;
/*
将CCR寄存器:
位14 MEM2MEM: 清0
位6 PINC(外设地址增量模式 (Peripheral increment mode) ) 清0
位7 MINC:存储器地址增量模式 (Memory increment mode) 置1
位9:8 PSIZE[1:0]:外设数据宽度 (Peripheral size) 清为00: 8位
位11:10 MSIZE[1:0]:存储器数据宽度 (Memory size) 清为00: 8位
位5 CIRC:循环模式 (Circular mode) 清0:不执行循环操作
位13:12 PL[1:0]:通道优先级 (Channel priority level) 清为00: 低
*/
/* Initialise the error code */
hdma->ErrorCode = HAL_DMA_ERROR_NONE; //无错误
/* Initialize the DMA state*/
hdma->State = HAL_DMA_STATE_READY; //准备好
/* Allocate lock resource and initialize it */
hdma->Lock = HAL_UNLOCKED; //解锁状态
return HAL_OK;
}
从以上代码可以看出,串口没有开启任何的中断;
串口中断服务函数:
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles UART interrupt request.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
uint32_t isrflags = READ_REG(huart->Instance->SR); //读取整个SR寄存器
uint32_t cr1its = READ_REG(huart->Instance->CR1); //读取整个CR1寄存器
uint32_t cr3its = READ_REG(huart->Instance->CR3); //读取整个CR3寄存器
uint32_t errorflags = 0x00U;
uint32_t dmarequest = 0x00U;
/* If no error occurs */
errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
//如果出现错误:PE校验错误;FE: 帧错误;ORE:过载错误;NE: 噪声错误
if (errorflags == RESET)
{
/* UART in mode Receiver -------------------------------------------------*/
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
//RXNE:读数据寄存器非空 ,0:数据没有收到;1:收到数据,可以读出。
//RXNEIE:接收缓冲区非空中断使能 (RXNE interrupt enable) 该位由软件设置或清除。
//0:禁止产生中断;
//1:当USART_SR中的ORE或者RXNE为’1’时,产生USART中断。
//如果没有设置RXNEIE 中断,就不会运行下面的代码
UART_Receive_IT(huart);
return;
}
}
/* If some errors occur */
if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
{
/* UART parity error interrupt occurred ----------------------------------*/
/*发生奇偶校验错误
如果没使能校验错误中断,不会运行下面的代码
*/
if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
/* UART noise error interrupt occurred -----------------------------------*/
/*发生噪声错误
如果没使能错误中断,不会运行下面的代码
*/
if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_NE;
}
/* UART frame error interrupt occurred -----------------------------------*/
/*发生帧错误错误
如果没使能错误中断,不会运行下面的代码
*/
if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
/* UART Over-Run interrupt occurred --------------------------------------*/
/*发生过载错误 (Overrun error)
如果没使能错误中断,不会运行下面的代码
*/
if (((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
/* Call UART Error Call back function if need be --------------------------*/
/*当有错误*/
if (huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* UART in mode Receiver -----------------------------------------------*/
/*
//RXNE:读数据寄存器非空 ,0:数据没有收到;1:收到数据,可以读出。
//RXNEIE:接收缓冲区非空中断使能 (RXNE interrupt enable) 该位由软件设置或清除。
//0:禁止产生中断;
//1:当USART_SR中的ORE或者RXNE为’1’时,产生USART中断。
//如果没有设置RXNEIE 中断,就不会运行下面的代码
*/
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
UART_Receive_IT(huart);
}
/* If Overrun error occurs, or if any error occurs in DMA mode reception,
consider error as blocking */
/*
如果OVERRUN 错误发生了 或者 在DMA接收模式下发生了任何错误
将错误视为阻塞
*/
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
//如果运行了HAL_UART_Receive_DMA,那么dmarequest =TRUE
//我运行了HAL_UART_Receive_DMA
if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
{
/* Blocking error : transfer is aborted
Set the UART state ready to be able to start again the process,
Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
UART_EndRxTransfer(huart);
/*
static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
/*清除RXNEIE(OVERRUN中断)、PEIE(奇偶中断)、EIE(错误中断)这些中断 */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* At end of Rx process, restore huart->RxState to Ready */
/*接收状态为准备好*/
huart->RxState = HAL_UART_STATE_READY;
}
*/
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); //清除DMAR 位
/* Abort the UART DMA Rx channel */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; //将收到和发送的数据都清为0
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
/* Call Directly XferAbortCallback function in case of error */
huart->hdmarx->XferAbortCallback(huart->hdmarx);
}
}
else
{
/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Non Blocking error : transfer could go on.
Error is notified to user through user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
huart->ErrorCode = HAL_UART_ERROR_NONE;
}
}
return;
} /* End if some error occurs */
/* UART in mode Transmitter ------------------------------------------------*/
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
{
UART_Transmit_IT(huart);
return;
}
/* UART in mode Transmitter end --------------------------------------------*/
if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
{
UART_EndTransmit_IT(huart);
return;
}
}