【STM32HAL库】DAC输出0-3.3v

一、简要介绍一下DAC

DAC也有分辨率,转换时间,精度等

分辨率常见为8或12位的 

转换时间F1,F4,F7都是3us左右,而H7系列是1.7us

1.DAC框图

 2.数据格式(对齐方式)

3.触发源 

4.可以发送DMA请求 

注意:只能由外部事件触发DMA请求 

5.模数转换 

6.输出缓存(一般关闭)

二、HAL库函数

三、实验思路及实践

用DAC在引脚输出一个电压值,然后再用ADC来读取这个电压值 

#include "dac.h"

DAC_HandleTypeDef hdac1;
void DAC_Init(void)
{
	DAC_ChannelConfTypeDef sConfig;
	hdac1.Instance = DAC1;
	HAL_DAC_Init(&hdac1);
	
	sConfig.DAC_Trigger = DAC_TRIGGER_NONE;//自动触发
	sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;//关闭输出缓存
	HAL_DAC_ConfigChannel(&hdac1,&sConfig,DAC_CHANNEL_1);
	HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);
}
	
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{
	if(hdac->Instance == DAC1)
	{
		RCC_PeriphCLKInitTypeDef  ADC_PeriphClkInit={0};

		__HAL_RCC_GPIOA_CLK_ENABLE();//PA4
		__HAL_RCC_DAC_CLK_ENABLE();//
		GPIO_InitTypeDef GPIO_Init;
	
		GPIO_Init.Pin = GPIO_PIN_4;
		GPIO_Init.Mode = GPIO_MODE_ANALOG;
		HAL_GPIO_Init(GPIOA,&GPIO_Init);

	}
}

//用0-3300代表0-3.3v
//设置通道输出电压
void DAC_SET_VALUE(uint16_t val)
{
	double temp = val;
	temp /= 1000;
	temp  = temp/3.3*4096;//转换成数字量,供ADC读取,然后我们在转换为模拟量
	if(temp>=4096)temp=4095;
	HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,temp);
}


ADC_HandleTypeDef hadc1;

void ADC_Single_Init(void)
{
	ADC_ChannelConfTypeDef ADC_sConfig;
	hadc1.Instance = ADC1;
	hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
	hadc1.Init.ContinuousConvMode = DISABLE;//我们使用不连续模式,则每想转换一次ADC,就要调用HAL_ADC_Start(&hadc1);函数
	hadc1.Init.NbrOfConversion = 1;
	hadc1.Init.DiscontinuousConvMode = DISABLE;//不用(不连续采用模式,只适用于扫描模式)间断模式
	hadc1.Init.NbrOfDiscConversion = 0;
	hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;//软件触发
	HAL_ADC_Init(&hadc1);
	
	HAL_ADCEx_Calibration_Start(&hadc1);//开启校准
	
	ADC_sConfig.Channel = ADC_CHANNEL_11;
	ADC_sConfig.Rank	  = ADC_REGULAR_RANK_1;
	ADC_sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
	HAL_ADC_ConfigChannel(&hadc1, &ADC_sConfig);

}


uint32_t ADC_Single_CONVERT_START()
{
	HAL_ADC_Start(&hadc1);
	HAL_ADC_PollForConversion(&hadc1,1);//计算的到转换时间为21us,所以这里给1ms绰绰有余
	return HAL_ADC_GetValue(&hadc1);
}

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "usart.h"
#include "adc.h"
#include "stdio.h"






uint32_t time;
int main(void)
{
  uint16_t adc_tem;
  float adc_value;
  HAL_Init();                              /* 初始化HAL库 */
  sys_stm32_clock_init(RCC_PLL_MUL9);      /* 设置时钟, 72Mhz */
  delay_init(72);                          /* 延时初始化 */
	USART_Init(115200);
	DAC_Init();
	DAC_SET_VALUE(3000);
	ADC_Single_Init();

    while(1)
    { 
			adc_temp=ADC_Single_CONVERT_START();
			adc_value=adc_temp*3.3/4096;
			printf("PC1\nadc_temp->%d\nadc_value->%.5f v\n\n\n\n",adc_temp,adc_value);
			HAL_Delay(1000);
	}
}


### 使用 HAL 进行 DAC 操作 在 STM32 微控制器系列中,硬件抽象层 (HAL) 提供了简化外设配置和使用的函数。对于 DAC 的操作,主要通过初始化结构体 `DAC_HandleTypeDef` 来完成设置。 #### 初始化 DAC 外设 为了启动 DAC 功能,需先创建并填充描述符实例句柄: ```c DAC_ChannelConfTypeDef sConfig = {0}; DAC_HandleTypeDef hdac; ``` 接着调用初始化函数来设定参数,例如通道选择、对齐方式等[^1]: ```c hdac.Instance = DAC1; // 或者 DAC2, 取决于具体芯片支持情况 if (HAL_DAC_Init(&hdac) != HAL_OK){ // 错误处理代码... } ``` 针对每个要启用的 DAC 通道,还需单独配置其属性: ```c sConfig.DAC_Trigger = DAC_TRIGGER_NONE; sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK){ // 错误处理代码... } ``` 上述代码片段展示了不带触发源且启用了输出缓冲器的一个典型单声道 DAC 配置案例[^1]。 #### 设置 DAC 输出电压值 一旦完成了必要的初始化工作之后,就可以利用下面的方法向指定通道写入数据从而改变模拟信号电平了: ```c uint32_t value = 2048; /* 假定采用12位分辨率 */ if(HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,value)!= HAL_OK){ // 错误处理代码... } ``` 这里假设设备具有 12-bit 的精度范围,则输入数值应介于 0 至 4095 之间[^1]。 #### 启动/停止 DAC 转换过程 最后,在实际应用当中可能还需要控制何时开始或暂停转换动作: ```c // 开始生成波形 HAL_DAC_Start(&hdac, DAC_CHANNEL_1); // ...一段时间过后... // 结束当前活动 HAL_DAC_Stop(&hdac, DAC_CHANNEL_1); ``` 这些 API 函数允许程序灵活地管理 DAC 工作状态,满足不同应用场景下的需求[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值