微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 用STM32做了一个TIM+DMA的DAC波形发生器,无波形输出,烦大神...

用STM32做了一个TIM+DMA的DAC波形发生器,无波形输出,烦大神...

时间:10-02 整理:3721RD 点击:
#include"stm32f10x_lib.h"
#include"stm32f10x_flash.h"
#include"stm32f10x_usart.h"
#define DAC1_D0R1_Address    ((u32)0x40012400+0x2c)
#define DAC2_DOR2_Address    ((u32)0x40012400+0x30)
u32 DAC1_ConvertedValue[32];
u32 DAC2_ConvertedValue[32];
/*
*/
/*********************************************************************
*函數名:RCC_DAC_Init(void)
*描述  :時鐘配置
*輸入  :無
*輸出  :無
*調用  :內部調用
**********************************************************************/
void RCC_Configuration(void)
{   
    ErrorStatus HSEStartUpStatus;  
    // RCC system reset(for debug purpose)
    RCC_DeInit();           7
    // Enable HSE */   
    RCC_HSEConfig(RCC_HSE_ON);   
    // Wait till HSE is ready   
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    if(HSEStartUpStatus == SUCCESS)
    {  
            // Enable Prefetch Buffer  
            FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  
            FLASH_SetLatency(FLASH_Latency_2);  
            RCC_HCLKConfig(RCC_SYSCLK_Div1);   
            // PCLK2 = HCLK
            RCC_PCLK2Config(RCC_HCLK_Div1);  
               //PCLK1 = HCLK
            RCC_PCLK1Config(RCC_HCLK_Div2);   
            // PLLCLK = 8MHz * 9 = 72 MHz   
            RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_3);   
            //Enable PLL   
            RCC_PLLCmd(ENABLE);   
            // Wait till PLL is ready //
            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  
            {  
            }  
            //Select PLL as system clock source  
            RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  
            // Wait till PLL is used as system clock source
            while(RCC_GetSYSCLKSource() != 0x08)
            {
            }
    }      
    //Enable peripheral clocks -------------------------------------------------
       //DMA clock enable   
       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
       //AFIO and GPIOA Periph clock enable  
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
       //DAC Periph clock enable  
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);  
       //TIM8 Periph clock enable   
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);  
}
/*
*/
/*********************************************************************
*函數名:void TIM6_Configuration(void)
*描述  :計時器配置
*輸入  :無
*輸出  :無
*調用  :內部調用
**********************************************************************/
void TIM6_Configuration(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
    TIM_DeInit(TIM6);
    //根据音频采样率为44.1khz所以定时器设为2.26us触发DMA
    //下一個更新事件裝入活動的自動重裝寄存器週期的值
    TIM_TimeBaseStructure.TIM_Period = 1633;
    //預分頻值 ,部位零時輸出始終需除以  TIM_Prescaler   
    TIM_TimeBaseStructure.TIM_Prescaler = 0;  
    //时钟分频   
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_div1;  
     //向上计数方式   
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    //根據TimeBaseStructure中指定的参数初始化TIMx 的时间基数单位
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
     //清除待處理標誌位
    TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE);   
    TIM_Cmd(TIM6, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:GPIO_DAC_Init(void)
*描述  :DAC引腳配置
*輸入  :無
*輸出  :無
*調用  :內部調用
**********************************************************************/
void GPIO_DAC_Init(void)
{
       GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
       //端口配置
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
    //模擬輸出   
       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
    //50Hz     
       GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    //初始化端口  
       GPIO_Init(GPIOA,&GPIO_InitStructure);
    //將DAC端口初始化后設置為高電平   
       GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);  
}
/*
*/
/*********************************************************************
*函數名:DAC_All——Init
*描述  :DA轉換相關端口時鐘配置
*輸入  :無
*輸出  :無
*調用  :內部調用
**********************************************************************/
void DAC_All_Init(void)
{
        
       //定義一個結構體
       DAC_InitTypeDef DAC_InitType;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
   
   
    //选择定时器6作外部触发源
       DAC_InitType.DAC_Trigger = DAC_Trigger_T6_TRGO;
    //無波形產生
       DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
    //DAC輸出緩衝使能
       DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;  
       DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable;
    // 初始化DAC1、DAC2
       DAC_Init(DAC_Channel_1|DAC_Channel_2,&DAC_InitType);
    //設置數據右對齊,轉換值設置為0  
       DAC_SetChannel1Data(DAC_Align_12b_R,0);      
    //設置數據右對齊,轉換值設置為0   
       DAC_SetChannel2Data(DAC_Align_12b_R,0);  
    DAC_Cmd(DAC_Channel_1|DAC_Channel_2,ENABLE);
    //DAC的DMA傳輸
    DAC_DMACmd(DAC_Channel_1,ENABLE);
       DAC_DMACmd(DAC_Channel_2,ENABLE);
}
/*
*/
/*********************************************************************
*函數名:DMA_DAC_Init(void)
*描述  :配置DAC的DMA傳輸方式
*輸入  :無
*輸出  :無
*調用  :內部調用
**********************************************************************/
void DMA_DAC_Init(void)
{
       DMA_InitTypeDef DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
   
    /* DMA通道配置*/
    DMA_DeInit(DMA2_Channel3);
    //DMA外設基DAC1地址
    DMA_InitStructure.DMA_PeripheralBaseAddr = DAC1_D0R1_Address;
    //DMA内存基地址     
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DAC1_ConvertedValue;   
    //外設作為數據傳輸的目的地  
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;              
    //定義DMA緩存的大小   
    DMA_InitStructure.DMA_BufferSize =32*16;                              
    //外设寄存器地址固定
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;      
    //内存地址固定
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;            
    //設定外設的數據寬度為半字(16位)
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    //設定外設的數據寬度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    //循环传输
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                  
    //設置通道11的優先級為高
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;               
    //申明非內存到內存傳輸
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;         
    DMA_Init(DMA2_Channel3, &DMA_InitStructure);
    DMA_Cmd(DMA2_Channel3, ENABLE);
    DAC_DMACmd(DAC_Channel_1, ENABLE);
       /**************/
    /* DMA通道配置*/
    DMA_DeInit(DMA2_Channel4);
    //DMA外設基DAC2地址
    DMA_InitStructure.DMA_PeripheralBaseAddr = DAC2_DOR2_Address;
    //DMA内存基地址      
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DAC2_ConvertedValue;  
    //外設作為數據傳輸的目的地   
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;               
    //定義DMA緩存的大小  
    DMA_InitStructure.DMA_BufferSize =32*16;                              
    //外设寄存器地址固定
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;      
    //内存地址固定
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;            
    //設定外設的數據寬度為半字(16位)
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    //設定外設的數據寬度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    //循环传输
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                 
    //設置通道11的優先級為高
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;               
    //申明非內存到內存傳輸
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;         
    DMA_Init(DMA2_Channel4, &DMA_InitStructure);
   
  
    //使能DMA
    /* Enable DMA channel1 */
    DMA_Cmd(DMA2_Channel4, ENABLE);
    DAC_DMACmd(DAC_Channel_2, ENABLE);
}
/*
*/
/*********************************************************************
*函數名:void DAC_DMA_TIM_Config(void)
*描述  :配置DAC的工作方式
*輸入  :無
*輸出  :無
*調用  :外部調用
**********************************************************************/
void DAC_DMA_TIM_Config(void)
{
  RCC_Configuration();
  TIM6_Configuration();
  GPIO_DAC_Init();
  DMA_DAC_Init();
  DAC_All_Init();
}
主程序主要操作是在DAC2_ConvertedValue[32]数组中加入数据
,然后调用  DAC_DMA_TIM_Config()函数初始化DAC  
只有开机时输出一个周期的波形,后续均没有波形,求大神指点啊  

看都没人看一眼吗?

看了好几眼了,但自己真心不是大神,同志你要努力啊!

感谢你看了 好几眼,目前已经解决了 大致是外设地址定义错误,还有线初始化DAC在初始化GPIO 貌似是这样的 波形目前测量到了,具体还未调整,搞了这么久,终于有点进步,欣喜若狂

请问有源码吗 我也在做这个  好头疼  好多都不太会

上面已经说得很清楚了  稍微改下就可以了  你试试

上面已经说得很清楚了  稍微改下就可以了  你试试

“还有线初始化DAC在初始化GPIO”,小编,这个顺序有问题么?不都是先初始化GPIO在初始化DAC么?

是的,这是必须的

#define DAC1_D0R1_Address    ((u32)0x40012400+0x2c)
#define DAC2_DOR2_Address    ((u32)0x40012400+0x30)
DOR1,DOR2 是禁止用户写的,你地址用错了,具体要用DAC_DHR12R2_ADDR这类的地址,手册有说明

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top