zsign.c
#include "zsign.h"
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
//信号初始化
void Sign_Init(u32 Wave1_Fre)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); //开DAC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开引脚端口时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开定时器时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); //开启DMA2时钟
//引脚初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;//DAC1-》PA4 ; DAC2-》PA5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//DAC初始化
DAC_StructInit(&DAC_InitStructure); //DAC结构体初始化
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Triangle; //输出波形是三角波
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_2047; //DAC1输出大约是0-1.65V
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; //定时器2触发,没触发一次产生一次DAC里的值加1,从0加到2047,再从2047减至0,循环往复
DAC_Init(DAC_Channel_1,&DAC_InitStructure);
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1023; //DAC2输出大约是0-0.825V
DAC_Init(DAC_Channel_2,&DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE);//打开DAC的CH1
DAC_Cmd(DAC_Channel_2, ENABLE);//打开DAC的CH2
DAC_SetDualChannelData(DAC_Align_12b_R, 0x00, 0x00);//设置DAC两个通道的数据右对齐,波谷对应的数字量风别为0,0
//时钟初始化
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
TIM_TimeBaseInitStructure.TIM_Prescaler = 0x0; //不分频,是72Mhz
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0x0; //不分频,是72Mhz
TIM_TimeBaseInitStructure.TIM_Period = Wave1_Fre;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update); //设置TIME输出触发为更新模式
TIM_Cmd(TIM2, ENABLE); //开启定时器
}
/*
生成三角波的关键就在这个代码里了。首先是要设置DAC的触发源为TIM2,并设置DAC生成的波形为三角波。DAC完全可以自己生成三角波,而不用借助DMA。接下去设置DAC的CH1的幅值为2047,CH2的幅值为1023。
要知道DAC是12位的,它的最高数字量为4095,所以通道1输出的三角波型对应的数字量会随着定时器更新从0~2747增加,在从2047~0减少;通道2输出的三脚波对应的数字量会随着定时器更新从0~1023增加,再从1023~0减少。
最后在设置DAC的谷值为0。如果参考电压为3.3v,那么通道1的波形就会从0v~1.65v增加,再从1.65v~0v减少;通道1的波形就会从0~0.825v增加,在从0.825~0减少,这样的话就形成了三角波了。
还要有一点要说的,上面代码中,DAC_SetDualChannelData(DAC_Align_12b_R, 0x00, 0x00);这句话很重要,它的意思是设置DAC的两个通道的数据右对齐,并且设置两路通道的波形的波谷为0。
如果我们这样设置:DAC_SetDualChannelData(DAC_Align_12b_R, 0xFF, 0xFF),设置波谷的数字量为0xff,那么波形就会抬高0xff对应的电压0.2v左右。
还要讲讲输出三角波的频率是怎么计算的,定时器的时钟为72M,它设置的周期为100,DAC的CH1的幅值设置成2047,DAC的CH2的幅值设置成1023,那么就可以计算出输出两路三角波的频率了:
CH1输出频率 = 72M / 100 / 2048 / 2 = 175.8Hz
CH2输出频率 = 72M /100 / 1024 / 2 = 351.6Hz
*/
zsign.h
#ifndef _zsign_H
#define _zsign_H
#include "system.h"
void Sign_Init(u32 Wave1_Fre);
#endif
main.c
#include "system.h"
#include "SysTick.h"
#include "led.h"
//#include "usart.h"
#include "zsign.h"
int main()
{
SysTick_Init(72);
LED_Init();
//USART1_Init(9600);
Sign_Init(100); //信号初始化
while(1)
{
}
}