本文主要是介绍DAC数模转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 数模转换原理
- DAC模块主要特点
- DAC引脚
- DAC转换
- DAC数据格式
- DAC触发选择
- DAC输出电压
- DAC通道使能
- DAC输出缓冲器使能
- DAC通道1 相关寄存器
- DAC控制寄存器 DAC_CR
- DAC 通道1的12位右对齐数据保持寄存器DAC_DHR12R1
- DAC 通道1的12位左对齐数据保存寄存器DAC_DHR12L1
- DAC通道1的8位右对齐数据保存寄存器DAC_DHR8R1
- 硬件连接
- DAC配置步骤
- 相关代码
数模转换原理
DAC模块(数字/模拟转换模块)是12位数字输入,电压输出型。可以配置8位 12位 模式,也可与DMA控制器配合使用。12位模式下,可以设置成左对齐或右对齐。DAC模块有2个输出通道,各有单独的转换器。双DAC模式下2个通道可以独立的进行转换,也可以同时进行转换并同步的更新2个通道的输出。
DAC模块主要特点
① 2个DAC转换器:每个转换器对应1个输出通道
② 8位或者12位单调输出
③ 12位模式下数据左对齐或者右对齐
④ 同步更新功能
⑤ 噪声波形生成
⑥ 三角波形生成
⑦ 双DAC通道同时或者分别转换
⑧ 每个通道都有DMA功能
DAC引脚
避免电流消耗,应先将PA4或PA5引脚配置为模拟模式。
DAC_OUT1对应PA4
DAC_OUT2对应PA5
DAC转换
DAC_DORx寄存器无法直接写入,所有数据必须加载DAC_DHRx寄存器(写入DAC_DHR8Rx、DAC_DHR12Lx、DAC_DHR12Rx、DAC_DHR8RD、DAC_DHR12LD或DAC_DHR12LD)才能传输到DAC通道x。
未选择硬件触发(DAC_CR寄存器中的TENx位复位),则经过一个APB1时钟周期后,DAC_DHRx寄存器中存储的数据将自动转移到DAC_DORx寄存器。选择了硬件触发且有触发条件,在三个APB1时钟周期后进行转移。
当DAC_DORx加载了DAC_DHRx内容时,模拟输出电压将在一段时间t(SETTLING)后可用,具体时间取决于电源电压和模拟输出负载。
DAC数据格式
有三种情况
① 8位数据右对齐:用户须将数据写入寄存器DAC_DHR8Rx【7:0】位,最终转存到DHRx【11:4】位
② 12位数据左对齐:用户需将数据写入寄存器DAC_DHRLx【15:4】位,最终转存到DHRx【11:0】位
③ 12位数据右对齐:用户须将数据写入寄存器DAC_DHR12Rx【11:0】位,最终转存到DHRx【11:0】位。
DAC触发选择
TENx控制位置1 可通过外部事件触发转换。通过TSELx【2:0】控制位决定8个可能事件中的哪一个来触发转换。
DAC接口检测到上升沿时,DAC_DHRx寄存器中存储的最后一个数据即会转换到DAC_DORx寄存器中。触发后三个APB1周期DAC_DORx寄存器会得到更新。
SWTRIG位置为 1 转换开始 DAC_DHRx寄存器内容加载到DAC_DORx 寄存器中后,SWTRIG即由硬件复位。
DAC输出电压
线性转换后,数字输入会转换为0-V(REF+)之间的输出电压
模拟输出电压公式:
DAC(output) = V(REF) * DOR/4095
DAC通道使能
将DAC_CR寄存器中的相应ENx 位置1,即可接通对应DAC通道。经过一段启动时间t(WAKEUP)后,DAC通道被真正使能)
ENx位只能使能模拟DAC Channelx宏单元,即使ENx位复位,DAC Channelx数字接口仍处于使能状态
DAC输出缓冲器使能
DAC继承了两个输出缓冲器,可降低输出阻抗并不增加运算放大器的情况下直接驱动外部负载。
DAC通道1 相关寄存器
DAC控制寄存器 DAC_CR
DAC 通道1的12位右对齐数据保持寄存器DAC_DHR12R1
DAC 通道1的12位左对齐数据保存寄存器DAC_DHR12L1
DAC通道1的8位右对齐数据保存寄存器DAC_DHR8R1
硬件连接
DAC配置步骤
① 开启PA口时钟,设置PA4为模拟输入
DAC通道1 接在PA4上,则先使能GPIOA,然后设置PA4为模拟输入
RCC_AHB1PeriphClockCmd(RCC_AHBIPeriph_GPIOA, ENABLE)://
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_IniStructure.GPIO_Mode = GPIO_Mode_AN://模拟输入
GPIO_InitStructure.GPlO_PuPd = GPIO_PuPd_DOWN://下拉
GPIO_Init(GPIOA, &GPIO_InitStructure)//初始化
② 使能DAC1时钟
DAC模块时钟由APB1提供,则先使能DAC1时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);//使能DAC时钟
③ 初始化DAC,设置DAC的工作模式
DAC初始化 :DAC_Init
其他全部通过DAC_CR设置实现
void DAC_Init(uint32_t DAC_Channel,DAC_InitTypcDef DAC_InitStruct);typedef struct
{
uint32_t DAC_Trigger;
uint32_t DAC_WaveGeneration;
uint32_t DAC_LFSRUnmask_TriangleAmplitude;
uint32_t DAC_OutputBuffer;
}
DAC InitTypeDef:
④ 使能DAC转换通道
DAC_Cmd(DAC_Channel_1,ENABLE);//使能DAC通道1
⑤ 设置DAC的输出值
使用12位右对齐数据格式 设置DHR12R1
DAC_SetChannel1Data(DAC_Align_12b_R,0);
相关代码
int main(void)
{ u16 adcx;float temp;u8 t=0; u16 dacval=0;u8 key; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);delay_init(168); uart_init(115200); LED_Init(); LCD_Init(); Adc_Init(); KEY_Init(); Dac1_Init(); POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"Explorer STM32F4"); LCD_ShowString(30,70,200,16,16,"DAC TEST"); LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,110,200,16,16,"2021/9/4"); LCD_ShowString(30,130,200,16,16,"WK_UP:+ KEY1:-"); POINT_COLOR=BLUE;//ÉèÖÃ×ÖÌåΪÀ¶É« LCD_ShowString(30,150,200,16,16,"DAC VAL:"); LCD_ShowString(30,170,200,16,16,"DAC VOL:0.000V"); LCD_ShowString(30,190,200,16,16,"ADC VOL:0.000V");DAC_SetChannel1Data(DAC_Align_12b_R,dacval);while(1){t++;key=KEY_Scan(0); if(key==WKUP_PRES){ if(dacval<4000)dacval+=200;DAC_SetChannel1Data(DAC_Align_12b_R, dacval);}else if(key==2) {if(dacval>200)dacval-=200;else dacval=0;DAC_SetChannel1Data(DAC_Align_12b_R, dacval);} if(t==10||key==KEY1_PRES||key==WKUP_PRES) { adcx=DAC_GetDataOutputValue(DAC_Channel_1);LCD_ShowxNum(94,150,adcx,4,16,0); temp=(float)adcx*(3.3/4096); adcx=temp;LCD_ShowxNum(94,170,temp,1,16,0); temp-=adcx;temp*=1000;LCD_ShowxNum(110,170,temp,3,16,0X80); adcx=Get_Adc_Average(ADC_Channel_5,10); temp=(float)adcx*(3.3/4096); adcx=temp;LCD_ShowxNum(94,190,temp,1,16,0); temp-=adcx;temp*=1000;LCD_ShowxNum(110,190,temp,3,16,0X80); LED0=!LED0; t=0;} delay_ms(10); }
}
这篇关于DAC数模转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!