这样全采用HAL库的配置是完全没有问题的,那么为什么会出现上面所说的那个问题呢?且往下看 相信不少同学在开发的时候,对于一些定义命名都喜欢“顾名思义”,也是变量命名的一种最基本要求,加入用了4个串口,各自负责不同的功能,这样命名,谁看得出来哪个串口是干什么用的: UART_HandleTypeDef huart1;UART_HandleTypeDef huart2;UART_HandleTypeDef huart3;UART_HandleTypeDef huart4;一般都会命名为具体的功能描述: UART_HandleTypeDef ble_uart;UART_HandleTypeDef print_uart;UART_HandleTypeDef gsm_uart;UART_HandleTypeDef gps_uart;然后串口在初始化的时候,就会重新初始化,写成自己的函数: static void BluetoothUartInit(void){ BluetoothUart.Instance = USART2; BluetoothUart.Init.BaudRate = 115200; BluetoothUart.Init.WordLength = UART_WORDLENGTH_8B; BluetoothUart.Init.StopBits = UART_STOPBITS_1; BluetoothUart.Init.Parity = UART_PARITY_NONE; BluetoothUart.Init.Mode = UART_MODE_TX_RX; BluetoothUart.Init.HwFlowCtl = UART_HWCONTROL_NONE; BluetoothUart.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&BluetoothUart) != HAL_OK) { Error_Handler(); } HAL_UART_Receive_IT(&BluetoothUart, &ble_com.recbyte, 1);}这时候我们开始运行代码,看一下huart2和BluetoothUart的值 BluetoothUart->Instance = 0x400044000;huart2->Instance = 0;再来看下USART2对应的值是多少,加起来不正是上面的值吗,也就是说huart2实际上是没有被赋予正确的值的: #define PERIPH_BASE (0x40000000UL) /*!< Peripheral base address */#define APBPERIPH_BASE (PERIPH_BASE)#define USART2_BASE (APBPERIPH_BASE + 0x00004400UL)当然其他值也是没有被正确赋值的: 至于为什么仿真会报PE错误,继续看看报这个错误的原因: uint32_t isrflags = READ_REG(huart->Instance->ISR); uint32_t cr1its = READ_REG(huart->Instance->CR1); uint32_t cr3its = READ_REG(huart->Instance->CR3); uint32_t errorflags; uint32_t errorcode;主要看ISR、CR1和USART_ISR_PE、USART_CR1_PEIE这几个寄存器
#define USART_ISR_PE_Pos (0U)#define USART_ISR_PE_Msk (0x1UL << USART_ISR_PE_Pos) /*!< 0x00000001 */#define USART_ISR_PE USART_ISR_PE_Msk /*!< Parity Error */#define USART_CR1_PEIE_Pos (8U)#define USART_CR1_PEIE_Msk (0x1UL << USART_CR1_PEIE_Pos) /*!< 0x00000100 */#define USART_CR1_PEIE USART_CR1_PEIE_Msk /*!< PE Interrupt Enable */CR1 = 0x20001160;ISR = 0;//最终计算isrflags & USART_ISR_PE = 0&1 = 0;cr1its & USART_CR1_PEIE = 0x20001160&(1<<8) = 0x100;触发PE错误条件是,当然满足了,我觉得触发这个错误可能纯属偶然... /* UART parity error interrupt occurred -------------------------------------*/ if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) { __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); huart->ErrorCode |= HAL_UART_ERROR_PE; }最终如何解决呢,很简单,还是上面说到的,你用cubemx配套生成的,肯定不会出问题,当然了,你改为自己的,肯定也不会出问题,一个用一半显然是不行的啦 为了不受cubemx生成代码影响,可以采取宏定义的方法: void USART2_IRQHandler(void){ /* USER CODE BEGIN USART2_IRQn 0 */ #if 0 /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */#else HAL_UART_IRQHandler(&BluetoothUart);#endif /* USER CODE END USART2_IRQn 1 */}问题就到这里了,问题不大,却需要多多留心!
|