一、工具
1、硬件:STM32L053R8單片機(HAL庫)
2、編譯環境:Atollic TrueSTUDIO for STM32 9.3.0
3、輔助工具:STM32CubeMX
二、DAC輸出三角波解讀
為了便於解讀和查看,我這里是從STM32F4的用戶手冊中截圖的DAC生成三角波的功能介紹,介紹的文字很少,但每句話都很重要,同時我還圈出來幾個地方作以標記。
這里我僅對標記的地方做一些解讀。
- 通過圖60可以看到使用DAC輸出的三角波基電壓(也就是DAC_DHRx的值)是可以調節的,而這個基電壓的值就是我們常用DAC輸出電壓的值,這個值決定了三角波的最低電壓(或者說向上的偏移)。三角波的最高電壓(也就是幅值)就是(DAC_DHRx+MAMPx)。
- DAC本身是不會自動進行計數的,要想達到遞增和遞減的效果需要一個觸發事件,如下圖61所示,每當獲取一個觸發事件,DOR就會加一,這就決定了我們需要為DAC配置一個觸發源(后面我使用的是定時器作為觸發源)。
- 最后一點需要注意,在進行配置MAMPx的值時要保證DAC沒有被啟動。

三、單片機系統時鍾配置
使用的是內部MSI時鍾源作為時鍾(沒有展示的部分默認配置)。

四、單片機DAC配置
要想使用DAC輸出三角波需要使用外部觸發源(至於原因上面有介紹),硬件不同觸發源可能會不同,這里我選擇定時器6作為觸發源。下圖中的第3步的最后一行是設置DAC輸出的三角波的MAMPx值,滿值是4095對應3.3V電壓。第2步的外部觸發不用勾選。
五、單片機DAC觸發源定時器6配置
定時器的周期可以決定DAC輸出三角波的頻率,周期越短頻率越高。

六、生成代碼並進行完善

自動生成的代碼DAC初始化完成后並沒有開啟,需要自己手動添加代碼開啟DAC功能。與此同時,在開啟DAC后還需要設置一下DAC輸出的三角波的基准電壓(我這里設置基准電壓值為0)。
/** * @brief DAC Initialization Function * @param None * @retval None */ static void MX_DAC_Init(void) { /* USER CODE BEGIN DAC_Init 0 */ /* USER CODE END DAC_Init 0 */ DAC_ChannelConfTypeDef sConfig = {0}; /* USER CODE BEGIN DAC_Init 1 */ /* USER CODE END DAC_Init 1 */ /** DAC Initialization */ hdac.Instance = DAC; if (HAL_DAC_Init(&hdac) != HAL_OK) { Error_Handler(); } /** DAC channel OUT1 config */ sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO; /* 定時器每個周期結束就會使DAC的值加1,最高幅值為2047,輸出三角波的周期為0.5ms*2047*2≈2s */ sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK) { Error_Handler(); } /** Configure Triangle wave generation on DAC OUT1 */ if (HAL_DACEx_TriangleWaveGenerate(&hdac, DAC_CHANNEL_1, DAC_TRIANGLEAMPLITUDE_2047) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN DAC_Init 2 */ HAL_DAC_Start(&hdac, DAC_CHANNEL_1); HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0); /* USER CODE END DAC_Init 2 */ }
同樣的定時器初始化完成后也需要自己手動添加啟動代碼。
/** * @brief TIM6 Initialization Function * @param None * @retval None */ static void MX_TIM6_Init(void) { /* USER CODE BEGIN TIM6_Init 0 */ /* USER CODE END TIM6_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM6_Init 1 */ /* USER CODE END TIM6_Init 1 */ htim6.Instance = TIM6; htim6.Init.Prescaler = 0; htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = 1023; /* 可以改變三角波的頻率 APB1總線時鍾是2.097MHz, 定時器的周期為(1023+1)/2.097 ≈ 0.5ms */ htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM6_Init 2 */ HAL_TIM_Base_Start(&htim6); /* USER CODE END TIM6_Init 2 */ }
完善以上兩處地方后,編譯沒問題就可以下載到單片機上,通過示波器即可觀察到三角波的輸出。

#endif
