DAC数模转换:将数字信号转换成模拟信号
特性:2个DAC转换器每个都拥有一个转换通道
8位或12位单调输出(8位右对齐;12位左对齐右对齐)
双ADC通道同时或者分别转换
外部触发中断
- 电压源
- 控制部分(外部触发3个APB1;不使用1个APB1)
- 外部触发
- 输出:DAC1-PA4;DAC2-PA5
软件设计流程:
- 使能端口以及DAC时钟;设置引脚为模拟输入
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟量输入
- 初始化DAC,设置DAC工作模式(触发选择;DAC波形发生;屏蔽\幅值选择器;DAC输出)
typedef struct
{uint32_t DAC_Trigger; /*!< 指定所选DAC通道的外部触发源此参数可以是 @ref DAC_trigger_selection 中的一个值 */uint32_t DAC_WaveGeneration; /*!< 指定是否生成DAC通道的噪声波或三角波,或不生成任何波形此参数可以是 @ref DAC_wave_generation 中的一个值 */uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< 指定噪声波生成的LFSR掩码或DAC通道的三角波最大生成幅度此参数可以是 @ref DAC_lfsrunmask_triangleamplitude 中的一个值 */uint32_t DAC_OutputBuffer; /*!< 指定是否启用或禁用DAC通道的输出缓冲器此参数可以是 @ref DAC_output_buffer 中的一个值 */
}DAC_InitTypeDef;
- 使能DAC输出通道
DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1
- 设置DAC输出值
/*** @brief 设置DAC通道1的转换数据* @param DAC_Align: 指定数据对齐方式* 该参数可以是 @ref DAC_data_align 中的一个值,例如:* - DAC_Align_8b_R: 8位右对齐* - DAC_Align_12b_L: 12位左对齐* - DAC_Align_12b_R: 12位右对齐* @param Data: 要转换的数字值* - 对于8位右对齐,有效范围为0~255(0x00~0xFF)* - 对于12位右对齐,有效范围为0~4095(0x000~0xFFF)* - 对于12位左对齐,有效范围同样为0~4095,但数据需左移4位* @retval 无* @note 写入的数据将在下次触发事件(如软件触发或定时器触发)时转换为模拟电压* 转换后的电压值 = (Data / 满量程值) × VREF+* 例如,对于12位DAC且VREF+=3.3V,Data=2048对应电压1.65V*/
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)
代码如下:
#include "dac.h"/*******************************************************************************
* 函 数 名 : DAC1_Init
* 函数功能 : DAC1初始化函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DAC1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef DAC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//DAC_1GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟量输入GPIO_Init(GPIOA,&GPIO_InitStructure);DAC_InitStructure.DAC_Trigger=DAC_Trigger_None; //不使用触发功能 TEN1=0DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1输出缓存关闭 BOFF1=1DAC_Init(DAC_Channel_1,&DAC_InitStructure); //初始化DAC通道1DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12位右对齐数据格式设置DAC值DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1}
主函数代码:(按键按下,DAC写入转换值)
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "key.h"
#include "dac.h"/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
int main()
{u8 i=0;u8 key;int dac_value=0;u16 dacval;float dac_vol;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组LED_Init();USART1_Init(115200);KEY_Init();DAC1_Init();while(1){key=KEY_Scan(0);//单次按下if(key==KEY_UP_PRESS){dac_value+=400;if(dac_value>=4000){dac_value=4095;}DAC_SetChannel1Data(DAC_Align_12b_R,dac_value);//写入4095}else if(key==KEY1_PRESS){dac_value-=400; if(dac_value<=0){dac_value=0;}DAC_SetChannel1Data(DAC_Align_12b_R,dac_value); }i++;if(i%20==0){LED1=!LED1;}if(i%50==0){dacval=DAC_GetDataOutputValue(DAC_Channel_1);dac_vol=(float)dacval*(3.3/4096);printf("输出DAC电压值为:%.2fV\r\n",dac_vol);}delay_ms(10); }
}