完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
DAC 简介
Stm32f4内嵌的DAC是12位数字输入,电压输出的数模转换器。DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压VREF+以获得更精确的转换结果。 主要特点: 2个DAC转换器:每个转换器对应1个输出通道 8位或者12位单调输出 12位模式下数据左对齐或者右对齐 同步更新功能 噪声波形生成 三角波形生成 双DAC通道同时或者分别转换 每个通道都有DMA功能 外部触发转换 输入参考电压VREF+ DAC框图 VDDA:模拟电源输入 VSSAL:模拟电源接地输入 Vref+:正模拟参考电压输入 DORx:输入数字寄存器 DAC_OUT:模拟输出通道 DAC_OUT1 ->PA4 DAC_OUT2 ->PA5 寄存器 ### 过程 软件将数据加载到DAC_DHRx寄存器 写入的数据将移位并存储到相应的 DHRx(数据保 持寄存器 x,即内部非存储器映射寄存器) 根据是否选择硬件触发,DHRx 寄存器将被自动加载,或者通过软件或外部事件触发加载到 DORx 寄存器的数据在 t SETTLING 时间后给模拟输出电压 时序: 如果未选择硬件触发: (DAC_CR 寄存器中的 TENx 位复位) 经过一个 APB1 时钟周期后, DAC_DHRx寄存器中存储的数据将自动转移到 DAC_DORx 寄存器。 如果选择硬件触发 (置位 DAC_CR 寄存器中的 TENx位)且触发条件到来 将在三个 APB1 时钟 周期后进行转移。 当 DAC_DORx 加载了 DAC_DHRx内容时,模拟输出电压将在一段时间 t SETTLING 后可用,具体时间取决于电源电压和模拟输出负载。 数据保持寄存器 对于 DAC 单通道 x,有三种可能的方式: 8 位右对齐:软件必须将数据加载到 DAC_DHR8Rx [7:0] 位(存储到 DHRx[11:4] 位)。 12 位左对齐:软件必须将数据加载到 DAC_DHR12Lx [15:4] 位(存储到 DHRx[11:0] 位)。 12 位右对齐:软件必须将数据加载到 DAC_DHR12Rx [11:0] 位(存储到 DHRx[11:0] 位)。 DAC 输出电压 经过线性转换后,数字输入会转换为 0 到 VREF+ 之间的输出电压。 各 DAC 通道引脚的模拟输出电压通过以下公式确定: 代码配置 设置步骤: 设置相关GPIO(PA4、5)。 若时钟源为TIMx更新事件,则设置TIMx。 使能DAC时钟 设置触发源,开启相关触发通道,如果用DMA,是否允许数据错误中断。 如果用DMA。配置相关DMA数据流。 #include"stm32f4xx.h" #include"sys.h" #include static GPIO_InitTypeDef GPIO_InitStructure; static NVIC_InitTypeDef NVIC_InitStructure; static USART_InitTypeDef USART_InitStructure; static ADC_InitTypeDef ADC_InitStructure; static ADC_CommonInitTypeDef ADC_CommonInitStructure; static DAC_InitTypeDef DAC_InitStructure; void delay_ms(uint32_t n) { while(n--) { SysTick->CTRL = 0; // Disable SysTick,关闭系统定时器 SysTick->LOAD = (168000)-1; // 配置计数值(168000)-1 ~ 0 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 5; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x10000)==0);// Wait until count flag is set } SysTick->CTRL = 0; // Disable SysTick } void delay_us(uint32_t n) { while(n--) { SysTick->CTRL = 0; // Disable SysTick,关闭系统定时器 SysTick->LOAD = (168)-1; // 配置计数值(168000)-1 ~ 0 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 5; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x10000)==0);// Wait until count flag is set } SysTick->CTRL = 0; // Disable SysTick } void usart1_init(uint32_t baud) { //端口A硬件是能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //串口硬件是能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF ; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL; GPIO_Init(GPIOA,&GPIO_InitStructure); //PF9应交连接到串口 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //配置串口 USART_InitStructure.USART_BaudRate = baud;//波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//数据为 USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶效验为 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//串口方式 允许收发数据 USART_Init(USART1, &USART_InitStructure); //配置中断触发方式 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //配置终端优先级 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //使能串口工作 USART_Cmd(USART1, ENABLE); } void dac_init() { RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);//使能 DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;//dac出发模式,不需要脉冲触发工作 DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;//不输出波形 DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;//应许输出电压 DAC_Init(DAC_Channel_1, &DAC_InitStructure); DAC_Cmd(DAC_Channel_1, ENABLE);//使能adc输出 } void adc_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//使能ADC RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //配置端口模式 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_NOPULL; GPIO_Init(GPIOA,&GPIO_InitStructure); ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立工作模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//分屏 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;//不需要映射数据 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//精度 ADC_InitStructure.ADC_ScanConvMode = DISABLE;//单通道,否则为多通道 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//不断的转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//不需要内部脉冲出发 // ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐存储 ADC_InitStructure.ADC_NbrOfConversion = 1;//几个转换通道 ADC_Init(ADC1,&ADC_InitStructure); //通道链接PA5 ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_56Cycles); ADC_Cmd(ADC1,ENABLE); } struct __FILE{int handle;}; FILE __stdout; FILE __stdin; int fputc(int ch,FILE *f) { USART_SendData(USART1,ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return ch; } int main(void) { uint16_t adc_val,adc_v; //波特率为115200 usart1_init(115200); printf("ADC testrn"); adc_Init(); dac_init(); DAC_SetChannel1Data(DAC_Align_12b_R,1650*4095/3300); //out=vcc(3300)*ODR/4095 ADC_SoftwareStartConv(ADC1);//启动ADC1转换 delay_ms(1000); while(1) { //等待转换完毕 while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET); ADC_ClearFlag(ADC1,ADC_FLAG_EOC); adc_val=ADC_GetConversionValue(ADC1); adc_v=adc_val*3300/4095; printf("电压为:%dmvrn",adc_v); printf("剩余点亮%d%% rn",adc_v/33); delay_ms(1000); } } void USART1_IRQHandler(void) { uint8_t d=0; //判断标志位i if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET) { d=USART_ReceiveData(USART1); // if(d==0x01)PFout(10)=0; if(d==0xf1)PFout(10)=1; USART_ClearITPendingBit(USART1,USART_IT_RXNE); } //清空标志位 } |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3458 浏览 1 评论
9000 浏览 16 评论
4051 浏览 18 评论
1110浏览 3评论
572浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
569浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2302浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1859浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 18:16 , Processed in 1.104052 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号