[STM32CubeMX]學習筆記6:按鍵控制DMA串口發送

MCU:STM32F103ZET6

IDE:  MDK-ARM V5 +STM32CubeMX5.0.0

串口調試助手:SSCOM3.2

 

功能描述:通過KEY_UP按鍵控制DMA串口1數據的傳送。

需要配置DMA,串口USART1,使能按鍵中斷,LED提示燈。

 

一. 在 Pinout&Configuration---System Core中:

  • 1. 首先設置時鐘RCC的HSE(外部高速時鐘)爲晶振模式:Crystal/ceramic Resonator

  • 2. 設置系統SYS的Debug爲Serial Wire:

  • 3. 設置GPIO中的LED管腳。

在MCU管腳圖中找到PC0和PC1管腳(查原理圖對應的管腳號),將管腳設置爲GPIO_Output輸出模式,此時在System Core的GPIO中,會出現對應端口,點擊端口將GPIO output level設置爲low,將User Label定義爲LED。

  • 4. 設置按鍵映射到外部中斷線上。

選擇PA0的端口爲GPIO_EXTI0:

KEY_UP應爲上升沿觸發,並外接下拉電阻,點擊端口將GPIO mode設置爲External Interrupt Mode with Rising edge trigger detection,將GPIO Pull-up/Pull-down配置爲Pull-down,將User Label定義爲KEY_UP。

*TIPS:在將端口映射到EXTI線上後,SYS會出現以下警告:表示紅色部分的模式不可使用,且因爲PA0本身對應的是系統喚醒功能,因此System Wake-UP的功能也無法被選中。

接着在GPIO-Configuration中使能四個GPIO的中斷(之前就是忘記了這個):

二. 在 Pinout&Configuration---Connectivity中:

  • 1. 打開USART1,並設置模式爲異步收發模式Asynchronous:

  • 2. 設置USART1的參數,通用的“96-N-8-1”模式,即波特率9600,N校驗位(無校驗),數據位數爲8,停止位爲1位:

三. 在 Pinout&Configuration---System Core中:

1. 配置DMA參數:

經過第二步後,PA9和PA10被配置爲了USART1_RX/USART1_TX:

按照圖中數字順序配置DMA,點擊Add,添加USARTT1_TX, Channel會自動選擇,Direction默認選擇的是存儲器到外設,Mode不使用循環,設置爲Normal即可;外設地址無增量,存儲器地址有增量;Data Width根據需要將存儲器和外設的寬度都設置爲字節。

四.在 Clock Configuration中:

配置時鐘爲72 Mhz。

五.在 Project Manager---Project中:

  • 1.設置項目的名稱以及保存的位置,選擇Toolchain/IDE爲MDK-ARM V5,

Tips:最好把Linker Settings中的Minimum Heap Size設置爲0x600。

  • 2.在Code Generator選項中如下勾選:

最後點Generate Code生成代碼,並選擇“Open Project”:

六.代碼分析與改寫:

配置思路:首先在一個數組中定義要發送的內容;讓LED1不斷閃爍,表示系統正在運行;編寫中斷回調函數,當按鍵按下時發送數據到外設(USART1)中,並改變LED2狀態表示進入中斷。

此處與筆記2的分析過程相同:

************************************************************************************************************************************************

在生成的stm32f1xx_it.c中是系統中斷的相關函數,找到四個外部中斷的中斷服務函數:

void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */
}

進入“HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0)”函數後發現定義如下:

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

服務函數中第一步對中斷口清零,隨後進入回調函數“HAL_GPIO_EXTI_Callback”:

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
}

回調函數中沒有定義任何操作,因此將我們要實現的功能編寫在回調函數中。

************************************************************************************************************************************************

  • 1. 定義發送的數組內容,在main.c中添加:
/* USER CODE BEGIN PV */
uint8_t serialMsg[] = "DMA has been successfully received! \r\n";
/* USER CODE END PV */
  • 2.在while(1)循環中添加LED1系統正常運行指示燈:
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	    HAL_GPIO_TogglePin(GPIOC,LED1_Pin);
	    HAL_Delay(200);
    /* USER CODE END WHILE */
  • 3.編寫中斷回調函數:
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin==UP_Pin)
	{
		for(long i=1;i<72000;i++){};  //軟件消抖
			if(HAL_GPIO_ReadPin(UP_GPIO_Port,UP_Pin)==1)  //按鍵是否按下
			{
				HAL_GPIO_TogglePin(GPIOC,LED2_Pin);
				HAL_UART_Transmit_DMA(&huart1, (uint8_t *)serialMsg, sizeof(serialMsg)); 
				HAL_Delay(1000);
			}
	}
}
/* USER CODE END 4 */

至此,編譯後無錯並下載到開發板中,就完成了通過STM32CubeMX調用HAL庫實現按鍵控制DMA串口發送的效果程序。

實驗現象:正常運行後,按下KEY_UP後DMA發送數組至串口:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章