T型电阻网络办法是一种常见的DAC实现方法,由T型电阻网络和运算放大器组成,下图是8位DAC的事理示意图。输入数字量中的每位都按其权值分别转换为仿照量,之后通过运算放大器求和相加。
图1:T型电阻网络示意图
上图中,由于运算放大器的反相输入端为“虚地”,以是无论仿照开相干接到“0”还是 “1”,从T形电阻网络节点对“地”往右看的等效电阻均为R,由此可打算出基准电流I=VREF/R。再根据电流可打算出流过各个分支的电流从右向左(I0~I7)依次是I/2、I/4、I/8、I/16、I/32、I/64、I/128和、I/256。

由此,每一位数字量都发挥了有效的位权,流向运算放大器反相输入真个总电流如下:
该电流经由运算放大器换成仿照电压输出,从而实现由数字旗子暗记到仿照旗子暗记的转换。这里以8位DAC示例,输出电压有256种变革,当然,这种T形电阻网络的转换事理可以推广到n位,实现n位DAC。
市情上很多单片机片内集成了DAC外设,并且也有专用独立DAC芯片供用户选择利用,那为什么还须要利用PWM实现DAC?
这是由于虽然市情上很多集成了DAC的单片机和独立DAC芯片,他们利用起来更方便,并且精度也高,但是很多时候,我们并不须要很高的精度,我们选择利用的单片机可能没有DAC外设,但是一样平常都有PWM,因此,出于对本钱的考虑,我们会利用PWM实现DAC,从而节省本钱。
硬件电路设计STC8A8K64D4系列单片机片内没有集成DAC外设,因此,IK-64D4开拓板通过PCA事情于PWM模式输出高速PWM脉冲合营RC滤波电路实现DAC功能。
实现DAC转换是基于将高速PWM旗子暗记通过RC电路整合成比较平缓的电压旗子暗记作为仿照输出,通过改变高速PWM旗子暗记的占空比达到改变输出电平旗子暗记幅度的目的。为了达到比较空想的电压旗子暗记输出,P7.0口输出的PWM旗子暗记经二阶RC滤波电路整合,如下图所示。
图2:PWM实现DAC电路
注:开拓板J27端子需利用短路帽短接P06和DAC_O以及P70和DAC_I,并且将J27端子的P06和ADC以及P70和DHT11的短路帽去掉。软件设计PWM实现DAC实验注:本节的实验是在“实验2-11-1:ADC采样电位器电压(查询办法)”的根本上修正,本节对应的实验源码是:“实验2-17-1: PWM实现DAC实验”。关于PWM的内容,读者可以参阅《第2-16讲:可编程计数器阵列PCA》中的PCA实现PWM部分的内容。实验内容配置PCA模块0事情于PWM模式, PCA配置如下:
系统时钟:24MHz。PCA时钟源:系统时钟= 24Mhz。功能引脚:P7.0。中断:不开启中断。PWM位数:8位。程序运行后,在主循环中不断改变PWM的占空比,从而改变P7.0输出的电压值。实验中为了方便不雅观察实验征象,配置P0.6为ADC功能引脚,并通过跳线帽将其连接到DAC电路的输出端,这样,就可以实时获取DAC输出的电压值并通过串口输出,以便于我们不雅观察实验征象(DAC输出电压值的改变)。
代码编写新建一个名称为“pca.c”的文件及其头文件“pca.h”并保存到工程的“Source”文件夹,并将“pca.c”加入到Keil工程中的“SOURCE”组。引用头文件由于在“pca.c”文件中利用了“pca.c”文件中的函数,以是须要引用下面的头文件“pca.h”。
代码清单:引用头文件
//引用pca的头文件 #include " pca.h" PCA初始化本例中,我们配置PCA模块0事情于PWM模式,PCA时钟源利用系统时钟(24Mhz),功能引脚为P7.0,代码清单如下。
代码清单:PCA初始化
/ 描 述 : PCA初始化 入 参 : 无 返回值 : 无 / void pca_init(void) { CCON = 0x00; //CF、CR、CCF1、CCF0位均清零 P_SW1 &= 0xEF; //PCA模块0功能引脚选择P7.0 P_SW1 |= 0x20; /--------------------PCA模式寄存器CMOD配置--------------------------- 位7 位6 位5 位4 位3~位1 位0 CIDL x x x CPS[2~0] BCF 0 x x x 100 0 CIDL=0:空闲模式下仍旧计数 CPS[2~0]=100:PCA时钟源选择:系统时钟 BCF=0:禁止PCA计数器溢出中断 -----------------------------END------------------------------------/ CMOD = 0x08; CL = 0x00; //PCA计数器赋初值 CH = 0x00; //PCA计数器赋初值 IP &= ~0x02; //中断优先级配置为2(较高优先级) IPH |= 0x02; /------------------PCA模块0模式掌握寄存器CCAPM0配置------------------ 位7 位6 位5 位4 位3 位2 位1 位0 x ECOM0 CCAPP0 CCAPN0 MAT0 TOG0 PWM0 ECCF0 x 0 0 0 0 0 1 0 ECOM0=0:关闭PCA模块0的比较功能 CCAPP0=0:关闭PCA模块0的上升沿捕获 CCAPN0=0:关闭PCA模块0的低落沿捕获 MAT0=0:关闭PCA模块0的匹配功能 TOG0=0:关闭PCA模块0的高速脉冲输出功能 PWM0=1:开启PCA模块0的脉宽调制输出功能 ECCF0=0:禁止PCA模块0的匹配/捕获中断 -----------------------------END------------------------------------/CCAPM0 = 0x02;PCA_PWM0 &= 0x3F; //PCA模块0事情于8位PWM功能 PCA_PWM0 &= 0xFC; //EPC0H位和EPC0L位置0 CCAP0L = 0x00; //PCA比较值寄存器赋初值 CCAP0H = 0x00; //PCA比较值寄存器赋初值 CR = 1; //启动PCA计数器阵列计数 } 主函数主函数中初始化PCA和ADC,PCA计数启动后,在主循环中不断改变PWM的占空比,使得DAC输出不同的电压。
ADC采样DAC输出的电压值后,通过串口输出采样值及其对应的电压值,代码清单如下。
代码清单:主函数
/ 描 述 : 主函数 入 参 : 无 返回值 : 无 / int main(void) { u16 adc_value; //存放ADC采样值 float voltage; //存放ADC采样值打算后的电压值 u16 TempData; P2M1 &= 0xBF; P2M0 &= 0xBF; //设置P2.6为准双向口(LED1) P3M1 &= 0xFE; P3M0 &= 0xFE; //设置P3.0为准双向口(串口1的RxD) P3M1 &= 0xFD; P3M0 |= 0x02; //设置P3.1为推挽输出(串口1的TxD) P7M1 &= 0xFE; P7M0 |= 0x01; //设置P7.0为推挽输出 pca_init(); uart1_init(); //串口1初始化 adc_config(); //初始化ADC EA = 1; //使能总中断 while(1) { TempData++; CCAP0H = (u8)(256 - TempData); //P7.0引脚输出频率不变但占空比不断变革的脉冲旗子暗记 if(TempData>138)TempData=1; //占空比达到很大时重新设定占空比 delay_ms(5); adc_value = get_adc_value(); //读取ADC采样值 voltage = (2.5adc_value)/4096; //将ADC采样值转换为电压(单位V) printf("ADC采样值: %d\r\n",adc_value); //串口打印上传的采集的原始值 printf("采样值对应的电压:%.2fV\r\n",voltage);//串口打印ADC采样电压 delay_ms(200); //延时200ms,方便不雅观察数据 led_toggle(LED_1); //翻转指示灯D1状态,指示一次ADC采样完成 } } 硬件连接本实验通过P7.0输出PWM旗子暗记实现DAC输出,P0.6配置为ADC用于采样DAC电路输出的电压,按照下图所示连接跳线帽。
图3:硬件连接
实验步骤解压“…\第3部分:配套例程源码”目录下的压缩文件“实验2-17-1: PWM实现DAC实验”,将解压后得到的文件夹拷贝到得当的目录,如“D\STC8”(这样做的目的是为了防止中文路径或者工程存放的路径过深导致打开工程涌现问题)。双击“…\pca_dac\project”目录下的工程文件“pca_dac.uvproj”。点击编译按钮编译工程,编译成功后天生的HEX文件“pca_dac.hex”位于工程的“…\pca_dac\Project\Object”目录下。打开STC-ISP软件下载程序,下载利用内部IRC时钟,IRC频率选择:24MHz。电脑上打开串口调试助手,选择开拓板对应的串口号,将波特率设置为9600bps。程序运行后,在串口吸收窗口可以看到开拓板上报的ADC采样值及其对应的电压值,如下图所示。图4:串口调试助手中不雅观察电压值