void EnableUsart_IT(void) { __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);//開啓串口2接收中斷 __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);//開啓串口2空閒接收中斷 __HAL_UART_CLEAR_IDLEFLAG(&huart2); //清除串口2空閒中斷標誌位 HAL_UART_Receive_DMA(&huart2,Usart2type.Usart2DMARecBuffer,USART2_DMA_REC_SIE); //使能DMA接收 }
void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ uint32_t temp; if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) == SET) //若是串口2觸發空閒中斷 { __HAL_UART_CLEAR_IDLEFLAG(&huart2); //清除串口2空閒中斷標誌位 HAL_UART_DMAStop(&huart2); //關閉DMA //讀取一下兩個寄存器方可清除DMA接收中斷 temp = huart2.Instance->SR; //清除SR狀態寄存器(F0系列爲ISR) temp = huart2.Instance->DR; //讀取DR數據寄存器(F0系列爲RDR)用來清除中斷 temp = hdma_usart2_rx.Instance->CNDTR;//獲取DMA中未傳輸的數據個數 Usart2type.UsartDMARecLen = USART2_DMA_REC_SIE - temp; //總計數減去未傳輸的數據個數,獲得已經接收的數據個數 HAL_UART_AbortCpltCallback(&huart2); //串口接收回調函數 } /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ HAL_UART_Receive_DMA(&huart2,Usart2type.Usart2DMARecBuffer,USART2_DMA_REC_SIE); //從新打開DMA接收 /* USER CODE END USART2_IRQn 1 */ }
有未讀數據則從地址0+old_len開始獲取DMA接收區的數據函數
無則從地址0開始獲取DMA接收區的數據oop
/* 功能:串口回調函數,用來搬移數據 */ void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) { //printf("*******in callback*******\r\n"); if(huart->Instance == USART2) { if(Usart2type.UsartRecLen>0) { memcpy(&Usart2type.Usart2RecBuffer[Usart2type.UsartRecLen],Usart2type.Usart2DMARecBuffer,Usart2type.UsartDMARecLen); //轉存到待處理區域 Usart2type.UsartRecLen += Usart2type.UsartDMARecLen; } else { memcpy(Usart2type.Usart2RecBuffer,Usart2type.Usart2DMARecBuffer,Usart2type.UsartDMARecLen); //轉存到待處理區域 Usart2type.UsartRecLen = Usart2type.UsartDMARecLen; } printf("%s\r\n", Usart2type.Usart2DMARecBuffer); memset(Usart2type.Usart2DMARecBuffer, 0x00, Usart2type.UsartDMARecLen); //先清空DMA緩衝區 Usart2type.UsartRecFlag = 1; //置位標記,表示串口2接收到數據 } }
int main(void) { /* USER CODE BEGIN 1 */ /* 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(); MX_DMA_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ EnableUsart_IT(); printf("System init OK!!\r\n"); //模組開機 HAL_GPIO_WritePin(NB_PWK_GPIO_Port, NB_PWK_Pin, GPIO_PIN_SET); HAL_Delay(2500); HAL_GPIO_WritePin(NB_PWK_GPIO_Port, NB_PWK_Pin, GPIO_PIN_RESET); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { memset(Usart2type.Usart2RecBuffer, 0x00, USART2_REC_SIE); HAL_UART_Transmit(&huart2, (uint8_t*)"ATI\r\n", strlen("ATI\r\n"), 0xff); printf("ATI\r\n"); HAL_Delay(2000); if(Usart2type.UsartRecFlag == 1) { //printf("Usart2 rec is:%s\r\n", Usart2type.Usart2RecBuffer); Usart2type.UsartRecFlag = 0; Usart2type.UsartRecLen = 0; } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
VCC------stm32 V3測試
或ui
VCC------cp2102 3V33d