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.若实验现象与推理不一致,一定要认真分析程序。