“解决STM32串口UART5无法进入接收中断问题”
在一个项目里,串口123均使用了,剩下uart4和5未使用。因新加入功能,需要再用1个串口,当时粗略看了手册,uart4和uart5只是不能同步通信,其他功能正常。于是就近使用了PC12和PD2引脚对应UART5。
配置好串口5的初始化代码和中断回调函数后,测试无法进入接收中断,现象为一收数据立即hardfault,然后过一会看狗就复位了。
在CSDN上查了很多关于UART4和UART5的资料,大多指向2个问题:
- ORE溢出导致反复进入中断;
- 启动文件里没有加入uart4和uart5的中断函数
ORE溢出导致反复进入中断和本例不相符,本例是根本进入不了中断。
仔细检查启动文件,使用的是startup_stm32f103xe.s ,uart4和uart5的中断均有。
一时间陷入僵局,排查了2天也没有找到原因。
后来把main函数前段仔细看了一下,根源找到了。在进入main函数后第一件事是转移了中断向量表!SCB->VTOR = 0X08010000;
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
SCB->VTOR = 0X08010000;//偏移量
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
添加该语句是因为项目使用了OTA升级功能,这个是用户APP程序。
为了调试方便,直接把语句注释掉,编译烧录UART5就正常了。
下面附上uart5的配置和回调函数源代码:
UART_HandleTypeDef huart5;
/* UART5 init function */
void MX_UART5_Init(void)
{
huart5.Instance = UART5;
huart5.Init.BaudRate = 9600;
huart5.Init.WordLength = UART_WORDLENGTH_8B;
huart5.Init.StopBits = UART_STOPBITS_1;
huart5.Init.Parity = UART_PARITY_NONE;
huart5.Init.Mode = UART_MODE_TX_RX;
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart5) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
UNUSED(Size);
if(huart->Instance==UART5)
{
gps_rx_len = Size;
HAL_UART_Transmit(&huart1,gps_rbuff,gps_rx_len,gps_rx_len);
memset(gps_rbuff,0x00,sizeof(gps_rbuff));
HAL_UARTEx_ReceiveToIdle_IT(&huart5,gps_rbuff,200);
}
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UARTEx_RxEventCallback can be implemented in the user file.
*/
}
在main函数里开启中断方式接收。这里用的是HAL_UARTEx_ReceiveToIdle_IT( ) 意思是接收到200bytes结束或者遇到Idle中断时结束。
HAL_UARTEx_ReceiveToIdle_IT(&huart5,gps_rbuff,200);