OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2124|回复: 0

stm32f407DAC+DMA+TIM 输出两路DAC问题

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2023-7-11
在线时间
0 小时
发表于 2023-8-5 00:02:36 | 显示全部楼层 |阅读模式
1金钱
我在使用stm32f407自带的DAC输出波形时,已经成功利用DAC1输出了正弦波,我想在此基础上仿照DAC1的DMA和TIM设计对DAC2进行设计,实现双通道输出不同波形
但结果导致两个通道都没有了输出,源码如下 求各位大佬帮帮忙

#include "dac.h"
#include "led.h"
#include "My.h"

u16  DAC_Datas[Dot_X] = {0};
u16  DAC_2Datas[Dot_X]={0};

#define DAC_DHR12R1_ADDRESS     0x40007408


//DAC通道1输出初始化
void Dac1_Init(void)
{  
  GPIO_InitTypeDef   GPIO_InitStructure;
        DAC_InitTypeDef    DAC_InitStructure;
        DMA_InitTypeDef    DMA_InitStructure;
        NVIC_InitTypeDef   NVIC_InitStructure;
       
       
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); //开DMA时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);  //使能DAC时钟
          
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;            // PA4初始化
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;         //模拟
  GPIO_Init(GPIOA, &GPIO_InitStructure);               //初始化

        DAC_InitStructure.DAC_Trigger = DAC_Trigger_T4_TRGO;           // DAC触发方式4   
        DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;// 不采用波形发生模式
        DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //输出缓冲不使能
        DAC_Init(DAC_Channel_1, &DAC_InitStructure);                   // DAC通道1初始化

        DMA_DeInit(DMA1_Stream5);
        DMA_InitStructure.DMA_Channel = DMA_Channel_7;                  // 数据流选择         
        DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1_ADDRESS; // DAC数据寄存器地址
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&DAC_Datas[0];// 内存地址
        DMA_InitStructure.DMA_BufferSize = Dot_X;                       // 一个周期内的点数
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 传输宽度
        DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                  //DMA 传输模式  循环模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;              //DMA 优先级  高
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
        DMA_Init(DMA1_Stream5, &DMA_InitStructure);                      //DMA初始化函数
       
        DMA_Cmd(DMA1_Stream5, ENABLE);
        DAC_Cmd(DAC_Channel_1, ENABLE);
        DAC_DMACmd(DAC_Channel_1, ENABLE);
}

void Dac2_Init(void)
{  
    GPIO_InitTypeDef   GPIO_InitStructure;
        DAC_InitTypeDef    DAC_InitStructure;
        DMA_InitTypeDef    DMA_InitStructure;
        NVIC_InitTypeDef   NVIC_InitStructure;
       
       
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); //开DMA时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);  //使能DAC时钟
          
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;            // PA4初始化
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;         //模拟
  GPIO_Init(GPIOA, &GPIO_InitStructure);               //初始化

        DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;           // DAC触发方式2  
        DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;// 不采用波形发生模式
        DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //输出缓冲不使能
        DAC_Init(DAC_Channel_2, &DAC_InitStructure);                   // DAC通道2初始化

        DMA_DeInit(DMA1_Stream6);
        DMA_InitStructure.DMA_Channel = DMA_Channel_7;                  // 数据流选择         
        DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1_ADDRESS; // DAC数据寄存器地址
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&DAC_2Datas[0];// 内存地址
        DMA_InitStructure.DMA_BufferSize = Dot_X;                       // 一个周期内的点数
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 传输宽度
        DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                  //DMA 传输模式  循环模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;              //DMA 优先级  高
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
        DMA_Init(DMA1_Stream6, &DMA_InitStructure);                      //DMA初始化函数
       
        DMA_Cmd(DMA1_Stream6, ENABLE);
        DAC_Cmd(DAC_Channel_2, ENABLE);
        DAC_DMACmd(DAC_Channel_2, ENABLE);
}


void TIM4_Int_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);             //使能TIM4时钟
    TIM_TimeBaseInitStructure.TIM_Period = 100000;                           //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc;                    //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Down; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;      
        TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);                                                        //初始化TIM4
        TIM_SelectOutputTrigger(TIM4,TIM_TRGOSource_Update);            //输出触发信号
        TIM_Cmd(TIM4,ENABLE); //使能定时器4
        // 在这里定时器只是作为一个时间基准, 定时器在一个计时周期结束以后会自动的触发一次DMA传输
}

void TIM2_Int_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);             //使能TIM4时钟
    TIM_TimeBaseInitStructure.TIM_Period = 50000;                           //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc;                    //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Down; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;      
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);                                                        //初始化TIM4
        TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);            //输出触发信号
        TIM_Cmd(TIM2,ENABLE); //使能定时器4
        // 在这里定时器只是作为一个时间基准, 定时器在一个计时周期结束以后会自动的触发一次DMA传输
}







#include "My.h"

// 第一个参数是波形种类,第二个是波形的电压峰值  第三个是波形参数的保存位置
void Generate_Wave(u8 Wave_Mode,short Votage_Max,u16 Wave[])
{// 这里的Voltage_Max 一般是4095  也就是DAC转换的最大电压  Vref
                short i = 0;
                float temp;
                short temp2;
                short temp3;
                short temp4;
                switch(Wave_Mode)
                {
                        case Wave_Sin: //  Sin 的 波形       
                        {// 对下列算法进行了优化  注释掉的是未优化的
                               
                                temp = 2*3.14159/Dot_X;//  周期是temp  2*Pi
                                for(i = 0 ; i< Dot_X;i++)
                                {
                                        //Wave[i] = 2048*(sin(2*3.14159*i/Dot_X)+1);
                                        Wave[i] = 0.5*Votage_Max*(sin(temp * i) +1 );//直流信号需要向上一个的偏置
                                }
                                break;
                        }
                       
                        case Wave_Triangular://  三角波
                        {
                                if(Dot_X%2) // 奇数
                                        temp2 = Dot_X/2 + 1;
                                else        // 偶数
                                        temp2 = Dot_X/2;
                                for(i = 0 ; i< temp2;i++)
                                {
                                        Wave[i] = i*Votage_Max/temp2;
                                }
                                for(i = temp2 ; i< Dot_X;i++)
                                {
                                        Wave[i] =Votage_Max - Votage_Max*(i -temp2) /temp2;
                                }
                                break;
                        }
                       
                }
}







main.c
#include "My.h"
#include "key.h"
#include <stdio.h>

// ARR = f_clk / ((PSC + 1) * freq * N)
#define f_clk 78000000
#define PSC 5
//freq = f_clk / ((PSC + 1) * ARR * N)

short Votage_Max = 0xfffff; //  电压最大值3.3V 12位的精度
//  以上参数主要是给 波形发生函数使用的  
int main(void)
{
       
        int key1=0;
        int freq;
        u8 ARR;
        extern u16 DAC_Datas[];
        extern u16 DAC_2Datas[];
        KEY_Init();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);      //初始化延时函数
       
         
        Dac1_Init();                                 //DAC通道1初始化       
        Dac2_Init();
        uart_init(115200);                     //初始化USART
       
        while(1)
        {       
               
                key1=KEY_Scan(0);
                if(key1==KEY0_PRES){
                       
                       
                       
                       
                       
                        freq=100000;
                        ARR = f_clk / ((0 + 1) * freq * Dot_X);
                        TIM4_Int_Init(ARR,0);
                        printf("正弦波111,3V,%dHz\r\n",freq);
                        delay_ms(10);
                        Generate_Wave(1,3720,DAC_Datas);
                       
                       
                       
                        freq=50000;
                        ARR = f_clk / ((0 + 1) * freq * Dot_X);
                        TIM2_Int_Init(ARR,0);
                        printf("正弦波2222,3V,%dHz\r\n",freq);
                        Generate_Wave(1,3720,DAC_2Datas);
                        delay_ms(10);
                       
                       
                       
                        /*freq=5000;
                        ARR = f_clk / ((PSC + 1) * freq * Dot_X);
                        TIM4_Int_Init(ARR,PSC);
                        delay_ms(10);
                        Generate_Wave(2,3720,DAC_Datas);
                        printf("三角波,3V,%dHz\r\n",freq);*/
                       
                }
                delay_ms(10);
               
        }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 08:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表