专栏中心

EEPW首页 > 专栏 > STM32之DAC波形输出

STM32之DAC波形输出

发布人:皓曦 时间:2013-08-03 来源:工程师 发布文章

    玩了几天模拟电路,因做程控放大电路,需要输出可调电压,于是转战STM32上来了,采用DMA通道输出DAC,输出为一正弦波。

    DAC配置略显简单,由于悟性不够,部分原因还是不懂。DMA通道传送DAC时,选取DAC_Channnel2程序很好使,而改为DAC_Channnel1时,相应地址等均作改变,但是就是没有波形输出,无果。

   选用TIM2作定时器触发,TIM2在APB1上,最高频率36MHz,预分频系数为1时测出正弦波形频率经换算频率为72MHz,而预分频系数为2时,换算频率为36MHz,正常情况应该相等的,不明所以。查询资料,有博客上说,采用默认库配置,TIM2最高频率可以为72MHz,不理解。于是更改程序,自己配置时钟,预分频系数为1时依然为72MHz,而预分频系数为2时,频率为36MHz,无果


//purpose: DA转换,DAC1->PA4管脚输出转换后的模拟值 ,DAC2->PA5
// 产生正弦波频率= 主频/(TIM_Prescaler+1)/TIM_Period/产生一个正弦波的点数 


#include "stm32f10x.h"


#define DAC_DHR12R2_Address      0x40007414  //相应地址通过数据手册和参考手册去查询


/* Init Structure definition */
DAC_InitTypeDef            DAC_InitStructure;
DMA_InitTypeDef            DMA_InitStructure;
TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;


const uint16_t Sine12bit[32] = {  //数据源用来产生波形
                      2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
                      3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909, 
                      599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};
uint32_t DualSine12bit[32];
uint32_t Idx = 0; 


/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void TIM_Configuration(void);
void DAC_Configuration(void);
void DMA_Configuration(void);
void GPIO_Configuration(void);


int main(void)
{
  
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     
 
  
// System Clocks Configuration 
     RCC_Configuration();   


  /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 
     connected to the DAC converter. In order to avoid parasitic consumption, 
     the GPIO pin should be configured in analog */
     GPIO_Configuration();


     TIM_Configuration();


DAC_Configuration();
 for (Idx = 0; Idx < 32; Idx++)
  {
    DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);   //双通道输出正弦波
  }


     DMA_Configuration();
   
   /* Enable DMA for DAC Channel1 */
     DAC_DMACmd(DAC_Channel_2, ENABLE);


  /* TIM6 enable counter */
     TIM_Cmd(TIM6, ENABLE);


while (1)
  {
  }
}




/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */
void RCC_Configuration(void)
{   
//时钟配置,不使用库默认时钟配置
    ErrorStatus HSEStartUpStatus;  //定义外部高速晶体启动状态枚举变量
    RCC_DeInit();     //复位RCC外部设备寄存器到默认值
    RCC_HSEConfig(RCC_HSE_ON);    //打开外部高速晶振
    HSEStartUpStatus = RCC_WaitForHSEStartUp();   //等待外部高速时钟准备好
    if(HSEStartUpStatus == SUCCESS)    //外部高速时钟已经准别好
    {
      RCC_HCLKConfig(RCC_SYSCLK_Div1);   //配置AHB(HCLK)时钟=SYSCLK
      RCC_PCLK2Config(RCC_HCLK_Div1);    //配置APB2(PCLK2)钟=AHB时钟
      RCC_PCLK1Config(RCC_HCLK_Div2);    //配置APB1(PCLK1)钟=AHB 1/2时钟
      RCC_ADCCLKConfig(RCC_PCLK2_Div4);  //配置ADC时钟=PCLK2 1/4
    
      RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //配置PLL时钟 == 外部高速晶体时钟*9
      RCC_ADCCLKConfig(RCC_PCLK2_Div4);  //配置ADC时钟= PCLK2/4
      RCC_PLLCmd(ENABLE);  //使能PLL时钟
      while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟就绪
       {
       }
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//配置系统时钟 = PLL时钟
 
      while(RCC_GetSYSCLKSource() != 0x08)    //检查PLL时钟是否作为系统时钟
       {
       }
     }


// DMA2 clock enable 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);


  /* GPIOA Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /* DAC Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
   /* TIM2 Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
}


void TIM_Configuration(void)
{
// Time base configuration 
     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 
     TIM_TimeBaseStructure.TIM_Period = 25-1;      //计数周期25    
     TIM_TimeBaseStructure.TIM_Prescaler = 1-1;    //预分频系数1   
     TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;    
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //向上计数
     TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);  
// TIM6 TRGO selection */
     TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); //触发源更新
}


void DAC_Configuration(void)
{
// DAC channel1 Configuration 
     DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; //DAC触发  TIM6触发
     DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; //不使用内部波形发生器
     DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;   //关闭外部输出缓存
     DAC_Init(DAC_Channel_1, &DAC_InitStructure);  //用DAC输出波形,传输的数据比较多,所以采用DMA传输可以节省CPU的开支
DAC_Init(DAC_Channel_2, &DAC_InitStructure);
// Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is automatically connected to the DAC converter
     DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_Cmd(DAC_Channel_2, ENABLE);


}
void DMA_Configuration(void)
{
 DMA_DeInit(DMA2_Channel4);   //将dma的通道寄存器设为默认值


      DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R2_Address;  //定义dma外设基地址 
      DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sine12bit;
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //外设作为数据传输的目的地 
      DMA_InitStructure.DMA_BufferSize = 32;  //dma缓存大小 
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器 递增
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度 
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环缓存模式,数据传输数目为0时,自动恢复配置初值 
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //通道未被设置成内存到内存模式,与循环模式相对


      DMA_Init(DMA2_Channel4, &DMA_InitStructure);  //将DMA_InitStructure中指定的参数初始化dma的通道寄存器 
// Enable DMA2 Channel4 
      DMA_Cmd(DMA2_Channel4, ENABLE);  //使能通道 
}


/**
  * @brief  Configures the different GPIO ports.
  * @param  None
  * @retval None
  */
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;


  /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 
     connected to the DAC converter. In order to avoid parasitic consumption, 
     the GPIO pin should be configured in analog */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4|GPIO_Pin_5;  //一旦DAC通道使能,相应的GPIO PA4,PA5自动与DAC的模拟输出相连,
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //为了避免避免寄生的干扰和额外的功耗,PA4 置成模拟输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}



专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词:

相关推荐

2010年英特尔杯大学生嵌入式设计大赛宣传片 ②

视频 2010-03-26

CRC 校验源码分析

资源下载 2007-02-16

大连Moblin研讨会视频 II

视频 2010-04-19

crc16 another one

资源下载 2007-02-16

LimX筹集2亿美元用于构建具身智能

机器人技术将颠覆人工智能基础设施:未来之路何在

ComCapture 1.0

别监管人工智能模型,要监管人工智能的使用

CAN应用

IDF 2010 MeeGo展区QT介绍

视频 2010-04-19

利用高压母线转换模块 (BCM) 为LED驱动器供电

视频 2010-04-16

cajviewer软件

资源下载 2007-02-16

Material公司的电池为每个角落提供电力

TACC借助 Horizon 系统探索高性能计算混合精度与 FP64 仿真技术

莫悲观,车企迎来盈利增长转折点

汽车电子 2026-02-04

IEEE审议神经科技消费品的安全指南

类脑计算机也能做数学

2010年英特尔杯大学生嵌入式设计大赛宣传片 ③

视频 2010-03-26

“漏音”6G芯片技术击败了狭窄的太赫兹束限制

Gartner再度预测人工智能支出趋势

更多 培训课堂
更多 焦点
更多 视频

技术专区