STM32G474单片机开发入门(十七)DAC详解及输出电压和正弦波实战
文章目录
- 一.概要
- 二.STM32G474RET6单片机DAC外设特点
- 三.STM32单片机DAC内部结构图
- 四.STM32单片机DAC基本操作
- 五.CubeMX配置一个DAC输出电压例程
- 1.硬件准备
- 2.创建CubeMX工程
- 3.实验效果
- 六.CubeMX配置一个DAC输出1KHZ正弦波例程
- 1.硬件准备
- 2.创建CubeMX工程
- 3.实验效果
- 七.小结
一.概要
DAC(Digital to analog converter)即数字模拟转换器,它可以将数字信号转换为模拟信号。它的功能与ADC相反,单片机普通I/O口只能输出高或者低,DAC引脚就能输出0~3.3V内任意电压值的电平。
STM32单片机的DAC功能通过内置于芯片内部的数模转换器实现,能够将数字信号转换为模拟信号,这在音频处理和波形生成中发挥着关键作用。
DAC的主要应用场景包括:
音频处理:STM32的DAC模块支持立体声音频输出,可以应用于各种音频应用,如安全警报系统、蓝牙耳机、发声玩具、答录机、人机接口以及低成本的音乐播放器等。通过配置适当的引脚和外设,STM32能够方便地实现音频信号的生成和播放。
波形生成:DAC还可以用于生成各种模拟波形,包括正弦波、方波等。例如,通过配置DAC输出正弦波,可以应用于科学实验、教育演示等领域,作为刺激源来测试听觉系统或其他系统的响应。此外,通过数学运算准备数字模式的波形数据,STM32能够生成高质量的正弦波形,用于精确的测量和控制应用。
模拟控制:除了音频和波形生成,DAC还可用于各种需要模拟信号控制的场景,如电机控制、温度调节、灯光亮度调整等。通过输出不同的模拟电压,可以实现对这些设备的精细控制。
二.STM32G474RET6单片机DAC外设特点
DAC 模块是 12 位电压输出数模转换器。DAC 可以8位或12 位模式进行配置,并且可与DMA 控制器配合使用。
STM32G474RET6的DAC(数模转换器)具有以下特点:
- 通道配置
提供7个12位DAC通道,其中3个为缓冲外部输出通道,4个为无缓冲内部通道。
内部通道支持直接连接至片上外设(如运算放大器或比较器),简化电路设计。 - 性能参数
外部通道:最高1MHz输出速率,支持轨到轨输出。
内部通道:最高15MHz输出速率,适合高速信号生成。
支持单端或差分输出模式,灵活适配不同应用场景。 - 功能特性
集成硬件加速的DMA传输,实现高效数据流处理。
支持与定时器同步触发,确保精确时序控制(如PWM波形生成)。
内置偏移补偿和增益校准功能,提升输出精度。 - 应用优势
可直接驱动外部负载或配合运算放大器构建模拟电路(如程控放大器)。
在电机控制、电源管理等场景中,与PWM、ADC协同实现闭环控制。
三.STM32单片机DAC内部结构图
DAC内部结构图如下
DAC相关引脚说明
四.STM32单片机DAC基本操作
DAC 通道使能
将 DAC_CR 寄存器中的相应 ENx 位置 1,即可接通对应 DAC 通道。经过一段启动时间
tWAKEUP 后,DAC 通道被真正使能。
DAC 转换
DAC_DORx 无法直接写入,任何数据都必须通过加载 DAC_DHRx 寄存器(写入
DAC_DHR8Rx、DAC_DHR12Lx、DAC_DHR12Rx、DAC_DHR8RD、DAC_DHR12LD 或DAC_DHR12LD)才能传输到 DAC 通道 x。
DAC 输出电压
经过线性转换后,数字输入会转换为 0 到 VREF+ 之间的输出电压。
各 DAC 通道引脚的模拟输出电压通过以下公式确定:
程序中调用Hal库代码,以下关键语句就能使PA4引脚输出1.65V直流电压值。
MX_DAC1_Init();//PA4作为DAC1_OUT1输出引脚HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,2048);//DAC引脚输出电压值为2048*3300/4096HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);//使能DAC1通道1
DAC 输出正弦波
有了DAC输出电压值,通过定时器将预先生成的正弦波数据表,按定时器触发频率逐点写入DAC寄存器,形成连续模拟信号,这样就形成了正弦波的波形。
以下关键语句就是使PA4引脚输出正弦波,在定时器中断时间触发DAC输出正弦波数据表格里的电压值。
//60个点为1个周期,所以如果需要产生1KHZ的正弦波,定时器中断频率就是60KHZ,如果定时器时钟是170MHZ,所以htim2.Init.Period就要改成2832(2833.3-1)
#define TABLE_SIZE 60 // 正弦波表的大小,决定了正弦波的分辨率和频率精度
uint16_t sinewave[TABLE_SIZE] = {
0x07ff,0x08cb,0x0994,0x0a5a,0x0b18,0x0bce,0x0c79,0x0d18,0x0da8,0x0e29,0x0e98,0x0ef4,0x0f3e,0x0f72,0x0f92,0x0f9d,
0x0f92,0x0f72,0x0f3e,0x0ef4,0x0e98,0x0e29,0x0da8,0x0d18,0x0c79,0x0bce,0x0b18,0x0a5a,0x0994,0x08cb,0x07ff,0x0733,
0x066a,0x05a4,0x04e6,0x0430,0x0385,0x02e6,0x0256,0x01d5,0x0166,0x010a,0x00c0,0x008c,0x006c,0x0061,0x006c,0x008c,
0x00c0,0x010a,0x0166,0x01d5,0x0256,0x02e6,0x0385,0x0430,0x04e6,0x05a4,0x066a,0x0733};
//定时器溢出中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) // 定时器中断服务例程
{uint16_t sineValue = sinewave[SineTableIndex]; // 获取当前正弦波值if (htim->Instance == TIM2) // 检查是否是TIM2的溢出中断{HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, sineValue); // 设置DAC输出值SineTableIndex = (SineTableIndex + 1) % TABLE_SIZE; // 更新索引,实现循环更新正弦波值}
}
五.CubeMX配置一个DAC输出电压例程
1.硬件准备
STLINK接STM32G474RET6开发板,STLINK接电脑USB口,万用表一个,板子用5V USB线供电。
2.创建CubeMX工程
如下图所示,打开STM32CubeMX软件,新建工程。
如下图所示,Part Number处输入STM32G474RE,再双击就创建新的工程。
如下图所示,配置下载口引脚,PA13为SWD的SWDIO脚,PA14为SWD的SWCLK脚。
如下图所示,配置DAC1,PA4引脚为DAC1通道1。
如下图所示,配置系统主频170Mhz,使用内部16MHZ晶振。
如下图所示,配置工程文件名,保存路径,KEIL5工程输出方式。
如下图所示,生成工程。
如下图所示,增加代码,实现PA4引脚输出1.65V电压。
主要代码如下
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();//SysTick配置成1ms中断/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//16M内部晶振,170MHZ系统主频/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DAC1_Init();//PA4作为DAC1_OUT1输出引脚/* USER CODE BEGIN 2 */HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,2048);//DAC引脚输出电压值为2048*3300/4096HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);//使能DAC1通道1/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
3.实验效果
下载完程序后,用万用表量PA4引脚电压,可以看到电压值1.646V。
六.CubeMX配置一个DAC输出1KHZ正弦波例程
1.硬件准备
STLINK接STM32G474RET6开发板,STLINK接电脑USB口,示波器一台,板子用5V USB线供电。
2.创建CubeMX工程
跟前面的DAC输出电压工程创建方式一样,配置DAC输出,只需要添加一个定时器2中断,以下配置定时器中断频率为60KHZ。
配置定时器2中断使能。
如下图所示,增加代码,添加正弦波数据表。
如下图所示,启动TIM2与DAC输出。
主要代码如下
//60个点为1个周期,所以如果需要产生1KHZ的正弦波,定时器中断频率就是60KHZ,如果定时器时钟是170MHZ,所以htim2.Init.Period就要改成2832(2833.3-1)
#define TABLE_SIZE 60 // 正弦波表的大小,决定了正弦波的分辨率和频率精度
uint16_t sinewave[TABLE_SIZE] = {
0x07ff,0x08cb,0x0994,0x0a5a,0x0b18,0x0bce,0x0c79,0x0d18,0x0da8,0x0e29,0x0e98,0x0ef4,0x0f3e,0x0f72,0x0f92,0x0f9d,
0x0f92,0x0f72,0x0f3e,0x0ef4,0x0e98,0x0e29,0x0da8,0x0d18,0x0c79,0x0bce,0x0b18,0x0a5a,0x0994,0x08cb,0x07ff,0x0733,
0x066a,0x05a4,0x04e6,0x0430,0x0385,0x02e6,0x0256,0x01d5,0x0166,0x010a,0x00c0,0x008c,0x006c,0x0061,0x006c,0x008c,
0x00c0,0x010a,0x0166,0x01d5,0x0256,0x02e6,0x0385,0x0430,0x04e6,0x05a4,0x066a,0x0733};/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */uint16_t SineTableIndex = 0; // 正弦波表的索引,用于循环更新正弦波值//定时器溢出中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) // 定时器中断服务例程
{uint16_t sineValue = sinewave[SineTableIndex]; // 获取当前正弦波值if (htim->Instance == TIM2) // 检查是否是TIM2的溢出中断{HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, sineValue); // 设置DAC输出值SineTableIndex = (SineTableIndex + 1) % TABLE_SIZE; // 更新索引,实现循环更新正弦波值}
}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();//16M内部晶振,170M系统主频/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DAC1_Init();//DAC1初始化,PA4:DAC1_OUT1MX_TIM2_Init();//定时器2初始化,中断频率为60KHZ/* USER CODE BEGIN 2 */if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK)//启动定时器2,并使能溢出中断{/* Counter enable error */Error_Handler();}HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);//使能DAC1通道1/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
3.实验效果
下载完程序后,用示波器测量PA4引脚波形,可以看到1KHZ的正弦波。
七.小结
DAC外设是STM32单片机开发中的基本操作,学会了DAC,单片机就可以在波形输出,音频驱动,模拟控制等场合发挥作用。