一、工具
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