10-stm32外设DAC学习

 

前言


         本系列,将stm32常用片上外设进行整理,包括大致原理和代码,主要是熟悉如何根据手册去编写代码。便于以后需要做实验时,能够快速编写基本的驱动,然后编写应用代码。

        本系列基于“标准库”整理,开发板用的是正点原子精英版V1.5,单片机是STM32F103ZET6。开发工具KEIL。主要参考资料有《STM32F103xCDE中文参考手册》《STM32F103xCDE中文数据手册》、《CM3权威指南》、《STM32F103xCDE闪存编程手册》、《精英版原理图V1.5》。

》《STM32F1xx Cortex-M3编程手册-英文版》

 

        本文用到的手册有《STM32F103xCDE中文参考手册》《STM32F103xCDE中文数据手册》讲解STM32F1的DAC框图和配置实验,实现配置DAC1,在PA4上输出不同电压。至于双DAC、产生噪声,三角波等功能暂时不说。

一、DAC介绍

        DAC是数字转模拟量的模块,通过软件写入数字,输出对应的电压。STM32F1的DAC的数字部分支持8位或者12位,由于12位是放在32位的低16位里面的寄存器里面的,STM32的寄存器只支持字操作,或者半字操作,所以12位放在了16位的内存里面,从而有左对齐和右对齐的区别,这个也就是软件写数据寄存器时有区别,影响不大。

二、STM32F1的DAC框图

在《STM32F103xCDE中文参考手册》的12.2DAC主要特征,有如下框图此框图在一眼看去,比ADC框图简单了不少,事实上也确实简单了很多,选择好触发源,配置好控制寄存器,就可以往DHRx中写入数字量,从而DAC_OUTx引脚上就会出现相应的电平。

6b83c1dfde394e39b1eaa612e0f9de73.png

        如上图中备注,只能写DHRx而不能直接写DORx,硬件会自动延时后传入DORx,此说明在《STM32F103xCDE中文参考手册》12.3.3DAC数据格式,有如下说明。

0df40035d4da45f186d6210804583616.png

 

三、DAC实验

1.查找资料

        在《STM32F103xCDE中文数据手册》的引脚定义一节,通过Ctrl+F,搜索DAC得知, DAC_OUT1是映射到PA4,DAC_OUT1是映射到PA5。

812fad54abd942dfab0bcea102b7453c.png

在《STM32F103xCDE中文参考手册》的8.1.11外设的GPIO配置,表29ADC/DAC配置,知道PA4需要配置为模拟输入模式

10afd7c927b14bc094bbe63c0df7ba64.png

2.编码

        查看DAC寄存器,发现主要介绍SWTRIG一个软件触发使能寄存器,CR控制寄存器,其余的都是DHR寄存器,即我们将数字量写入DHR中,从而在PA4或者PA5上输出对应的电压。

fe4512aabc574111a3d16351207f3bf0.png

        CR寄存器如下:TSEL1是DAC1的触发源选择位,TEN1是DAC1的触发使能位,BOFF1是DAC1的通道输出缓存使能位,EN1是DAC1的使能DAC1位。

5b4c973f25aa47a6a28351b89f9ce078.png

 

SWTRIG软件触发使能寄存器如下图:本次实验就是使用软件触发,所以需要置位SWTRIG1。

816165c21282469bbabc442fae8c2e59.png

本次实验初始化DAC1后,在PA4上输出想要的电压。

void dac1_init(void)
{
  
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitType;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );	  //使能PORTA通道时钟
   	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );	  //使能DAC通道时钟 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				 // 端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 		 //模拟输入
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_4)	;//PA.4 输出高
					
	DAC_InitType.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能 TEN1=0
	DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
	DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;	//DAC1输出缓存关闭 BOFF1=1
    DAC_Init(DAC_Channel_1,&DAC_InitType);	 //初始化DAC通道1

	DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1
  
    DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值

}

int  main(void)
{

    uint32_t dacval = 0;

    dac1_init();

    while(1)
    {
        if(dacval == 0)
        {    
             dacval = 1234;
             DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值,模拟量 = 数字量*分辨率。
        }

    }

}


计算公式:模拟量 = 数字量*分辨率。分辨率=Vref/2^DAC位数-1,如我们这里板子上一般Vref接3.3V的参考电压,DAC使用12位,那么分辨率=3.3/4095。除以4095而不是4096是因为寄存器是12位的最大只能表示4095,当数字量=4095时,模拟量=3.3刚好是最大值,当数字量=0时,模拟量=0。刚好数字量从0增加到4095时,模拟量从0V上升到3.3V。

 

四、总结

        DAC但输出还是挺简单的,要用来输出三角波,双DAC,还得做具体实验时再来研究。总体来说比ADC简单许多,转换公式一点要记住。模拟量 = 数字量*分辨率,这个公式在ADC里面是一样。ADC是读取出数字量来计算模拟量,而DAC知道模拟量来计算数字量。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值