[N32G45x]

求一个DMA双DAC生产两个不同频率的配置实例

[复制链接]
164|4
手机看帖
扫描二维码
随时随地手机跟帖
hisungao|  楼主 | 2023-3-8 11:11 | 显示全部楼层 |阅读模式
    如题,将DAC1和DAC2的触发源分别设置成两个定时器和不同时长,使用右对齐DAC_DR12CH1和DAC_DR12CH2,使用DAM方式时只能用一个DAC时才能输出正确频率的正弦波,同时使用两个DAC频率就比计算的低了约20%;
    按手册中的10.4.1中不使用波形发生器独立触发中的描述,似乎只需要选择不同触发源就能实现不同频率输出,但我在使用中将触发源改成两个定时器触发,使用DAC_DR12DCH,输出波形频率比实际计算的也是低了约20%,同时波形好像是DAC1
和DAC叠加在一起并不是正弦波,看DMA,TIM,DAC寄存器的内容和正常波形时寄存器的设置是内容是相同的,就是不知道哪里搞错了。
    求一个用DAM方式同时将两个DAC输出不同频率正弦波的配置例子学习参考,谢谢。

使用特权

评论回复
hisungao|  楼主 | 2023-3-10 10:09 | 显示全部楼层
参考例子改了,注释掉TIM_TrgoInit里的TIM2或者TIM4,只使用PA4能得到正确的56.25K或者只使用PA5也能得到正确的102.27K正弦波出来,但是只要将同时使用TIM2和TIM4让DAC1和DAC2同时输出正弦波,那么PA4还是正确的56.25K波,而PA5就只有80K多点跳动,而不是102.27K,求问帮忙指点指点下面改的是哪里不正确搞成这样的错误结果?
另外还有个问题是输出电压峰峰值不是3.3V,官方例子出来的电压是约1.6V,我这里输出频率不一样电压峰峰值也会变,大概是2.7V,这又是为什么?麻烦麻烦各位能看看指点指点,多谢多谢。
#include "n32g45x.h"

/** @addtogroup DAC_DualModeDMA_SineWave
* @{
*/

//#define DAC_DHR12RD_Address 0x40007420
#define DAC_DR12CH1_Address 0x40007408
#define DAC_DR12CH2_Address 0x40007414

/* Init Structure definition */
DAC_InitType DAC_InitStructure;
uint32_t Idx = 0;

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];

void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIM_TrgoInit(void);
void DAC_SineWaveInit(void);
void DMA_Config(void);

/**
* [url=home.php?mod=space&uid=247401]@brief[/url]   Main program.
*/
int main(void)
{

    GPIO_Configuration();
    TIM_TrgoInit();
    DAC_SineWaveInit();

    /* Fill Sine32bit table */
//    for (Idx = 0; Idx < 32; Idx++)
//    {
//        DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);
//    }
    /* DMA Config */
    DMA_Config();

                TIM_Enable(TIM2, ENABLE);
                TIM_Enable(TIM4, ENABLE);
    while (1)
    {
    }
}

/**
* @brief  Configures the different system clocks.
*/
void RCC_Configuration(void)
{
    /* DAC Periph clock enable */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_DAC, ENABLE);
}

/**
* @brief  Configures the different GPIO ports.
*/
void GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;

    /* GPIOA Periph clock enable */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
    GPIO_InitStructure.Pin       = GPIO_PIN_4 | GPIO_PIN_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
}
/**
* @brief  TIM4 Init.
*/
void TIM_TrgoInit(void)
{
    TIM_TimeBaseInitType TIM_TimeBaseStructure;

    /* TIM4 Periph clock enable */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2  , ENABLE); // RCC_APB2_PERIPH_TIM8
                RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM4  , ENABLE);
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
                TIM_TimeBaseStructure.Period           =39;
    TIM_TimeBaseStructure.Prescaler = 0x0;
    TIM_TimeBaseStructure.ClkDiv    = 0x0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
                TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);       
       
                TIM_TimeBaseStructure.Period                =21;
    TIM_TimeBaseStructure.Prescaler = 0x0;
    TIM_TimeBaseStructure.ClkDiv    = 0x0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
                TIM_InitTimeBase(TIM4, &TIM_TimeBaseStructure);

                TIM_SelectOutputTrig(TIM2, TIM_TRGO_SRC_UPDATE);       
                TIM_SelectOutputTrig(TIM4, TIM_TRGO_SRC_UPDATE);
}
/**
* @brief  DAC SineWave Config.
*/
void DAC_SineWaveInit(void)
{
    /* DAC Periph clock enable */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_DAC, ENABLE);

                DAC_InitStructure.Trigger                        = DAC_TRG_T2_TRGO;
    DAC_InitStructure.WaveGen      = DAC_WAVEGEN_NONE;
    DAC_InitStructure.BufferOutput = DAC_BUFFOUTPUT_DISABLE;
                DAC_Init(DAC_CHANNEL_1, &DAC_InitStructure);
       
                DAC_InitStructure.Trigger                        = DAC_TRG_T4_TRGO;
    DAC_InitStructure.WaveGen      = DAC_WAVEGEN_NONE;
    DAC_InitStructure.BufferOutput = DAC_BUFFOUTPUT_DISABLE;
                DAC_Init(DAC_CHANNEL_2, &DAC_InitStructure);

                DAC_Enable(DAC_CHANNEL_1, ENABLE);
                DAC_Enable(DAC_CHANNEL_2, ENABLE);

                DAC_DmaEnable(DAC_CHANNEL_1, ENABLE);
                DAC_DmaEnable(DAC_CHANNEL_2, ENABLE);
       
}
/**
* @brief  DMA Config.
*/
void DMA_Config(void)
{
    DMA_InitType DMA_InitStructure;

    /* DMA2 clock enable */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA2, ENABLE);

//                DMA_DeInit(DMA2_CH3);
                DMA_InitStructure.PeriphAddr                = DAC_DR12CH1_Address;
                DMA_InitStructure.MemAddr                                = (uint32_t)&Sine12bit;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = 32;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_HalfWord ;
    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
                DMA_Init(DMA2_CH3, &DMA_InitStructure);
                DMA_EnableChannel(DMA2_CH3, ENABLE);

//                DMA_DeInit(DMA2_CH4);
                DMA_InitStructure.PeriphAddr                =DAC_DR12CH2_Address;
                DMA_InitStructure.MemAddr                                = (uint32_t)&Sine12bit;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = 32;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_HalfWord ;
    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
                DMA_Init(DMA2_CH4, &DMA_InitStructure);

                DMA_EnableChannel(DMA2_CH4, ENABLE);
               
}


使用特权

评论回复
hisungao|  楼主 | 2023-3-13 22:40 | 显示全部楼层
我在51黑上下了个ST使用DMA+TIM+DAC生成1K和1.2K双频正弦波的例程对比了下,好像我上面生成的配置没什么问题,应该是可以生成正确的两个不同频率的正弦波的,这几天卡这里,不知道是自己哪里漏掉了啥造成生成的频率和实际的对不上,还是说这个N32G45X用来生成是有点别扭?下面是51黑上的例子代码,完整工程见附件,已用STM32F103VBT6的板子验证过程序正常生成波形正确。麻烦哪位有N32G45板子的兄弟能不能验证下生成两个不同频正弦波的配置是否正确,如配置有误还请能指点一二,实在想知道是自己哪里搞错了还是我买的这块板有问题还是哪里的问题。还有个奇怪的是生成的频率不同输出电压峰峰值也不同,0~4095的打点对应不了0~3.3V,先多谢多谢。 51黑论坛_输出两路不同频率正弦波.rar (4.61 MB)

使用特权

评论回复
hisungao|  楼主 | 2023-3-21 15:23 | 显示全部楼层
自己来回答了,用上面的例子改到STM32F103上试,两个DAC上到65K后也是开始乱搞,没搞明白这个DAC建立需要多长时间,感觉应该还是两个DAC来分的所以一超过就乱搞了。输出电压把缓冲打开也能到3.2V,只是这玩意啥负载都不带频率高了都不能满电压?有的人发的图片里是怎么能到满电压的呢?

使用特权

评论回复
zpwang| | 2023-4-2 19:15 | 显示全部楼层
我觉得吧,你需要得到2个DAC输出不同频率的话应该使用两个定时器分别去触发对应的DAC通道.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

51

帖子

0

粉丝