0%

STM32之ADC生成波形

平台:STM32F103VET6

1、三角波

使用STM32F103 DAC输出三角波,定时器2触发。

PA5,也就是通道2,输出波形:

ykU1eO.png

调整幅值为2047后:

ykUYYd.jpg

在增加1V的DC偏移

ykUUSI.jpg

通道1也可以,但是因为硬件原因,波形不正确。

ykUwOf.png

其输出波形:

ykUBm8.png

2、代码

(1) DAC配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void dac1_init_triangle(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitType;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_5);

DAC_InitType.DAC_Trigger = DAC_Trigger_T2_TRGO;//TIM2 TRGO事件
DAC_InitType.DAC_WaveGeneration =DAC_WaveGeneration_Triangle;
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_2047;
DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_2, &DAC_InitType);

DAC_SetChannel1Data(DAC_Align_12b_R, 0);
DAC_SoftwareTriggerCmd(DAC_Channel_2,ENABLE);
DAC_Cmd(DAC_Channel_2, ENABLE);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
设置输出电压
*/
void dac1_set_vol(float vol)
{
uint16_t data;

if(vol > 3.3)
return;

data = 4096 * vol / 3.3;
DAC_SetChannel2Data(DAC_Align_12b_R, data); //12位右对齐数据格式设置DAC值
}

(2)tim2配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void tim2_init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_DeInit(TIM2);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseStructure.TIM_Prescaler = psc-1; //72MHz分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_Period = arr-1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);//更新事件被选为触发输入(TRGO)
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_Cmd(TIM2,ENABLE);
}

3、原理

内部的三角波计数器每次触发事件之后3个APB1时钟周期后累加1。计数器的值与DAC_DHRx寄存器的数值相加并丢弃溢出位后写入DAC_DORx寄存器。在传入DAC_DORx寄存器的数值小于MAMP[3:0]位定义的最大幅度时,三角波计数器逐步累加。一旦达到设置的最大幅度,则计数器开始递减,达到0后再开始累加,周而复始。

上面这一段摘自《STM32F10xxx参考手册 》,在这里触发事件就是定时器2的TIM_TRGOSource_Update更新事件。所以,更改定时器的PSC与ARR即可改变三角波的周期。比如下图,PSC=6,ARR=1000。

ykUykQ.jpg

另一方面,三角波形的周期还与三角波的幅值有关,比如在上述定时器参数下,幅值变由DAC_TriangleAmplitude_2047变为DAC_TriangleAmplitude_1023,则波形变为:

ykUcfs.jpg

三角波的周期可以这样计算

  • 首先计算定时器触发频率:72M/(PSC+1)/ARR

    这里PSC=5,ARR=1000,72M/(5+1)/1000=12K,那么周期就是1/12K.

  • 三角波周期

    DAC_TriangleAmplitude_2047时,则周期为2047*(1/12K)=170.6ms

    DAC_TriangleAmplitude_1023时,则周期为1023*(1/12K)=85ms

4、噪声

DAC沟通过那样可以产生噪声,只需要将配置中改为

1
2
DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_Noise;
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bits11_0;

波形如下图:

ykUW60.jpg