STM32F4xxx系列 - DAC生成噪声波

目标:利用定时器5(周期为5ms),从DAC1通道产生一个噪声波。

涉及知识:DAC原理、stm32中的DAC、定时器、DAC输出IO配置

1. DAC原理

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

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

2. 二进制加权算法

3. STM32F407ZG中的DAC特性

有2个12位的DAC模块,对应输出引脚为PA4、PA5,各2个通道。

1、可选择8/12模式,向左还是向右对齐

2、单通道模式或双通道模式

3、触发方式:

自动触发、定时器触发、外部中断触发

3、输出计算方式

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] 决定通过哪一个来触发转换

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)打开使能

完整代码:

c 复制代码
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、其他定时器等。

TIM_SelectOutputTrigger

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

完整代码:

c 复制代码
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

实验2:bits5_0

相关推荐
✧˖‹gσσ∂ иιghт›✧3 小时前
stm32 cube max+keil5的环境怎么printf重定向
stm32·单片机·嵌入式硬件
xingzhemengyou15 小时前
STM32 时钟树
stm32·单片机
无聊到发博客的菜鸟5 小时前
STM32 手册寄存器属性
stm32·单片机·嵌入式·rtos·寄存器
tengtext5 小时前
单片机mcu(stm32)计算生成二维码
stm32·单片机·嵌入式硬件
玩嵌入式的菜鸡6 小时前
stm32bootloader跳到app无法运行问题
stm32·单片机·嵌入式硬件
无聊到发博客的菜鸟7 小时前
STM32 RTC时钟不准的问题
stm32·嵌入式·rtc·rtos
boneStudent7 小时前
Day41:四轴飞行器控制系统 (基础)
stm32·单片机·嵌入式硬件
曾浩轩8 小时前
跟着江协科技学STM32之3-3GPIO输入
科技·stm32·嵌入式硬件