[原创] 【ACM32G103RCT6】7-DAC两种方法输出正弦波形

qiao---   2024-1-20 01:01 楼主

本期测评我来完成一下我测评计划中提到的用DAC输出一个正选波形。DAC波形输出效果请看二楼。我这里给大家总结了两种输出正弦波形的方法,查表法和公式法

 

准备工作

首先我们先翻阅一下datasheet,看一下dac的引脚是什么。

image.png  

这里翻阅之后我们需要在msp.c文件中进行引脚的初始化。msp.c文件一般是使能相应的硬件和做引脚初始化的。

下面这段代码主要进行初始化dac以及dac两个通道的引脚,并且还使能了dma中断。

void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{
    if(hdac->Instance==DAC)
    { 
        /* Enable DAC clock */
        __HAL_RCC_DAC1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        
        GPIO_InitTypeDef GPIO_InitStructure;   	
        /* Initialization GPIO */
        /**DAC1 GPIO Configuration    
        PA4  ------> DAC_OUT1 
        PA5  ------> DAC_OUT2 
        */
        
        GPIO_InitStructure.Pin = GPIO_PIN_4|GPIO_PIN_5;	
        GPIO_InitStructure.Pull=GPIO_NOPULL;
        GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
        
        printfS("DAC Channel-1:PA4\r\n");
        printfS("DAC Channel-2:PA5\r\n");
        
        /* Enable the DAC DMA underrun interrupt */
        hdac->Instance->CR |= DAC_CR_DMAUDIE1 | DAC_CR_DMAUDIE2;
        NVIC_ClearPendingIRQ(DAC_IRQn);
        NVIC_SetPriority(DAC_IRQn, 5);
        NVIC_EnableIRQ(DAC_IRQn);
    }
}

这里完成之后我们需要在新建一个dac.c文件,用于存放我们的dac相关的代码。我们知道dac是属于数模转换,用12位或其他位数字转换成对应的电压值。下面是dac转换逻辑图,方便大家理解dac。

image.png  

 

1.查表法

查表法就是将正弦波的数据存在一个数组中,然后依次遍历这个数组将其存入dac转换器。这种方法的缺点是cpu占用率较高,不利于多任务的运行。

我们先定义一个数组,用于存放我们的dac的数值。到时候我们可以直接将这些数字写进dac转换寄存器当中就可以实现转换了。

image.png   紧接着我们需要硬件初始化dac,初始化代码如下所示:

image.png   

这里我打算用用定时器来定义每两个数值之间的转换时间,定义一个变量volatile uint32_t gtimer_Update_Flag标志位来确定是否可以进行转换了,并且在定时器中断中将他置1。这里我用的是TIM7,定时器初始化代码如下

image.png    

 

我们在更新中断里把这个标志位置1,如下图所示

image.png  

此时我们就可以编写dac输出正弦波的应用代码了,只需要在判断标志位为1时利用函数HAL_DACEx_DualSetValue将数组的数值写进到寄存器当中就可以了,如下图所示

image.png  

这里我们就完成了全部的代码编写,我这里创建一个任务来运行。

image.png  

 

2.公式法

公式法简而言之就是利用数学公式进行计算,我把这一步骤设计在定时器中断中,可以减少cpu的占有率,有利于多任务的运行。

我们这一方法相比上方的查表法,只需要修改函数DAC_OutPut_Sinx中的应用代码。其只需要进行初始化。

image.png  

而这个方法的重头戏就在定时器中断中,我们在定时器中断中进行计算。

image.png  

  大家看到我上面的公式,看一看出我的正选波的振幅是多大吗?

我的振幅A=(1240/4096)*3.3 约等于1V,有兴趣的小伙伴可以看看我的定时器,算算我的正弦波的频率为多大。

创建任务代码和查表法是一样的,不需要改动。

 

总结:这次测评我用了两种方法来输出正弦波,分别为查表法和公式法。但是我更推荐用公式法,因为是在定时器中断中完成的,减少了cpu的占用率,方便多任务的运行。两种方法我都在我的工程实现了,大家可以去验证一下。

 

06dac.7z (1.3 MB)
(下载次数: 1, 2024-1-22 20:12 上传)

 

 

本帖最后由 qiao--- 于 2024-1-22 22:59 编辑

    06dac.7z (2024-1-20 00:50 上传)

    1.3 MB, 下载次数: 1

    DAC两种方法输出正弦波形

回复评论 (36)

1 来自 2楼 qiao--- 

等了三天我买的便携示波器到了,调试了一下,成功显示出波形

第一种查表法的波形如下所示:

image.png   第二种公式法的波形如下:

image.png  

第二种公式法的可以看到峰峰值大约为2V说明振幅为1V,DAC输出正常,波形很稳定。

image.png  

点赞  2024-1-22 20:26
我直接输出电压值,但是用ADC测试,那的电压是不稳定的,如果我想一直输出电压值 需要怎么操作呀
点赞  2024-1-20 08:59

而这个方法的重头戏就在定时器中断中,我们在定时器中断中进行计算。

更正一下楼主的提法,应该是在定时器“回调函数”中完成。

我也很粗心呀,经常出错漏。

点赞  2024-1-20 09:02

我现在给你用示波器演示一下。

点赞  2024-1-20 09:05

楼主,您也可以尝试一下 DMA + DAC + Timer 的组合方式,即DMA用来传输DAC的输出值,Timer用来定期触发DMA开始传输。

点赞  2024-1-20 09:24

我测了一下,波形如下,你看对不对:

3f84bad042a023e5a9f0ae87a3b7f22.jpg  

点赞 (1) 2024-1-20 09:33
引用: lugl4313820 发表于 2024-1-20 09:02 而这个方法的重头戏就在定时器中断中,我们在定时器中断中进行计算。 更正一下楼主的提法,应该是在定时 ...

所言极是,感谢更正


点赞  2024-1-20 12:37
引用: lugl4313820 发表于 2024-1-20 09:05 我现在给你用示波器演示一下。

整么样,有没有波形,没有我改一下代码



点赞  2024-1-20 12:38
引用: lugl4313820 发表于 2024-1-20 08:59 我直接输出电压值,但是用ADC测试,那的电压是不稳定的,如果我想一直输出电压值 需要怎么操作呀

你的意思是用DAC输出电压,用ADC再测DAC输出的电压吗


点赞  2024-1-20 12:39
引用: jobszheng5 发表于 2024-1-20 09:24 楼主,您也可以尝试一下 DMA + DAC + Timer 的组合方式,即DMA用来传输DAC的输出值,Timer用来定期触发DMA ...

确实,这样也可以减少cpu 的使用率,直接用DMA传输表中的数了,感谢珍贵意见


点赞  2024-1-20 12:41

定时器中断里做这样的运算 应该花很长时间才能退出中断吧?

虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2024-1-20 12:43
引用: qiao--- 发表于 2024-1-20 12:38 整么样,有没有波形,没有我改一下代码

好象没有出波形,测出来的是电源的干扰波形。还有用中断的方式,你要加入延迟,要不LED任务就不运行了。

点赞  2024-1-20 12:45

我在前面也用DAC弄了一下,但是好象输出的电压不是稳定的。

点赞  2024-1-20 12:46
引用: lugl4313820 发表于 2024-1-20 12:45 好象没有出波形,测出来的是电源的干扰波形。还有用中断的方式,你要加入延迟,要不LED任务就不运行了。 ...

懂了,用第一种方法需要改一下那个定时器回调函数,需要把那个置1这个你改没,如果没改可能是因为这个才没有波形,就是第二种方法有波形但是led任务没有正常运行这样对吗


点赞  2024-1-20 12:49
引用: lugl4313820 发表于 2024-1-20 12:46 我在前面也用DAC弄了一下,但是好象输出的电压不是稳定的。

不稳定,DAC好像有一个矫正功能,你可以试一下,用之前矫正一下看看


点赞  2024-1-20 12:50
引用: littleshrimp 发表于 2024-1-20 12:43 定时器中断里做这样的运算 应该花很长时间才能退出中断吧?

中断要快进快出,我这个运算很快的,之前在一本书上看到这样写的


点赞  2024-1-20 12:51
引用: qiao--- 发表于 2024-1-20 12:49 懂了,用第一种方法需要改一下那个定时器回调函数,需要把那个置1这个你改没,如果没改可能是因为这个才 ...

第二种好象也没有,第一种也是一样的。

点赞  2024-1-20 13:10
引用: lugl4313820 发表于 2024-1-20 13:10 第二种好象也没有,第一种也是一样的。

行,感谢版主,我在看看是什么问题


点赞  2024-1-20 13:11
引用: qiao--- 发表于 2024-1-20 12:50 不稳定,DAC好像有一个矫正功能,你可以试一下,用之前矫正一下看看

其实这个CPU频率非常高,用你多任务系统,对CPU来说没什么问题。可以采用DMA配合中断来实现。

点赞  2024-1-20 13:12
引用: lugl4313820 发表于 2024-1-20 13:10 第二种好象也没有,第一种也是一样的。

没有示波器就是不方便呀


点赞  2024-1-20 13:13
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复