STM32F103的USART除錯日誌
阿新 • • 發佈:2018-11-15
本次串列埠除錯過程中遇到兩個問題:
1、傳送資料出現死迴圈:
具體表現為: 程式卡死在 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 無資料輸出。TXD線上只是低電平,傳送埠指示燈常亮。
注:串列埠1的引腳定義是PA.09,PA.10
解決問題:
串列埠初始化時:USART1 和USART6 要使用 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE);而
USART2, USART3, UART4 , UART5要使用 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) ;問題得以解決。
typedef struct _UART_CFG { USART_TypeDef* UartNo; PIN_CFG Tx; PIN_CFG RX; uint32_t BaudRate; }UART_CFG; void Comm_Port_Init(void) { UART_CFG uart_comm; uart_comm.UartNo = UART_COM; uart_comm.Tx.Pin= GPIO_Pin_9; uart_comm.Tx.Port = GPIOA; uart_comm.RX.Pin = GPIO_Pin_10; uart_comm.RX.Port = GPIOA; uart_comm.BaudRate = BAUD_COM; Uart_Init(uart_comm); } void Uart_Init(UART_CFG uart) { uint8_t Uart_IRQChannel_No; uint32_t RCC_APB1Periph; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; NVIC_InitTypeDef NVIC_InitStructure; if(uart.UartNo == USART1) { Uart_IRQChannel_No = USART1_IRQn; RCC_APB1Periph = RCC_APB2Periph_USART1; RCC_APB2PeriphClockCmd(RCC_APB1Periph, ENABLE); } else if(uart.UartNo == USART2) { Uart_IRQChannel_No = USART2_IRQn; RCC_APB1Periph = RCC_APB1Periph_USART2; RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE); } else if(uart.UartNo == USART3) { Uart_IRQChannel_No = USART3_IRQn; RCC_APB1Periph = RCC_APB1Periph_USART3; RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE); } else if(uart.UartNo == UART4) { Uart_IRQChannel_No = UART4_IRQn; RCC_APB1Periph = RCC_APB1Periph_UART4; RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE); } else { Uart_IRQChannel_No = UART5_IRQn; RCC_APB1Periph = RCC_APB1Periph_UART5; RCC_APB1PeriphClockCmd(RCC_APB1Periph, ENABLE); } GPIO_InitStructure.GPIO_Pin = uart.Tx.Pin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(uart.Tx.Port, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = uart.RX.Pin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(uart.RX.Port, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = uart.BaudRate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(uart.UartNo, &USART_InitStructure);//初始化外設 USARTx 暫存器 USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; USART_ClockInit(uart.UartNo, &USART_ClockInitStructure); USART_Cmd(uart.UartNo, ENABLE); USART_ITConfig(uart.UartNo,USART_IT_RXNE,ENABLE);//ENABLE-DISABLE//使能或者失能指定的 USART 中斷 NVIC_InitStructure.NVIC_IRQChannel = Uart_IRQChannel_No; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
2、接收資料中斷出現死迴圈:
具體表現:收到資料程式會不斷進入中斷,USART_GetITStatus 檢查又沒有中斷髮生。本函式一退出就重新再進入,就這樣死迴圈了。原始碼如下:
void USART2_IRQHandler(void) { BYTE Data = 0; OSIntEnter(); if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET) //檢查指定的usart是否發生了中斷 { Data = USART_ReceiveData(USART2); // do something at this; 處理資料 USART_ClearFlag(USART2,USART_FLAG_TC ); //清除中斷標誌 } else { USART_ClearFlag(UART_COM, USART_IT_ORE); } OSIntExit(); }
解決辦法:
進入中斷後必須第一時間清零RXNE,如沒及時清零,下一幀資料過來時就會產生Overrun error!
更改為如下程式碼就OK了。
void USART2_IRQHandler(void)
{
BYTE Data = 0;
OSIntEnter();
if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
//檢查指定的usart是否發生了中斷
{
Data = USART_ReceiveData(USART2);
USART_ClearFlag(USART2,USART_FLAG_TC ); //清除中斷標誌
// do something at this; 處理資料
}
else
{
USART_ClearFlag(UART_COM, USART_IT_ORE);
}
OSIntExit();
}