STM32F4xxx系列 - DAC生成噪声波

目标:利用定时器5(周期为5ms),从DAC1通道产生一个噪声波。
涉及知识:DAC原理、stm32中的DAC、定时器、DAC输出IO配置

1. DAC原理

DAC,是将数字输入转换成模拟输出,主要有两种实现方式:

  1. 电阻-电位器网络 :通过开关控制不同的电阻分压,生成对应的模拟电压。
  2. 电容-二进制加权 :利用电容的充放电特性,快速生成模拟信号。

2. 二进制加权算法

image

3. STM32F407ZG中的DAC特性

有2个12位的DAC模块,对应输出引脚为PA4、PA5,各2个通道。
1、可选择8/12模式,向左还是向右对齐
2、单通道模式或双通道模式
{B098A18D-7151-4DF9-81BC-FA783917067D}
3、触发方式:
自动触发、定时器触发、外部中断触发
{B10CE36A-B554-45E8-9F3B-2756984D1D43}

3、输出计算方式
{AB969A4A-21A6-4E2D-9A7F-CE972FC0D3B2}

4. 定时器

根据时钟树:
(1)高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11 ----- APB2总线
(2)通用定时器timer2-timer5,timer12-timer14以及基本定时器timer6,timer7 ----- APB1总线

(3)当APB1和APB2分频数为1,时钟频率=原频率

(4)当APB1和APB2分频数不为1,时钟频率=原频率x2

核心计算方式:
Tout = ((arr+1)*(psc+1))/Tclk,arr为预载值,psc为分频值,Tout为时钟频率

本实验使用的tim5挂载在APB1上,16位。

4. 程序配置

4.1DAC配置

在DAC.c文件中创建配置函数
1、DAC输出IO配置
为了避免寄生电流消耗,应首先将 PA4 或 PA5 引脚配置为模拟模式 (AIN)。
2、DAC转换配置
1)使能DAC时钟
2)选择DAC触发方式为timer5触发:
CR-TENx 控制位置 1,可通过外部事件
CR-TSELx[2:0] 决定通过哪一个来触发转换
{23331BD1-41C3-4DC1-AD72-B12B3DD5F02D}
DAC_InitStructure.DAC_Trigger=DAC_Trigger_T5_TRGO;
3)选择在转换后的信号上加上伪噪声
使用 LFSR(线性反馈移位寄存器)。将 WAVEx[1:0] 置为
“01”即可选择生成噪声。
DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_Noise;
4)设置噪声的最大幅值
最大就是12位,拉满3.3v
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bits11_0;
5)关闭输出缓冲
如果不需要驱动外部
6)初始化,将相应寄存器设置好
7)使能打开
完整代码:

void DAC1_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
	
	DAC_InitStructure.DAC_Trigger=DAC_Trigger_T5_TRGO;	//不使用触发功能 TEN1=0
	DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_Noise;//不使用波形发生
	DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bits11_0;//屏蔽、幅值设置
	DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;	//DAC1输出缓存关闭 BOFF1=1
	DAC_Init(DAC_Channel_1,&DAC_InitStructure);	 //初始化DAC通道1
	
	
	
	
	DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC通道1
	DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值
	
}

4.2定时器配置

1)使能时钟
2)设置装载值:arr(不得超过16位无符号)=500-1
3)设置分频值:psc(不得超过16位无符号值)=8400-1
4)计数方式:向上计数
5)初始化
6)打开使能

完整代码:

void Tim5_Init(uint16_t arr, uint16_t psc)
{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

    TIM_TimeBaseInitStructure.TIM_Period = arr;

    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);

    TIM_Cmd(TIM5, ENABLE);

}

4.3定时器触发

定时器的框图中有一个TRGO信号输出,此信号可以用来触发ADC、DAC、其他定时器等。
image

TIM_SelectOutputTrigger
这个函数TIMx_CR2寄存器的位6到位4赋值,位6到位4是MMS[2:0],

完整代码:

void TIM5_TriggerInit(void)
{	
	// 定时器TIMx初始化
	// TIM5_Int_Init 函数已经设置好了主模式定时器TIMx的周期arr
	
	// TIMx触发其他模块的功能设置
	// TIM_SelectMasterSlaveMode(TIM5, TIM_MasterSlaveMode_Enable);    // 设置定时器的主从模式
	                                                                // 设置定时器5为主模式
	TIM_SelectOutputTrigger(TIM5, TIM_TRGOSource_Update);    //设置TIME输出触发为更新模式
}


实验1:bits11_0
_cgi-bin_mmwebwx-bin_webwxgetmsgimg__&MsgID=295027844866752088&skey=@crypt_cb51e609_53f6db05b7ce21f5871ecbd847e61b63&mmweb_appid=wx_webfilehelper

实验2:bits5_0
_cgi-bin_mmwebwx-bin_webwxgetmsgimg__&MsgID=7788708451097938682&skey=@crypt_cb51e609_53f6db05b7ce21f5871ecbd847e61b63&mmweb_appid=wx_webfilehelper

posted @ 2025-12-26 16:19  树上掉下一只鱼  阅读(52)  评论(0)    收藏  举报