控制器:STM32F411RE
我使用USART2作为基于中断的串行端口。我在stmcubemx中启用了NVIC,每当从终端中断传输数据时生成的代码就会生成,但uart状态为HAL_UART_STATE_READY。因为它将接收函数UART_Receive_IT函数并且出来了。请帮助解决这个问题,我还需要指导如何将uart作为中断模式。
代码:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE))
{
HAL_UART_Transmit(huart, str, 7, 0xFF);
memset(str, '\0', sizeof(str));
}
} /********* IRQ code*******/
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);
/* UART parity error interrupt occurred ------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_PEFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART frame error interrupt occurred -------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_FEFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART noise error interrupt occurred -------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_NEFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_NE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART Over-Run interrupt occurred ----------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_OREFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
if(tmp2 == 0x32)
tmp2=0x32;
/* UART in mode Receiver ---------------------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
UART_Receive_IT(huart);
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE);
/* UART in mode Transmitter ------------------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
UART_Transmit_IT(huart);
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC);
/* UART in mode Transmitter end --------------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
UART_EndTransmit_IT(huart);
}
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
HAL_UART_ErrorCallback(huart);
}
}
/************receive code *********/
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp1 = 0;
tmp1 = huart->State;
if((tmp1 == HAL_UART_STATE_BUSY_RX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
{
if(huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t*) huart->pRxBuffPtr;
if(huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1;
}
}
else
{
if(huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
if(--huart->RxXferCount == 0)
{
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Check if a transmit process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
else
{
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
huart->State = HAL_UART_STATE_READY;
}
HAL_UART_RxCpltCallback(huart);
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
答案 0 :(得分:0)
我认为您的代码中存在一些问题。 HAL的工作方式是让您更轻松,这样您就不需要检查中断标志等等。 在中断处理程序中,实际检查UART_IT_RXNE位,但当HAL从USART RX寄存器读取字节时,该位已自动清零。所以删除该行:
if(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE)
str似乎是一个字符数组,我认为你没有使用memset,正确的方法是:
#define LEN 7
char str[LEN];
memset(str, '\0', LEN);
我知道你想要在到达RX中断处理程序时发送一个字符串,但我不确定你是如何调用HAL_UART_Receive_IT
函数的。
我使用它的方式如下:
volatile bool char_received = false;
volatile char rx_char;
int main(void)
{
//All your hardware init here
//Receive 1 character in interrupt mode
HAL_UART_Receive_IT(&huart, &rx_char, 1);
while(1)
{
if (rx_char == true)
{
rx_char = false;
if (rx_char == 's')
{
HAL_UART_Transmit(&huart, "Hello", 5, 100);
}
HAL_UART_Receive_IT(&huart, &rx_char, 1);
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
rx_char = true;
}
在上面的代码中,我发送了" Hello"如果我收到字符串'在中断模式下。请注意,我在中断处理程序中没有做太多,只需设置一个标志。另请注意,您需要再次拨打电话HAL_UART_Receive_IT
。
答案 1 :(得分:-1)
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);
/* UART parity error interrupt occurred ------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_PEFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART frame error interrupt occurred -------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_FEFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART noise error interrupt occurred -------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_NEFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_NE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART Over-Run interrupt occurred ----------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_OREFLAG(huart);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
if(tmp2 == 0x32)
tmp2=0x32;
/* UART in mode Receiver ---------------------------------------------------*/
if((tmp1 != RESET) && (tmp2 != RESET))
{
HAL_UART_Receive(huart, buff, 8, 0xFF); // FOR receive data on interrupt base :chandan
}