奇信邦网游福利站

DAC的知识点汇总,不看肯定后悔

问答对人有帮助,内容完整,我也想知道答案

0

DAC的知识点汇总,不看肯定后悔

0

2021-11-8 07:41:53

评论

淘帖0

邀请回答

您可以邀请以下用户,快速回答问题

×

heks

该类别下有 54 个回答。

邀请回答

hgimtk

该类别下有 45 个回答。

邀请回答

新星之火12138

该类别下有 43 个回答。

邀请回答

chm5

该类别下有 42 个回答。

邀请回答

wang21cj

该类别下有 41 个回答。

邀请回答

hjfjsdgfjdsf

该类别下有 38 个回答。

邀请回答

werywer

该类别下有 36 个回答。

邀请回答

fdjslkjd

该类别下有 35 个回答。

邀请回答

uvysdfydad

该类别下有 35 个回答。

邀请回答

h1654155957.9520

该类别下有 35 个回答。

邀请回答

凤毛麟角

该类别下有 34 个回答。

邀请回答

维生素B2

该类别下有 34 个回答。

邀请回答

dfzvzs

该类别下有 34 个回答。

邀请回答

江左盟

该类别下有 34 个回答。

邀请回答

jenny042

该类别下有 34 个回答。

邀请回答

爱与友人

该类别下有 33 个回答。

邀请回答

wenminglang

该类别下有 33 个回答。

邀请回答

lining870815844

该类别下有 33 个回答。

邀请回答

储蓄叛逆

该类别下有 33 个回答。

邀请回答

ggfvxv

该类别下有 33 个回答。

邀请回答

举报

陈秀英

相关推荐

• STM32F103C8串口中断/接收数据得知识点汇总,不看肯定后悔

1580

• 串口printf函数的相关知识点汇总,不看肯定后悔

1200

• stm32串口的相关知识点汇总,不看肯定后悔

1188

• STM32F103 UART串口的知识点汇总,不看肯定后悔

970

• STM32库的相关知识点汇总,不看肯定后悔

920

• STM32红外接收解码的知识点汇总,不看肯定后悔

1664

• ARM Cortex的知识点汇总,不看肯定后悔

1810

• 计算机的基础知识点汇总,不看肯定后悔

1704

• UART的知识点汇总,不看肯定后悔

1084

• IIC总线的知识点汇总,不看肯定后悔

1153

提交评论

1个回答

答案对人有帮助,有参考价值

0

本章节为大家讲解DAC,实际项目用到DAC的地方比较多,而且H7的DAC性能也比较给力。

59.1 初学者重要提示

注意STM32H7只有一个DAC,但有两个独立的通道,跟F4的略不同,F4是两个DAC。

如果仅使用STM32H7的一个通道,即PA4或者PA5引脚,另一个引脚没有做任何配置,这个引脚上会有波形效应。

STM32H7的DAC支持出厂校准和用户校准模式。特别注意一点,校准是建立在用户使能了输出缓冲的情况下才有效。

STM32H7的DAC支持正常模式和采样保持模式,其中采样保持模式用于低功耗状态使用。

DAC的输出除了可以连接PA4或者PA5引脚,也可以连接到片上外设,比如运放,比较器。

59.2 DAC基础知识

对于STM32H7的DAC了解到以下几点即可:

STM32H7的DAC只有一个,但有两个独立的通道,跟F4的略不同,F4是两个DAC

12位分辨率,双通道,支持独立或者同时使用。

两个DAC通道均支持DMA。

每路DAC输出均可与DAC_OUTx输出引脚断开连接,而且DAC 输出可与片上外设连接。

支持偏移校准,参考电压可以使用内部的VREFBUF,也可以使用VREF+引脚外接的电压基准。

支持噪声波和三角波生成。这两种方案不够灵活,所以基本都采用定时器触发+DMA方式生成任意波形。

59.2.1 DAC硬件框图

认识一个外设,最好的方式就是看它的框图,方便我们快速地了解DAC的基本功能,然后再看手册了解细节。框图如下所示:

通过这个框图,我们可以得到如下信息:

VDDA

用于ADC、DAC、运放、比较器和电压基准供电,这部分供电是独立的。

VREF+

用于ADC和DAC的基准电压,当使能了STM32H7内部的电压基准,将使用内部基准供VREF+,VREF-。如果没有使能的话,通过外置电压基准提供。

VSSA

所有电源和模拟稳压器的地端。

dac_ch1_dma

DAC通道1的DMA请求。

dac_ch2_dma

DAC通道2的DMA请求。

dac_ch1_trg[0:15]

DAC通道1的输入触发。

dac_ch2_trg[0:15]

DAC通道2的输入触发。

dac_unr_it

DAC输出的下溢中断信号。

dac_pclk

DAC时钟输入

dac_out1

DAC通道1输出。

dac_out2

DAC通道2输出。

lsi_ck

使用LSI时钟源,可以让DAC在停止模式下运行。

59.2.2 DAC数据格式和输出电压

DAC的数据寄存器设计比较灵活,每个通道都有一组单独的寄存器(下面是通道1的寄存器):

8位右对齐数据保持寄存器DACx_DHR8R1。

12位右对齐数据保持寄存器DACx_DHR12R1。

12位左对齐数据保持寄存器DACx_DHR12L1。

除了这种单独寄存器,为了降低带宽,也支持两个通道公用一个寄存器。

8 位右对齐数据保持寄存器DACx_DHR8RD。

12 位左对齐数据保持寄存器DACx_DHR12LD。

12 位右对齐数据保持寄存器DACx_DHR12RD。

通道1和通道2共用的效果如下:

由于DAC是12bit的DAC,那么范围就是0-4095,对应的输出电压如下:

DAC Output = Vref *(DOR / 4095),其中Vref是参考电压,DOR是数据输出寄存器。

比如需要DAC输出0.7V,那么假设VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V。

59.2.3 DAC支持的触发源

DAC支持软件触发和硬件触发,具体支持的触发源如下:

#define DAC_TRIGGER_NONE ((uint32_t)0x00000000)

#define DAC_TRIGGER_SOFTWARE ((uint32_t)(DAC_CR_TEN1))

#define DAC_TRIGGER_T1_TRGO ((uint32_t)(DAC_CR_TSEL1_0 | DAC_CR_TEN1))

#define DAC_TRIGGER_T2_TRGO ((uint32_t)(DAC_CR_TSEL1_1 | DAC_CR_TEN1))

#define DAC_TRIGGER_T4_TRGO ((uint32_t)(DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)

#define DAC_TRIGGER_T5_TRGO ((uint32_t)(DAC_CR_TSEL1_2 |DAC_CR_TEN1))

#define DAC_TRIGGER_T6_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1))

#define DAC_TRIGGER_T7_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TEN1))

#define DAC_TRIGGER_T8_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1))

#define DAC_TRIGGER_T15_TRGO ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TEN1))

#define DAC_TRIGGER_HR1_TRGO1 ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_0 | DAC_CR_TEN1))

#define DAC_TRIGGER_HR1_TRGO2 ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_1 | DAC_CR_TEN1))

#define DAC_TRIGGER_LP1_OUT ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1))

#define DAC_TRIGGER_LP2_OUT ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 | DAC_CR_TEN1))

#define DAC_TRIGGER_EXT_IT9 ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1))

59.2.4 DAC正常模式和采样保持模式

关于正常模式和采样保持模式,注意以下几点:

正常模式是平时最常用的方式,比较好理解。而采样保持模式用于低功耗方式。

在采样保持模式下,DAC内核转换数据,然后保持电容上的电压。不转换时,DAC内核和样本之间的缓冲器完全关闭,DAC输出为三态,因此降低了整体功耗,但每次新转换前都需要一段稳定期。

采样保持模式可修改内部或者外部参考电压。

采样保持部分可以用LSI时钟,也可以运行在几种低功耗模式下,如RUN模式, SLEEP& STOP模式。

59.2.5 DAC的出厂校准和用户校准

一般情况下,使用出厂校准即可,芯片上电后自动完成出厂校准。而用户校准略麻烦,暂不做研究。这里特别注意一点,校准是建立在用户使能了输出缓冲的情况下才有效。

59.3 DAC的HAL库用法

DAC的HAL库用法其实就是几个结构体变量成员的配置和使用,然后配置时钟,并根据需要配置NVIC、中断和DMA。下面我们逐一展开为大家做个说明。

59.3.1 DAC寄存器结构体DAC_TypeDef

DAC相关的寄存器是通过HAL库中的结构体DAC_TypeDef定义的,在stm32h743xx.h中可以找到它们的具体定义:

typedef struct

{

__IO uint32_t CR;

__IO uint32_t SWTRIGR;

__IO uint32_t DHR12R1;

__IO uint32_t DHR12L1;

__IO uint32_t DHR8R1;

__IO uint32_t DHR12R2;

__IO uint32_t DHR12L2;

__IO uint32_t DHR8R2;

__IO uint32_t DHR12RD;

__IO uint32_t DHR12LD;

__IO uint32_t DHR8RD;

__IO uint32_t DOR1;

__IO uint32_t DOR2;

__IO uint32_t SR;

__IO uint32_t CCR;

__IO uint32_t MCR;

__IO uint32_t SHSR1;

__IO uint32_t SHSR2;

__IO uint32_t SHHR;

__IO uint32_t SHRR;

} DAC_TypeDef;

__IO表示volatile, 这是标准C语言中的一个修饰字,表示这个变量是非易失性的,编译器不要将其优化掉。core_m7.h 文件定义了这个宏:

#define __O volatile /*!< Defines 'write only' permissions */

#define __IO volatile /*!< Defines 'read / write' permissions */

下面我们再看DAC的定义,在stm32h743xx.h文件。

#define PERIPH_BASE ((uint32_t)0x40000000)

#define D2_APB1PERIPH_BASE PERIPH_BASE

#define DAC1_BASE (D2_APB1PERIPH_BASE + 0x7400)

#define DAC1 ((DAC_TypeDef *) DAC1_BASE) <----- 展开这个宏,(DAC_TypeDef *) 0x40007400

我们访问DAC1的CR寄存器可以采用这种形式:DAC1->CR = 0。

59.3.2 DAC的采样保持DAC_SampleAndHoldConfTypeDef

此结构体用于DAC的采样保持参数,具体定义如下:

typedef struct

{

uint32_t DAC_SampleTime ;

uint32_t DAC_HoldTime ;

uint32_t DAC_RefreshTime ; }

DAC_SampleAndHoldConfTypeDef;

下面将这几个参数逐一为大家做个说明:

uint32_t DAC_SampleTime

此参数用于设置DAC的采样时间,范围0 - 1023。

uint32_t DAC_HoldTime

此参数用于设置DAC的保持时间,范围0 – 1023。

uint32_t DAC_RefreshTime

此参数用于设置DAC的刷新时间,范围0 – 255。

59.3.3 DAC的通道参数结构体DAC_ChannelConfTypeDef

此结构体用于DAC的通道参数配置,具体定义如下:

typedef struct

{

uint32_t DAC_SampleAndHold;

uint32_t DAC_Trigger;

uint32_t DAC_OutputBuffer;

uint32_t DAC_ConnectOnChipPeripheral ;

uint32_t DAC_UserTrimming;

uint32_t DAC_TrimmingValue;

DAC_SampleAndHoldConfTypeDef DAC_SampleAndHoldConfig;

}DAC_ChannelConfTypeDef;

下面将这几个参数逐一为大家做个说明:

uint32_t DAC_SampleAndHold

此参数用于使能采样保持模式,具体支持的参数如下:

#define DAC_SAMPLEANDHOLD_DISABLE ((uint32_t)0x00000000)

#define DAC_SAMPLEANDHOLD_ENABLE ((uint32_t)DAC_MCR_MODE1_2)

uint32_t DAC_Trigger

此参数用于DAC触发源的选择,具体支持的参数如下:

#define DAC_TRIGGER_NONE

#define DAC_TRIGGER_SOFTWARE

#define DAC_TRIGGER_T1_TRGO

#define DAC_TRIGGER_T2_TRGO

#define DAC_TRIGGER_T5_TRGO

#define DAC_TRIGGER_T6_TRGO

#define DAC_TRIGGER_T7_TRGO

#define DAC_TRIGGER_T8_TRGO

#define DAC_TRIGGER_T15_TRGO

#define DAC_TRIGGER_HR1_TRGO1

#define DAC_TRIGGER_HR1_TRGO2

#define DAC_TRIGGER_LP1_OUT

#define DAC_TRIGGER_LP2_OUT

#define DAC_TRIGGER_EXT_IT9

uint32_t DAC_OutputBuffer

此参数用于使能或者关闭DAC的输出缓冲,使能输出缓冲后,可以增加DAC的驱动能力,具体支持的参数如下:

#define DAC_OUTPUTBUFFER_ENABLE ((uint32_t)0x00000000)

#define DAC_OUTPUTBUFFER_DISABLE ((uint32_t)DAC_MCR_MODE1_1)

uint32_t DAC_ConnectOnChipPeripheral

此参数用于DAC是否连接片上外设(运放,比较器等),具体支持的参数如下:

#define DAC_CHIPCONNECT_DISABLE ((uint32_t)0x00000000)

#define DAC_CHIPCONNECT_ENABLE ((uint32_t)DAC_MCR_MODE1_0)

uint32_t DAC_UserTrimming

此参数用于设置DAC的校准方式,采用出厂模式还是用户模式,具体支持的参数如下:

#define DAC_TRIMMING_FACTORY ((uint32_t)0x00000000)

#define DAC_TRIMMING_USER ((uint32_t)0x00000001)

uint32_t DAC_TrimmingValue

此参数用于设置用户校准模式的偏移值,参数范围1-31。

DAC_SampleAndHoldConfTypeDef DAC_SampleAndHoldConfig

此参数用于采样保持具体参数设置,详解本章3.2小节的说明。

59.3.4 DAC结构体句柄DAC_HandleTypeDef

HAL库在DAC_TypeDef的基础上封装了一个结构体DAC_HandleTypeDef,定义如下:

typedef struct

{

DAC_TypeDef *Instance;

__IO HAL_DAC_StateTypeDef State;

HAL_LockTypeDef Lock;

DMA_HandleTypeDef *DMA_Handle1;

DMA_HandleTypeDef *DMA_Handle2;

__IO uint32_t ErrorCode;

}DAC_HandleTypeDef;

下面将这几个参数逐一做个说明。

DAC_TypeDef *Instance

这个参数是寄存器的例化,方便操作寄存器,详见本章3.1小节。

DMA_HandleTypeDef *DMA_Handle1

DMA_HandleTypeDef *DMA_Handle2

DMA句柄结构体指针变量,用于关联DAC句柄,方便调用。

HAL_LockTypeDef Lock

__IO HAL_DAC_STATETypeDef State

__IO uint32_t ErrorCode

这三个变量主要供函数内部使用。Lock用于设置锁状态,State用于设置DAC状态,而ErrorCode用于配置代码错误。

59.3.5 DAC初始化流程总结

使用方法由HAL库提供:

第1步:基本的初始化。

函数HAL_DAC_Init初始化。

配置DAC_OUT1: PA4, DAC_OUT2: PA5引脚为模拟模式。

函数HAL_DAC_ConfigChannel配置通道参数。

函数HAL_DAC_Start() or HAL_DAC_Start_DMA()使能DAC。

第2步:DAC校准。

出厂校准比较简单,芯片上电后自动完成,而用户校准需要依次调用函数HAL_DACEx_GetTrimOffset,HAL_DACEx_SelfCalibrate和HAL_DACEx_SetUserTrimming。

第3步:查询模式。

函数HAL_DAC_Start() 启动。

函数HAL_DAC_GetValue()可以读取输出值。

函数HAL_DAC_Stop可以停止DAC。

第4步:DMA方式。

函数HAL_DAC_Start_DMA()启动DMA方式转换。

DAC的数据传输一半的时候, HAL_DAC_ConvHalfCpltCallbackCh1() 或者 HAL_DACEx_ConvHalfCpltCallbackCh2() 会被调用。

DAC的数据传输完成的时候,HAL_DAC_ConvCpltCallbackCh1() 或者 HAL_DACEx_ConvHalfCpltCallbackCh2() 会被调用。

传输错误时,函数HAL_DAC_ErrorCallbackCh1会被调用。

DMA下溢错误,会调用函数HAL_DAC_DMAUnderrunCallbackCh1()或者HAL_DACEx_DMAUnderrunCallbackCh2()。

停止DAC的DMA方式,可以调用函数HAL_DAC_Stop_DMA

59.4 源文件stm32h7xx_hal_dac.c

这里把我们把如下几个常用到的函数做个说明:

HAL_DAC_Init

HAL_DAC_ConfigChannel

HAL_DAC_Start_DMA

59.4.1 函数HAL_DAC_Init

函数原型:

HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac)

{

/* 检测DAC句柄 */

if(hdac == NULL)

{

return HAL_ERROR;

}

assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));

if(hdac->State == HAL_DAC_STATE_RESET)

{

hdac->Lock = HAL_UNLOCKED;

/* 初始化GPIO,NVIC等 */

HAL_DAC_MspInit(hdac);

}

/* 设置DAC状态忙 */

hdac->State = HAL_DAC_STATE_BUSY;

/* 设置DAC无错误 */

hdac->ErrorCode = HAL_DAC_ERROR_NONE;

/* 设置DAC就绪 */

hdac->State = HAL_DAC_STATE_READY;

/* 返回HAL_OK */

return HAL_OK;

}

函数描述:

此函数用于初始化DAC。

函数参数:

第1个参数是DAC_HandleTypeDef类型结构体指针变量,结构体变量成员的详细介绍看本章3.4小节。

返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。

注意事项:

函数HAL_DAC_MspInit用于初始化DAC的底层时钟、NVIC等功能。需要用户自己在此函数里面实现具体的功能。由于这个函数是弱定义的,允许用户在工程其它源文件里面重新实现此函数。当然,不限制一定要在此函数里面实现,也可以像早期的标准库那样,用户自己初始化即可,更灵活些。

如果形参hdac的结构体成员State没有做初始状态,这个地方就是个坑。特别是用户搞了一个局部变量DAC_HandleTypeDef DacHandle。

对于局部变量来说,这个参数就是一个随机值,如果是全局变量还好,一般MDK和IAR都会将全部变量初始化为0,而恰好这个 HAL_DAC_STATE_RESET = 0x00U。

解决办法有三

方法1:用户自己初始DAC底层。

方法2:定义DAC_HandleTypeDef DacHandle为全局变量。

方法3:下面的方法

if(HAL_DAC_DeInit(&DacHandle) != HAL_OK)

{

Error_Handler();

}

if(HAL_DAC_Init(&DacHandle) != HAL_OK)

{

Error_Handler();

}

使用举例:

DAC_HandleTypeDef DAC_Handle;

DacHandle.Instance = DAC1;

if (HAL_DAC_Init(&DacHandle) != HAL_OK)

{

Error_Handler(__FILE__, __LINE__);

}

59.4.2 函数HAL_DAC_ConfigChannel

函数原型:

HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel)

{

uint32_t tmpreg1 = 0, tmpreg2 = 0;

uint32_t tickstart = 0;

/* 部分省略,未贴出 */

/* 上锁 */

__HAL_LOCK(hdac);

/* 设置DAC忙 */

hdac->State = HAL_DAC_STATE_BUSY;

if(sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE)

{

/* 通道1设置 */

if (Channel == DAC_CHANNEL_1)

{

}

else /* 通道2设置 */

{

}

}

if(sConfig->DAC_UserTrimming == DAC_TRIMMING_USER)

/* 用户校准配置 */

{

}

/* 出厂模式无需配置,复位后自动设置 */

/* 获取DAC MCR数值 */

tmpreg1 = hdac->Instance->MCR;

/* 清除DAC_MCR_MODE2_0, DAC_MCR_MODE2_1 和 DAC_MCR_MODE2_2 位 */

tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << Channel);

/* 配置DAC通道 */

tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | sConfig->DAC_ConnectOnChipPeripheral);

tmpreg1 |= tmpreg2 << Channel;

/* 设置MCR数值 */

hdac->Instance->MCR = tmpreg1;

/* DAC工作在正常模式 */

CLEAR_BIT (hdac->Instance->CR, DAC_CR_CEN1 << Channel);

/* 获取DAC CR值 */

tmpreg1 = hdac->Instance->CR;

tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << Channel);

tmpreg2 = (sConfig->DAC_Trigger);

tmpreg1 |= tmpreg2 << Channel;

/* 写DAC CR值 */

hdac->Instance->CR = tmpreg1;

/* 禁止波形生成 */

hdac->Instance->CR &= ~(DAC_CR_WAVE1 << Channel);

/* 设置DAC就绪 */

hdac->State = HAL_DAC_STATE_READY;

/* 解锁 */

__HAL_UNLOCK(hdac);

/* 返回HAL_OK */

return HAL_OK;

}

函数描述:

此函数主要用于配置DAC的通道参数。

函数参数:

第1个参数是DAC_HandleTypeDef类型结构体指针变量,结构体变量成员的详细介绍看本章3.4小节。

第2个参数是DAC_ChannelConfTypeDef类型结构体指针变量,用于DAC的通道参数配置,结构体变量成员的详细介绍看本章3.3小

第3个参数用于选择要配置那个通道,DAC_CHANNEL_1表示配置通道1,DAC_CHANNEL_2表示配置通道2。

返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。

使用举例:

static DAC_ChannelConfTypeDef sConfig;

static DAC_HandleTypeDef DacHandle;

sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE; /* 关闭采样保持模式,这个模式主要用于低功耗 */

sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO; /* 采用定时器6触发 */

sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; /* 使能输出缓冲 */

sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;/* 不将DAC连接到片上外设 */

sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY; /* 使用出厂校准 */

if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1) != HAL_OK)

{

Error_Handler(__FILE__, __LINE__);

}

59.4.3 函数HAL_DAC_Start_DMA

函数原型:

HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment)

{

uint32_t tmpreg = 0;

/* 部分省略,未贴出 */

/* 检测参数 Check the parameters */

assert_param(IS_DAC_CHANNEL(Channel));

assert_param(IS_DAC_ALIGN(Alignment));

/* 上锁 Process locked */

__HAL_LOCK(hdac);

/* 设置DAC忙 Change DAC state */

hdac->State = HAL_DAC_STATE_BUSY;

/* 配置通道1 */

if(Channel == DAC_CHANNEL_1)

{

/* DMA传输完成回调 */

hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;

/* DMA半传输完成回调 */

hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;

/* DMA传输错误回调 */

hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;

/* 使能DAC DMA */

SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);

/* 数据对齐方式设置 */

switch(Alignment)

{

case DAC_ALIGN_12B_R:

tmpreg = (uint32_t)&hdac->Instance->DHR12R1;

break;

case DAC_ALIGN_12B_L:

tmpreg = (uint32_t)&hdac->Instance->DHR12L1;

break;

case DAC_ALIGN_8B_R:

tmpreg = (uint32_t)&hdac->Instance->DHR8R1;

break;

default:

break;

}

}

else

{

}

}

/* 使能DMA Stream */

if(Channel == DAC_CHANNEL_1)

{

/* 使能DAC DMA下溢中断 */

__HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);

/* 启动传输 */

HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);

}

else

{

__HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);

HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);

}

/* 解锁 */

__HAL_UNLOCK(hdac);

/* 使能DAC通道 */

__HAL_DAC_ENABLE(hdac, Channel);

/* 返回HAL_OK */

return HAL_OK;

}

函数描述:

此函数用于启动DAC的DMA方式

函数参数:

第1个参数是DAC_HandleTypeDef类型结构体指针变量,结构体变量成员的详细介绍看本章3.4小节。

第2个参数用于选择要配置那个通道,DAC_CHANNEL_1表示配置通道1,DAC_CHANNEL_2表示配置通道2。

第3个参数是波形数据地址。

第4个参数是传输的数据长度。

第5个参数是数据对齐方式设置。

DAC_ALIGN_8B_R 表示8bit右对齐。

DAC_ALIGN_12B_L 表示12bit左对齐。

DAC_ALIGN_12B_R 表示12bit右对齐。

返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。

使用举例:

static DAC_HandleTypeDef DacHandle;

/* 启动DAC DMA */

if (HAL_DAC_Start_DMA(&DacHandle, DAC_CHANNEL_2, (uint32_t *)g_usWaveBuff, 64, DAC_ALIGN_12B_R) != HAL_OK)

{

Error_Handler(__FILE__, __LINE__);

}

59.5 总结

本章节就为大家讲解这么多,DAC功能用到的地方还是比较多的,建议熟练使用。

2021-11-8 11:31:41

评论

举报

吴键洪

提交评论

只有小组成员才能发言,加入小组>>