本帖最后由 qiao--- 于 2024-1-22 22:59 编辑
本期测评我来完成一下我测评计划中提到的用DAC输出一个正选波形。DAC波形输出效果请看二楼。我这里给大家总结了两种输出正弦波形的方法,查表法和公式法。
准备工作
首先我们先翻阅一下datasheet,看一下dac的引脚是什么。
这里翻阅之后我们需要在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。
1.查表法
查表法就是将正弦波的数据存在一个数组中,然后依次遍历这个数组将其存入dac转换器。这种方法的缺点是cpu占用率较高,不利于多任务的运行。
我们先定义一个数组,用于存放我们的dac的数值。到时候我们可以直接将这些数字写进dac转换寄存器当中就可以实现转换了。
紧接着我们需要硬件初始化dac,初始化代码如下所示:
这里我打算用用定时器来定义每两个数值之间的转换时间,定义一个变量volatile uint32_t gtimer_Update_Flag标志位来确定是否可以进行转换了,并且在定时器中断中将他置1。这里我用的是TIM7,定时器初始化代码如下
我们在更新中断里把这个标志位置1,如下图所示
此时我们就可以编写dac输出正弦波的应用代码了,只需要在判断标志位为1时利用函数HAL_DACEx_DualSetValue将数组的数值写进到寄存器当中就可以了,如下图所示
这里我们就完成了全部的代码编写,我这里创建一个任务来运行。
2.公式法
公式法简而言之就是利用数学公式进行计算,我把这一步骤设计在定时器中断中,可以减少cpu的占有率,有利于多任务的运行。
我们这一方法相比上方的查表法,只需要修改函数DAC_OutPut_Sinx中的应用代码。其只需要进行初始化。
而这个方法的重头戏就在定时器中断中,我们在定时器中断中进行计算。
大家看到我上面的公式,看一看出我的正选波的振幅是多大吗?
我的振幅A=(1240/4096)*3.3 约等于1V,有兴趣的小伙伴可以看看我的定时器,算算我的正弦波的频率为多大。
创建任务代码和查表法是一样的,不需要改动。
总结:这次测评我用了两种方法来输出正弦波,分别为查表法和公式法。但是我更推荐用公式法,因为是在定时器中断中完成的,减少了cpu的占用率,方便多任务的运行。两种方法我都在我的工程实现了,大家可以去验证一下。