STM32学习笔记(二十四)DAC数模转换实验

本文详细介绍了基于STM32F103ZET6的DAC数模转换实验,从原理到配置,再到程序实现。通过库函数版本操作,展示了如何设置DAC输出电压,并通过按键控制电压变化。实验中还涉及了ADC读取,实现了电压的实时显示。
摘要由CSDN通过智能技术生成

STM32F103ZET6之DAC数模转换实验



前言

对于STM32的学习可分为3个版本。
1.寄存器版本
2.库函数版本
3.HAL库版本
由于个人原因,选择库函数版本来进行STM32的学习。


提示:软件安装等问题,不进行讲解!!!

一、原理

1.简介

STM32 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的 DAC。 DAC 可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。 DAC 工作在 12 位模式时,数据可以设置成左对齐或右对齐。 DAC 模块有 2 个输出通道,每个通道都有单独的转换器。在双 DAC模式下, 2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。DAC 可以通过引脚输入参考电压 VREF+以获得更精确的转换结果。

STM32 的 DAC 模块主要特点有:
① 2 个 DAC 转换器:每个转换器对应 1 个输出通道
② 8 位或者 12 位单调输出
③ 12 位模式下数据左对齐或者右对齐
④ 同步更新功能
⑤ 噪声波形生成
⑥ 三角波形生成
⑦ 双 DAC 通道同时或者分别转换
⑧ 每个通道都有 DMA 功能

2.ADC通道与引脚关系

在这里插入图片描述

3.原理图

在这里插入图片描述
硬件连接图
在这里插入图片描述

二、相关配置

1.相关寄存器

在这里插入图片描述

2.输入与输出关系

在这里插入图片描述

3.配置步骤

1.开启 PA 口时钟,设置 PA4 为模拟输入
2.使能 DAC1 时钟
3.初始化 DAC,设置 DAC 的工作模式
4.使能 DAC 转换通道
5.设置 DAC 的输出值

三、程序源码

1.dac.h

代码如下:

#ifndef __DAC_H
#define __DAC_H

#include "sys.h"
void Dac1_Init(void);
void Dac1_Set_Vol(u16 vol);

#endif

2.dac.c

代码如下:

#include "dac.h"


void Dac1_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	DAC_InitTypeDef DAC_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);//使能DAC时钟
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_4);//PA4输出为高
	
	DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
	DAC_InitStruct.DAC_OutputBuffer=DAC_OutputBuffer_Disable;//DAC输出缓存关
	DAC_InitStruct.DAC_Trigger=DAC_Trigger_None;//不使用触发功能
	DAC_InitStruct.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	DAC_Init(DAC_Channel_1, &DAC_InitStruct);
	
	DAC_Cmd(DAC_Channel_1,ENABLE);//使能ADC
	
	DAC_SetChannel1Data(DAC_Align_12b_R, 0);//12位右对齐,初值设置为0
}
//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void Dac1_Set_Vol(u16 vol)
{
	float temp=vol;
	temp/=1000;
	temp=temp*4096/3.3;
	DAC_SetChannel1Data(DAC_Align_12b_R,temp);
}

3.main.c

代码如下:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "adc.h"
#include "dac.h"
#include "usmart.h"

 int main(void)
 {	 
	u16 adcx;
	float temp;
	u8 t=0;
	u16 dacval=0;
  u8 key;	 
	 
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	LED_Init();			     //LED端口初始化
	LCD_Init();
	KEY_Init();
	usmart_dev.init(72);
	Adc_Init();
	Dac1_Init();
	 
	POINT_COLOR=RED;//设置字体为红色
	LCD_ShowString(60,50,200,16,16,"chen");
	//显示提示信息
	POINT_COLOR=BLUE;//设置字体为蓝色
	LCD_ShowString(60,150,200,16,16,"DAC VAL:");	
	LCD_ShowString(60,170,200,16,16,"DAC VAL:0.000V");
	LCD_ShowString(60,190,200,16,16,"ADC VAL:0.000V");
	 
	DAC_SetChannel1Data(DAC_Align_12b_R, 0);
	
	while(1)
	{
		t++;
		key=KEY_Scan(0);
		if(key==WKUP_PRES)
		{
			LED1=!LED1;
			if(dacval<4000) dacval+=200;
			DAC_SetChannel1Data(DAC_Align_12b_R, dacval);
		}
		else if(key==KEY1_PRES)
		{
			if(dacval>200) dacval-=200;
			else dacval=0;
			DAC_SetChannel1Data(DAC_Align_12b_R, dacval);
		}
		if(t==10||key==KEY1_PRES||key==WKUP_PRES)
		{
			adcx=DAC_GetDataOutputValue(DAC_Channel_1);
			LCD_ShowxNum(124,150,adcx,4,16,0);
			temp=(float)adcx*(3.3/4096);
			adcx=temp;
			LCD_ShowxNum(124,170,temp,1,16,0);
			temp-=adcx;
			temp*=1000;
			LCD_ShowxNum(140,170,temp,3,16,0x80);
			adcx=Get_Adc_Average(ADC_Channel_1,10);
			temp=(float)adcx*(3.3/4096);
			adcx=temp;
			LCD_ShowxNum(124,190,temp,1,16,0);
			temp-=adcx;
			temp*=1000;
			LCD_ShowxNum(140,190,temp,3,16,0x80);
			LED0=!LED0;
			t=0;
		}
		delay_ms(10);
	}
}

实验结果

通过按键加减运算来改变输入数字量,从而导致输出电压改变
通过USMART组件,直接调用Dac1_Set_Vol函数,从而直接可以使输出电压为理想值
在这里插入图片描述
在这里插入图片描述


总结

1.看完视频,一定自己写一遍程序。
2.烧写程序前,对程序进行分析,推理实验现象。
3.若实验现象与推理不一致,一定要认真分析程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白正在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值