新闻  |   论坛  |   博客  |   在线研讨会
STM32之DAC波形输出
皓曦 | 2013-08-03 10:44:31    阅读:30887   发布文章

    玩了几天模拟电路,因做程控放大电路,需要输出可调电压,于是转战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);
}



*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
嵌入式,计算机,电子信息,运动,旅游
最近文章
2013-08-31
2013-08-31 09:49:48
2013-8-27
2013-08-27 17:44:06
STM32之DAC波形输出
2013-08-03 10:44:31
推荐文章
最近访客