现在USART接受上遇到两个问题,想请教一下。
1. USART参数设为 19200 + 8Bit + Even + 1 Stop. 用 IRNE 中断来接受从串口来的字符输入。
现在能接收到IRNE的中断并能正确读到字符,但是中断例程里同时能检测到帧错误(FE)或者校验错误(PE)。
而且有这样的规律,若键入字符ASCII码为EVEN位数,则报PE,如果是ODD位数则包FE。
请问有谁知道这种问题的是什么原因吗?
2. 还是USART接受字符问题。配置同上,接收字串在IRNE中断例程里读取单字节数据。正常串口输入能接收到正确字符,现象同1。
如果用串口助手发送一串字符串,如“ABCDEFG”,中断里总是检测到 ORE的错误,并且会丢到几个字符。之前以为是系统时钟频率低导致的,
于是将系统时钟频率由2MHz升到32MHz,问题依旧。请问这是什么原因?
附代码(stm32L07x):
- void USARTx_IRQHandler(void)
- {
- iCnt++;
- USART_FUNCTION_ISR = 0;
- if (LL_USART_IsActiveFlag_RXNE(USARTx_INSTANCE) && LL_USART_IsEnabledIT_RXNE(USARTx_INSTANCE))
- {
- uiRxByte = (uint32_t)LL_USART_ReceiveData8(USARTx_INSTANCE);
- //LL_USART_TransmitData8(USARTx_INSTANCE, (uint8_t) uiRxByte);
- //LL_USART_TransmitData8(USARTx_DEBUG_INSTANCE, (uint8_t) uiRxByte);
- //printf("(%d)-rev(0x%02x)\n",iCnt, uiRxByte);
- USART_FUNCTION_ISR |= USART_ISR_RXNE_Msk;
- }
- if (LL_USART_IsActiveFlag_TXE(USARTx_INSTANCE) && LL_USART_IsEnabledIT_TXE(USARTx_INSTANCE))
- {
- USART_FUNCTION_ISR |= USART_ISR_TXE_Msk;
- //printf ("(%d)-USARTx_IRQHandler-LL_USART_IsActiveFlag_TXE\n",iCnt);
- }
- if (LL_USART_IsActiveFlag_ORE(USARTx_INSTANCE))
- {
- //printf("(%d)-OVERUN happened\n",iCnt);
- LL_USART_ClearFlag_ORE(USARTx_INSTANCE);
- LL_USART_ReceiveData8(USARTx_INSTANCE);
- USART_FUNCTION_ISR |= USART_ISR_ORE_Msk;
- }
- if (LL_USART_IsActiveFlag_NE(USARTx_INSTANCE))
- {
- //printf("(%d)-Noise detected\n", iCnt);
- LL_USART_ClearFlag_NE(USARTx_INSTANCE);
- //LL_USART_ReceiveData8(USARTx_INSTANCE);
- USART_FUNCTION_ISR |= USART_ISR_NE_Msk;
- }
- if (LL_USART_IsActiveFlag_FE(USARTx_INSTANCE))
- {
- //printf("(%d)-Frame Error\n",iCnt);
- LL_USART_ClearFlag_FE(USARTx_INSTANCE);
- //LL_USART_ReceiveData8(USARTx_INSTANCE);
- USART_FUNCTION_ISR |= USART_ISR_FE_Msk;
- }
- if (LL_USART_IsActiveFlag_PE(USARTx_INSTANCE))
- {
- //printf("(%d)-Parity Error\n",iCnt);
- LL_USART_ClearFlag_PE(USARTx_INSTANCE);
- //LL_USART_ReceiveData8(USARTx_INSTANCE);
- USART_FUNCTION_ISR |= USART_ISR_PE_Msk;
- }
- }
- void USART_Init( \
- uint32_t uiBoudRate, \
- uint32_t uiDataWidth, \
- uint32_t uiParity, \
- uint32_t uiStopBits)
- {
- //TODO: Parameters checking
- /* (1) Enable GPIO clock and configures the USART pins *********************/
- /* Enable the peripheral clock of GPIO Port */
- USARTx_GPIO_CLK_ENABLE();
- /* Configure Tx Pin as : Alternate function, High Speed, Push pull, Pull up */
- LL_GPIO_SetPinMode(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_MODE_ALTERNATE);
- USARTx_SET_TX_GPIO_AF();
- LL_GPIO_SetPinSpeed(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_SPEED_FREQ_HIGH);
- LL_GPIO_SetPinOutputType(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_OUTPUT_PUSHPULL);
- LL_GPIO_SetPinPull(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_PULL_UP);
- /* Configure Rx Pin as : Alternate function, High Speed, Push pull, Pull up */
- LL_GPIO_SetPinMode(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_MODE_ALTERNATE);
- USARTx_SET_RX_GPIO_AF();
- LL_GPIO_SetPinSpeed(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_SPEED_FREQ_HIGH);
- LL_GPIO_SetPinOutputType(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_OUTPUT_PUSHPULL);
- LL_GPIO_SetPinPull(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_PULL_UP);
- /* (2) NVIC Configuration for USART interrupts */
- /* - Set priority for USARTx_IRQn */
- /* - Enable USARTx_IRQn */
- NVIC_SetPriority(USARTx_IRQn, 0);
- NVIC_EnableIRQ(USARTx_IRQn);
- /* (2) Enable USART peripheral clock and clock source ***********************/
- USARTx_CLK_ENABLE();
- /* Set clock source */
- USARTx_CLK_SOURCE();
- /* (3) Configure USART functional parameters ********************************/
- /* Disable USART prior modifying configuration registers */
- /* Note: Commented as corresponding to Reset value */
- LL_USART_Disable(USARTx_INSTANCE);
- /* TX/RX direction */
- LL_USART_SetTransferDirection(USARTx_INSTANCE, LL_USART_DIRECTION_TX_RX);
- /* 8 data bit, 1 start bit, 1 stop bit, no parity */
- LL_USART_ConfigCharacter(USARTx_INSTANCE, uiDataWidth, uiParity, uiStopBits);
- LL_USART_SetBaudRate(USARTx_INSTANCE, SystemCoreClock, LL_USART_OVERSAMPLING_16, uiBoudRate);
- /* (4) Enable USART *********************************************************/
- LL_USART_Enable(USARTx_INSTANCE);
- /* Polling USART initialisation */
- while((!(LL_USART_IsActiveFlag_TEACK(USARTx_INSTANCE))) || (!(LL_USART_IsActiveFlag_REACK(USARTx_INSTANCE))))
- {
- }
- /* Enable RXNE and Error interrupts */
- LL_USART_EnableIT_ERROR(USARTx_INSTANCE);
- }
- void main(void)
- {
- ...
- while(1)
- {
- if (i == iCnt) continue;
-
- __disable_irq();
- i = iCnt;
- if (pSerialGetByte(&cReadByte))
- {
- printf("(%d) - Read(0x%02x)\n", i , cReadByte);
- }
- if (USART_ISR_TXE_Msk & USART_FUNCTION_ISR)
- {
- printf("(%d) - USART_ISR_TXE_Msk\n", i );
- }
- if (USART_ISR_ORE_Msk & USART_FUNCTION_ISR)
- {
- printf("(%d) - USART_ISR_ORE_Msk\n", i );
- }
- if (USART_ISR_FE_Msk & USART_FUNCTION_ISR)
- {
- printf("(%d) - USART_ISR_FE_Msk\n", i );
- }
- if (USART_ISR_NE_Msk & USART_FUNCTION_ISR)
- {
- printf("(%d) - USART_ISR_NE_Msk\n", i );
- }
- if (USART_ISR_PE_Msk & USART_FUNCTION_ISR)
- {
- printf("(%d) - USART_ISR_PE_Msk\n", i );
- }
- __enable_irq();
- }
- }
复制代码
|
如果是的话,那么问题来了:按照楼主的说法,用串口助手发送一串字符串,如“ABCDEFG”,这是多个字节,如果中断处理函数没有一个字节处理完再打开中断处理 下一个字节,肯定是有问题的。
当我授渔好了,根据 官方 例程“stm32cube_fw_f1_v160.zip”(下载官方软件STM32CubeMX底下搜索路径“STM32Cube\Repository”,L0系列也有自己找)
路径下找到自己要的应用例程,例如楼主找 LL库下用 串口中断方式通讯,而且是连续不断的打开中断处理,那么找路径“Cube_FW_F1_V1.6.0\Projects\STM32F103RB-Nucleo\Examples_LL\USART\USART_Communication_Rx_IT_Continuous\MDK-ARM”下点击“Project.uvprojx”打开工程。
官方的串口中断处理回调函数是这样的,参考一下:
官方有轮子,就不需要自己造轮子,关注怎么用官方给的轮子去造车子就好了。
评分
查看全部评分
评分
查看全部评分