10、DAC
1、DAC介绍
数字/模拟转换模块(DAC)是12位数字输入,电压输出的数字/模拟转换器。DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压VREF+ 以获得更精确的转换结果。
2、DAC主要特征
● 2个DAC转换器:每个转换器对应1个输出通道
● 8位或者12位单调输出
● 12位模式下数据左对齐或者右对齐
● 双DAC通道同时或者分别转换
● 每个通道都有DMA功能
● 外部触发转换
● 输入参考电压VREF+
3、DAC管脚
注意: 一旦使能DACx通道,相应的GPIO引脚(PA4或者PA5)就会自动与DAC的模拟输出相连(DAC_OUTx)。为了避免寄生的干扰和额外的功耗,引脚PA4或者PA5在之前应当设置成模拟输入(AIN)。
4、使能DAC通道
将DAC_CR寄存器的ENx位置’1’ 即可打开对DAC通道x 的供电。经过一段启动时间tWAKEUP,DAC通道x 即被使能。
注意: ENx位只会使能DAC通道x的模拟部分,即便该位被置’0’,DAC通道x的数字部分仍然工作。
5、使能DAC输出缓存
DAC集成了2个输出缓存,可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载。每个DAC通道输出缓存可以通过设置DAC_CR寄存器的BOFFx位来使能或者关闭。
6、 DAC输出电压
数字输入经过DAC被线性地转换为模拟电压输出,
其范围为0到VREF+ 。
任一DAC通道引脚上的输出电压满足下面的关系:
DAC输出 = VREF x (DOR / 4095) 。
7、DAC数据格式
根据选择的配置模式,数据按照下文所述写入指定的寄存器: ─ 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_DHRyyyx寄存器的操作,经过相应的移位后,写入的数据被转存到DHRx寄存器中(DHRx是内部的数据保存寄存器x) 。随后,DHRx寄存器的内容或被自动地传送到DORx寄存器,或通过软件触发或外部事件触发被传送到DORx寄存器。
8、选择DAC触发
如果TENx位被置1,DAC转换可以由某外部事件触发(定时器计数器、外部中断线)。配置控制位TSELx[2:0] 可以选择8个触发事件之一触发DAC转换。
每次DAC接口侦测到来自选中的定时器TRGO输出,或者外部中断线9的上升沿,最近存放在寄存器DAC_DHRx中的数据会被传送到寄存器DAC_DORx中。在3个APB1 时钟周期后,寄存器 DAC_DORx更新为新值。
如果选择软件触发,一旦SWTRIG位置’1’ ,转换即开始。在数据从DAC_DHRx寄存器传送到DAC_DORx寄存器后,SWTRIG位由硬件自动清’0’。
9、例程代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************************************************************************************* 2 * 3 * 文件名称:main.c 4 * 文件功能:主函数文件 5 * 6 ***************************************************************************************************************************************/ 7 8 #include "pbdata.h"//调用自定义公共函数库 9 10 11 /********************************************************************************* 12 * 13 * 初始化操作 14 * 15 *********************************************************************************/ 16 void RCC_Configuration(void);//系统时钟初始化函数声明 17 void GPIO_Configuration(void);//GPIO初始化函数声明 18 void NVIC_Configuration(void);//中断优先级配置函数声明 19 void USART_Configuration(void);//串口配置函数声明 20 void DAC_Configuration(void);//DAC配置函数声明 21 22 23 24 /******************************************************************************** 25 * 26 * 函数名称:main(void) 27 * 函数功能:主函数 28 * 函数说明:不能用void定义主函数 29 * 30 ********************************************************************************/ 31 int main(void)//void不能void定义主函数 32 { 33 34 RCC_Configuration(); //系统时钟初始化 35 36 GPIO_Configuration();//端口初始化 37 38 USART_Configuration();//串口配置 39 40 NVIC_Configuration(); 41 42 DAC_Configuration();//DAC配置 43 44 45 while(1) 46 { 47 u8 i=0; 48 float da=0; 49 50 for(i=0;i<=10;i++) 51 { 52 da=i*400;//范围4096 53 54 DAC_SetChannel1Data(DAC_Align_12b_R,da);//12位右对齐,设置初值0 55 56 printf("da=%f v\n",3.3*da/4095);//输出电压 57 58 delay_ms(1000); 59 delay_ms(1000); 60 delay_ms(1000); 61 delay_ms(1000); 62 delay_ms(1000); 63 } 64 65 66 } 67 68 } 69 70 71 72 73 /******************************************************************************** 74 * 75 * 函数名称:RCC_Configuration(void) 76 * 函数功能:系统时钟高初始化函数 77 * 78 ********************************************************************************/ 79 void RCC_Configuration(void)//系统时钟高初始化函数 80 { 81 82 SystemInit();//系统初始化 83 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//串口对应GPIO时钟使能 84 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口时钟使能 85 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//引脚复用 86 87 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);//DAC时钟使能 88 89 } 90 91 92 93 /******************************************************************************* 94 * 95 * 函数名称:GPIO_Configuration(void) 96 * 函数功能:GPIO初始化函数 97 * 98 ********************************************************************************/ 99 100 void GPIO_Configuration(void)//GPIO初始化函数 101 { 102 103 104 /*串口引脚配置*/ 105 GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO设置的结构体变量 106 107 /*输出引脚配置*/ 108 /*结构体变量赋值*/ 109 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;////引脚配置TX 110 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//配置频率 111 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//发送要配置成复用推挽输出 112 /*对应的GPIO初始化*/ 113 GPIO_Init(GPIOA,&GPIO_InitStructure); 114 115 116 /*输入引脚配置*/ 117 /*结构体变量赋值*/ 118 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;////引脚配置RX 119 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//接收引脚配置成浮空输入 120 /*对应的GPIO初始化*/ 121 GPIO_Init(GPIOA,&GPIO_InitStructure); 122 123 /*DAC输入引脚配置*/ 124 /*结构体变量赋值*/ 125 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;////引脚配置adc 126 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟输入 127 /*对应的GPIO初始化*/ 128 GPIO_Init(GPIOA,&GPIO_InitStructure); 129 130 GPIO_SetBits(GPIOA,GPIO_Pin_4);//输出为高 131 132 133 } 134 135 136 /******************************************************************************** 137 * 138 * 函数名称:NVIC_Configuration(void) 139 * 函数功能:配置中断优先级 140 * 141 ********************************************************************************/ 142 143 void NVIC_Configuration(void) 144 { 145 NVIC_InitTypeDef NVIC_InitStructure; //定义一个优先级配置结构体变量 146 147 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//分组 148 149 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 150 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢断优先级 151 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级 152 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能 153 154 NVIC_Init(&NVIC_InitStructure);//初始化 155 } 156 157 158 /********************************************************************************* 159 * 160 * 函数名称:USART_Configuration(void) 161 * 函数功能:串口配置函数 162 * 163 *********************************************************************************/ 164 void USART_Configuration(void) 165 { 166 /*定义串口配置结构体变量*/ 167 USART_InitTypeDef USART_InitStructure;//定义一个串口配置结构体变量 168 169 170 /*结构体变量赋值*/ 171 USART_InitStructure.USART_BaudRate = 9600;//波特率9600 172 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//位宽,8位 173 USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位1 174 USART_InitStructure.USART_Parity = USART_Parity_No;//不奇偶校验 175 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//流控禁止 176 USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//发送使能 177 178 179 /*发送串口配置初始化*/ 180 USART_Init(USART1, &USART_InitStructure); 181 182 183 /*打开串口接收中断*/ 184 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//当接收到数据时,会产生中断 185 186 187 /*打开串口*/ 188 USART_Cmd(USART1,ENABLE);//串口使能,打开 189 190 /*清空中断标志位*/ 191 USART_ClearFlag(USART1,USART_FLAG_TC); 192 } 193 194 195 196 /********************************************************************************* 197 * 198 * 函数名称:DAC_Configuration(void) 199 * 函数功能:DAC配置函数 200 * 201 *********************************************************************************/ 202 void DAC_Configuration(void) 203 { 204 DAC_InitTypeDef DAC_Initstructure; 205 206 DAC_Initstructure.DAC_Trigger=DAC_Trigger_None;//不使用触发功能 207 DAC_Initstructure.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用三角波 208 DAC_Initstructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0; //屏蔽幅值设置 209 DAC_Initstructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable;//关闭缓存 210 211 DAC_Init(DAC_Channel_1,&DAC_Initstructure);//DAC初始化 212 213 DAC_Cmd(DAC_Channel_1,ENABLE);//使能DAC1 214 215 DAC_SetChannel1Data(DAC_Align_12b_R,0);//12位右对齐,设置初值0 216 217 } 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /**************************************************************************************************************** 2 * 3 * 文件名称:pbdata.c 4 * 文件功能:自定义函数或者全局变量的初始化 5 * 6 ****************************************************************************************************************/ 7 8 /*头文件声明*/ 9 #include "pbdata.h" 10 11 12 13 14 /******************************************************************************************** 15 * 16 * 自定义全局变量 17 * 18 ********************************************************************************************/ 19 u8 dt=0; 20 21 22 23 24 25 /****************************************************************************************** 26 * 27 * 自定义函数 28 * 29 ******************************************************************************************/ 30 31 32 33 /************************************************** 34 * 35 * 函数名称:delay_us(u32 nus) 36 * 函数功能:微秒延时函数 37 * 输入参数:输入值为延时us 38 * 39 ***************************************************/ 40 void delay_us(u32 nus) 41 { 42 u32 temp; 43 SysTick->LOAD = 9*nus;//载入初值,72M/8=9M,也就是1/9us,9*1/9us,所以是执行9次 44 SysTick->VAL=0X00;//清空计数器,清空后,就自动设置自己设定的计数器的值 45 SysTick->CTRL=0X01;//使能,减到零动作(不发生中断),采用外部时钟 46 47 do 48 { 49 temp=SysTick->CTRL;//标志位,等到一直减到0 50 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 51 52 SysTick->CTRL=0x00; //关闭计数器 53 SysTick->VAL =0X00; //清空计数器 54 } 55 56 57 58 59 60 61 62 /*************************************************** 63 * 64 * 函数名称:delay_ms(u16 nms) 65 * 函数功能:毫秒级延时 66 * 输入参数:输入值位延时ms 67 * 68 ****************************************************/ 69 void delay_ms(u16 nms) 70 { 71 u32 temp; 72 SysTick->LOAD = 9000*nms;//载入初值,72M/8=9M,也就是1/9us,9*1/9us,所以是执行9000次 73 SysTick->VAL=0X00;//清空计数器,清空后,就自动设置自己设定的计数器的值 74 SysTick->CTRL=0X01;//使能,减到零动作(不发生中断),采用外部时钟 75 76 do 77 { 78 temp=SysTick->CTRL;//标志位,等到一直减到0 79 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 80 81 SysTick->CTRL=0x00; //关闭计数器 82 SysTick->VAL =0X00; //清空计数器 83 } 84 85 86 87 /**************************************************** 88 * 89 * 重定义printf函数部分 90 * 91 ****************************************************/ 92 int fputc(int ch,FILE *F) 93 { 94 95 USART_SendData(USART1,(u8)ch); 96 97 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待发送完成,判断标志位 98 99 return ch; 100 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*pbdata.h*/ 2 /*************************************************************************************************** 3 * 4 * 文件名称:pbdata.h 5 * 文件功能:自定义的函数和全局变量的声明头文件 6 * 7 ***************************************************************************************************/ 8 9 #ifndef _pbdata_H 10 #define _pbdata_H 11 12 13 14 15 16 /******************************************************************** 17 * 18 * 调用的头文件放在这里 19 * 20 ********************************************************************/ 21 #include "stm32f10x.h" 22 23 24 #include "stm32f10x_rcc.h" 25 #include "stm32f10x_gpio.h" 26 #include "misc.h" 27 #include "stm32f10x_adc.h" 28 #include "stm32f10x_bkp.h" 29 #include "stm32f10x_can.h" 30 #include "stm32f10x_cec.h" 31 #include "stm32f10x_dac.h" 32 #include "stm32f10x_dbgmcu.h" 33 #include "stm32f10x_dma.h" 34 #include "stm32f10x_exti.h" 35 #include "stm32f10x_flash.h" 36 #include "stm32f10x_fsmc.h" 37 #include "stm32f10x_i2c.h" 38 #include "stm32f10x_iwdg.h" 39 #include "stm32f10x_pwr.h" 40 #include "stm32f10x_rtc.h" 41 #include "stm32f10x_sdio.h" 42 #include "stm32f10x_spi.h" 43 #include "stm32f10x_tim.h" 44 #include "stm32f10x_usart.h" 45 #include "stm32f10x_wwdg.h" 46 47 48 #include "stdio.h" 49 50 51 52 53 /******************************************************************** 54 * 55 * 自定义全局变量声明 56 * 57 ********************************************************************/ 58 extern u8 dt; 59 60 61 62 63 64 /******************************************************************** 65 * 66 * 自定义全函数声明 67 * 68 ********************************************************************/ 69 void delay(u32 nCount); 70 void delay_us(u32 nus); 71 void delay_ms(u16 nms); 72 int fputc(int ch,FILE *F); 73 74 75 76 #endif
10、
http://download.csdn.net/detail/a1181803348/8750147