单片机:DAC数模转换实验(内含DAC介绍+PWM介绍+硬件设计+软件设计+原始代码)

简介: 单片机:DAC数模转换实验(内含DAC介绍+PWM介绍+硬件设计+软件设计+原始代码)

f23a843211234b708adc1643f0290552.png

注:DAC芯片贵,一般用PWM代替DAC


0043460327d34403bfad0086e6eb66a2.png


1.DAC介绍:


999879c746d0418fa6ad4fa33ad8b7a8.png


1.分辨率:指输入数字量的最低有效位(LSB)发生变化时,所对应的输出模拟量(电压或电流)的变化量。它反映了输出模拟量的最小变化值。


分辨率与输入数字量的位数有确定的关系,可以表示成FS /(2^n)。FS表示满量程输入值,n为二进制位数。对于5V的满量程,采用8位的DAC时,分辨率为5V/256=19.5mV;当采用12位的DAC时,分辨率则为5V/4096=1.22mV。显然,位数越多分辨率就越高。


2.线性度(也称非线性误差):实际转换特性曲线与理想直线特性之间的最大偏差。常以相对于满量程的百分数表示。如±1%是指实际输出值与理论值之差在满刻度的±1%以内。


3.绝对精度和相对精度


绝对精度(简称精度):指在整个刻度范围内,任一输入数码所对应的模拟量实际输出值与理论值之间的最大误差。绝对精度是由DAC的增益误差(当输入数码为全1时,实际输出值与理想输出值之差)、零点误差(数码输入为全0时,DAC的非零输出值)、非线性误差和噪声等引起的。绝对精度(即最大误差)应小于1个LSB。


相对精度:与绝对精度表示同一含义,用最大误差相对于满刻度的百分比表示。


4.建立时间:指输入的数字量发生满刻度变化时,输出模拟信号达到满刻度值的±1/2LSB所需的时间。是描述D/A转换速率的一个动态指标。


电流输出型DAC的建立时间短。电压输出型DAC的建立时间主要决定于运算放大器的响应时间。根据建立时间的长短,可以将DAC分成超高速(<1μS)、高速(10~1μS)、中速(100~10μS)、低速(≥100μS)几档。


b328676a4b61409abaf7cd5bc6e97939.png


数字寄存器+模拟电子开关+分压电阻网络+求和运算放大器+电压源


注:Vref是参考电压,是已知的。如,Vref为5V时,V0为0~5V


Z表示单片机所给数字量,即D7~D0对应的数据,如0x01,z为1


256为2的8次方


2.PWM介绍


9104e67fe3fd4672b04ce99cd6a7c826.png


通过微处理器的数字输出来对开关控制的一种方式。控制简单,灵活,动态响应好。


PWM是对模拟信号进行数字编码的方式 。


a为模拟信号,b为数字信号。


单片机只能识别0和1,即0V和5V,如果想让单片机实现如1.6V等数据,可通过脉宽,及占空比来实现。(占空比:一个周期内,高电平所占据的时间)


右图的T是周期,c是占空比。


PWM+RC电路=低配版DAC


3.硬件设计:


7123f617ae504cf783859d97e358e28b.png


A2-A4版                                                                       A5-A7版(控制管脚单独引出)


通过PWM模拟DAC芯片。


通过单片机PWM控制P21改变呼吸灯的亮暗。


J52引出,目的是方便外部设备的使用


4.软件设计:


4fc25685176c464f9ee398e74e427423.png


每一个周期内,都是从0-->1的瞬间开始。占空比增加,"1"的长度增加。


c17c78414b104080ac8e22cbbffda491.png

c08bd3330c6c495ca3a0d5061fda037a.png

d715bdeb9a844365a0411a9ad5b5b09e.png

5eb1b8201413434eb7faf08bf6d677e6.png


59b3c3fd40e6443387712c589b6cd9ab.png

原始代码如下:


main部分:


#include "public.h"
#include "pwm.h"
void main()
{    
    u8 dir=0;//默认为0
    u8 duty=0;
    pwm_init(0XFF,0XF6,100,0);//定时时间为0.01ms,PWM周期是100*0.01ms=1ms,占空比为0%
    while(1)
    {
        if(dir==0)//当dir为递增方向
        {
            duty++;//占空比递增
            if(duty==70)dir=1;//当到达一定值切换方向,占空比最大能到100,但到达70左右再递增,
                                //肉眼也分辨不出亮度变化    
        }
        else
        {
            duty--;
            if(duty==0)dir=0;//当到达一定值切换方向    
        }
        pwm_set_duty_cycle(duty);//设置占空比
        delay_ms(1);//短暂延时,让呼吸灯有一个流畅的效果            
    }
}

pwm.c部分:


#include "pwm.h"
//全局变量定义
u8 gtim_h=0;//保存定时器初值高8位
u8 gtim_l=0;//保存定时器初值低8位
u8 gduty=0;//保存PWM占空比
u8 gtim_scale=0;//保存PWM周期=定时器初值*tim_scale
//tim_h:定时器高8位
//tim_l:定时器低8位
//tim_scale:PWM周期倍数:定时器初值*tim_scale
//duty:PWM占空比(要小于等于tim_scale)
void pwm_init(u8 tim_h,u8 tim_l,u16 tim_scale,u8 duty)
{
    gtim_h=tim_h;//将传入的初值保存在全局变量中,方便中断函数继续调用
    gtim_l=tim_l;
    gduty=duty;
    gtim_scale=tim_scale;
    TMOD|=0X01;    //选择为定时器0模式,工作方式1
    TH0 = gtim_h;    //定时初值设置 
    TL0 = gtim_l;        
    ET0=1;//打开定时器0中断允许
    EA=1;//打开总中断
    TR0=1;//打开定时器
}
//PWM占空比(要小于等于tim_scale)
void pwm_set_duty_cycle(u8 duty)
{
    gduty=duty;    
}
void pwm(void) interrupt 1    //定时器0中断函数
{
    static u16 time=0;
    TH0 = gtim_h;    //定时初值设置 
    TL0 = gtim_l;
    time++;
    if(time>=gtim_scale)//PWM周期=定时器初值*gtim_scale,重新开始计数
        time=0;
    if(time<=gduty)//占空比    
        PWM=1;
    else
        PWM=0;        
}

pwm.h部分


#ifndef _pwm_H
#define _pwm_H
#include "public.h"
//管脚定义
sbit PWM=P2^1;
//变量声明
extern u8 gtim_scale;
//函数声明
void pwm_init(u8 tim_h,u8 tim_l,u16 tim_scale,u8 duty);
void pwm_set_duty_cycle(u8 duty);
#endif


相关文章
|
4月前
|
C语言
【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。
【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。
|
4月前
|
C语言
51单片机汇编语言流水灯代码
51单片机汇编语言流水灯代码
100 1
|
7月前
|
传感器
51单片机循迹小车原理介绍和代码示例
51单片机循迹小车原理介绍和代码示例
51单片机循迹小车原理介绍和代码示例
|
5月前
单片机课程设计——PWM电机调速
单片机课程设计——PWM电机调速
|
7月前
|
传感器
51单片机矩阵键盘超详解!(内含LCD1602代码)
51单片机矩阵键盘超详解!(内含LCD1602代码)
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
|
7月前
|
C++
【51单片机】添加模块代码的常见问题(图示&代码演示)
【51单片机】添加模块代码的常见问题(图示&代码演示)
下一篇
DataWorks