学51单片机-基于PCF8591的AD采样和DA输出

发布者:码字奇思最新更新时间:2020-07-21 来源: 51hei关键字:51单片机  PCF8591  AD采样  DA输出 手机看文章 扫描二维码
随时随地手机看文章

     首先思考一个问题,我们的世界是数字的还是模拟的?


      当然是模拟的了,所有的量都是在一定范围内连续变化的。我们为了能够更加方便的描述这些量,对它们进行了数字化。而数字量就不一样了,它是分立的的几个值。


      举个例子,我们形容一个人的身高,模拟的说法是一米七到一米七五之间,数字的说法就是一米七三。


接下来说AD转换器,它的出现也是为了让我们能更方便、更直接的描述电压的高低。AD转换器,英文全称为Analog-to-Digital Converter,是模拟量到数字量的一个转换过程,主要用于电压的采集。它的出现就如同有了一把尺子,很容易就能量出电压的高低。


在电子设备中,经常要检测各种模拟量:温度、压力、速度、流量、重力加速度等等,这些模拟量都被相应的传感器转换为电压信号,我们只需要测量电压的高低,就能得到相应参数。


AD的主要参数有哪些?

1、AD的位数:表明这个AD共有2^n个刻度,8位AD,输出的刻度是0~255.

2、分辨率:就是AD能够分辨的最小的模拟量变化,假设5.10V的系统用8位的AD采样,那么它能分辨的最小电压就是5.10/255=0.02V。

3、INL:Interger NONliner 积分非线性度,表示了ADC器件在所有的数值点上对应的模拟值,和真实值之间误差最大的那一点的误差值。也就是,输出数值偏离线性最大的距离。单位是LSB(即最低位所表示的量)。比如12位ADC:TLC2543,INL值为1LSB。那么,如果基准4.095V,测某电压得的转换结果是1000,那么,真实电压值可能分布在0.999~1.001V之间。

4、DNL:Differencial NonLiner-差分非线性度,理论上说,模数器件相邻量个数据之间,模拟量的差值都是一样的。就相一把疏密均匀的尺子。但实际并不如此。一把分辨率1毫米的尺子,相邻两刻度之间也不可能都是1毫米整。那么,ADC相邻两刻度之间最大的差异就叫差分非线性值(Differencial NonLiner)。DNL值如果大于1,那么这个ADC甚至不能保证是单调的,输入电压增大,在某个点数值反而会减小。这种现象在SAR(逐位比较)型ADC中很常见。

5、基准源:有内部基准源、外部基准源等等。

6、转换速率:也就是转换周期的倒数,转换周期就是完成一次AD转换所需的时间。


今天要用到的器件是PCF8591,为什么选它?太多的开发板上用它做演示了,而且还是IIC总线通信的。既学习了AD采样,又学习了IIC总线。


先上应用电路:

      如上图所示,PCF8591的9脚和10脚,一个是数据线SDA,一个是时钟线SCL。分别接到单片机的P2.0 , P2.1上面。


为什么选这两个引脚?因为51单片机上没有IIC总线接口,需要用普通的IO模拟,所以它随便选了两个IO接上就行。


VREF是什么?基准电压,也是它能测量的最大电压。


如何控制?今天先不说IIC总线,只说控制流程。

看器件手册可以知道:

分四步:

1、发送地址字节,选择该器件。

2、发送控制字节,选择相应通道。               //

3、重新发送地址字节,选择该器件。

4、接收目标通道的数据。

这次的程序流程是:AD采样,串口发送,循环执行。


下面是AD采样源代码:

/**********************51单片机学习例程************************

*  平台:Keil U4 + STC89C52

*  名称:AD采样+串口发送

*  编写:起航

*  晶体:11.0592MHZ

******************************************************************/

#include

#include


typedef unsigned char uint8;

typedef unsigned int uint16;


#define SLAVEADDR  0x90                 //定义器件地址

#define nops()  do{_nop_();_nop_();_nop_();_nop_();_nop_();} while(0) //定义空指令



sbit SCL = P2^1;       //I2C  时钟

sbit SDA = P2^0;       //I2C  数据


void delay(uint16 n)

{

        while (n--);

}

/**

* 函数: i2c_start()

* 功能: 启动i2c                  起始信号

*/

void i2c_start()

{

        SCL = 1;

        nops();

        SDA = 1;

        nops();

        SDA = 0;

        nops();

        SCL = 0;

}


/**

* 函数: i2c_stop()

* 功能: 停止i2c

*/

void i2c_stop()

{

        SCL = 0;

        nops();

        SDA = 0;

        nops();

        SCL = 1;

        nops();

        SDA = 1;

        nops();

}


/**

* 函数: i2c_ACK(bit ck)

* 功能: ck为1时发送应答信号ACK,

*       ck为0时不发送ACK

*/

void i2c_ACK(bit ck)

{

    if (ck)

                SDA = 0;

    else

                SDA = 1;

    nops();

    SCL = 1;

    nops();

    SCL = 0;

        nops();

    SDA = 1;

    nops();

}


/**

* 函数: i2c_waitACK()

* 功能: 返回为0时收到ACK

*       返回为1时没收到ACK

*/

bit i2c_waitACK()

{

        SDA = 1;

        nops();

        SCL = 1;

        nops();

        if (SDA)

        {   

                SCL = 0;

                i2c_stop();

                return 1;

        }

        else

        {  

                SCL = 0;

                return 0;

        }

}


/**

* 函数: i2c_sendbyte(uint8 bt)

* 功能: 将输入的一字节数据bt发送

*/

void i2c_sendbyte(uint8 bt)

{

    uint8 i;

   

    for(i=0; i<8; i++)

    {  

        if (bt & 0x80)

                        SDA = 1;

        else

                        SDA = 0;

        nops();

        SCL = 1;

        bt <<= 1;

        nops();      

        SCL = 0;

    }

}


/**

* 函数: i2c_recbyte( )

* 功能: 从总线上接收1字节数据

*/

uint8 i2c_recbyte()

{

        uint8 dee, i;

       

        for (i=0; i<8; i++)

        {

                SCL = 1;   

                nops();

                dee <<= 1;

                if (SDA)

                        dee = dee | 0x01;

                SCL = 0;

                nops();

        }

       

        return dee;

}


/**

* 函数: i2c_readbyte

* 输入: addr

* 功能: 读出一字节数据

* 返回值: 0->成功  1->失败

*/

bit i2c_readbyte(uint8 com, uint8 *dat)

{       

        i2c_start();

        i2c_sendbyte(SLAVEADDR);    //地址

    if (i2c_waitACK())

                return 1;

        i2c_sendbyte(com);        //控制字节

    if (i2c_waitACK())

                return 1;

        i2c_start();

        i2c_sendbyte(SLAVEADDR+1); //地址

    if (i2c_waitACK())

                return 1;

        *dat = i2c_recbyte();      //读数据

        i2c_ACK(0);                //因为只读一字节数据,不发送ACK信号

        i2c_stop();   

       

        return 0;

}


/**

* UART初始化

* 波特率:9600

*/

void uart_init(void)

{

    ET1=0;

    TMOD = 0x21;        // 定时器1工作在方式2(自动重装)

    SCON = 0x50;        // 10位uart,允许串行接受


    TH1 = 0xFD;

    TL1 = 0xFD;


    TR1 = 1;

}


/**

* UART 发送一字节

*/

void UART_Send_Byte(uint8 dat)

{

        SBUF = dat;

        while (TI == 0);

        TI = 0;

}



main()

{

        uint8 ans;


        uart_init();


        while(1)

        {


                i2c_readbyte(0x43, &ans);

            

                UART_Send_Byte(ans);

                delay(50000);

        }

}


关键字:51单片机  PCF8591  AD采样  DA输出 引用地址:学51单片机-基于PCF8591的AD采样和DA输出

上一篇:学51单片机-IIC总线与时序
下一篇:学51单片机-UART口发送一串字符

推荐阅读最新更新时间:2024-11-16 20:24

51单片机-74HC595移位寄存器
1.74HC595芯片介绍 74HC595芯片是一个串行输入,并行输出设备。其内部包括一个8位移位寄存器、一个存储器以及三态输出门电路,其中移位寄存器和存储器都有相互独立的时钟,每当移位寄存器输入时钟SHCP上升沿来临之时,数据被移出。 1.1.引脚定义 引脚定义,怎么命名,并没有个统一的规则,所以每个人在绘制芯片引脚图时,根据个人习惯命名可能都不一样(如:14号引脚(DS/SER),10号引脚(MR/SCLR),11号引脚(SHCP/SCK),12号引脚(STCP/RCK)等);虽然命名可能不一样,但引脚的功能确是一样; 1.2.工作原理 工作方式1:将DS的数据,通过SHCP产生上升沿,一位位的移入移
[单片机]
<font color='red'>51单片机</font>-74HC595移位寄存器
51单片机控制RTL8019AS实现以太网通讯
  互联网络硬件、软件的迅猛发展,使得网络用户呈指数增长,在使用计算机进行网络互联的同时,各种家电设备、仪器仪表以及工业生产中的数据采集与控制设备在逐步地走向网络化,以便共享网络中庞大的信息资源。在电子设备日趋网络化的背景下,利用廉价的51单片机来控制RTL8019AS实现以太网通讯具有十分重要的意义。 1 以太网(Ethernet)协议   一个标准的以太网物理传输帧由七部分组成(如表1所示,单位:字节)。 表1 以太网的物理传输帧结构表   除了数据段的长度不定外,其他部分的长度固定不变。数据段为46~1500字节。以太网规定整个传输包的最大长度不能超过1514字节(14字节为DA、SA、TYPE),最小不能小于60字节
[单片机]
用<font color='red'>51单片机</font>控制RTL8019AS实现以太网通讯
51单片机驱动CT1642数码管显示源程序
拆解电视机顶盒找到带CT1642控制的数码管 在网上找到代码修改了一下 没有解决按键检测的问题 可根据自己的需求修改对应引脚 制作出来的实物图如下: 单片机源程序如下: sbit DAT=P2^2; sbit CLK=P2^1; sbit KEY=P2^0; u8 NixieTable ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; u8 NixieTablepos ={0,0x02,0x04,0x08}; void CT1642_Write(u8 Pos, u8 Val) { u8 i,Posn; // 1、移18位:对应C1--C4、6位空、Q2--Q9 P
[单片机]
<font color='red'>51单片机</font>驱动CT1642数码管显示源程序
利用51单片机实现IO口模拟串口
有时需要双串口,转贴一篇 地址见下面 IO口模拟串口 1602显示数据位内容 程序可以实现一个51 单片机 有两个串口 #include regx52.h sbit BT_SND =P1^1; sbit BT_REC =P1^0; //1602部分引脚定义 sbit LCM_RW =P2^1 ;//定义引脚 sbit LCM_RS =P2^0; sbit LCM_E =P2^2; #define LCM_Data P0 #define Busy 0x80 //用于检测LCM状态字中的Busy标识 #define F_TM F0 #define TIMER0_ENABLE TL0=TH0; TR0=1; #define TIME
[单片机]
51单片机快速入门指南】3.1:配置外部中断触发方式和中断优先级
普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 源码 stdint.h见【51单片机快速入门指南】1:基础知识和工程创建 中断知识见【51单片机快速入门指南】3:中断系统 将外部中断0和外部中断1均配置为下降沿触发,但外部中断1的优先级最高,外部中断0的优先级最低。 EXTI.c #include REGX52.H #include intrins.h #include stdint.h #include EXTI.h //定义LED管脚 sbit D1 = P2^0; sbit D2 =
[单片机]
【<font color='red'>51单片机</font>快速入门指南】3.1:配置外部中断触发方式和中断优先级
51单片机 使用一个独立按键控制蜂鸣器
第一次按下按键按键key后,蜂鸣器响; 第二次按下按键按键key后,蜂鸣器停。 #include reg52.h sbit beep=P1^5; sbit key=P3^1; unsigned int mode; //定义一个模式 void delay(unsigned int i) { while(i--); } void voice() { if(mode) { beep=~beep; delay(100); //更改delay可以让蜂鸣器发出不同的声音 } else { beep=0; } } void main()
[单片机]
C-51单片机最简单静态数码管显示数字
单片机系统中常用的显示器有:发光二极管LED(Light Emitting Diode)显示器、液晶LCD(Liquid Crystal Display)显示器、CRT显示器等,其中七段数码管显示器是常用的显示器,常用来显示设备的运行状态, 可以显示各种数字和字符,分共阴极和共阳极两种,内部电路如图1所示。 让某一数码管显示某一数字只需要 P1=0X**; // ** 表示点亮的位置 P2=0X**; // ** 表示点亮的数字 直接上代码 #include reg51.h void main() { while(1) { P1=0Xfb; P2=0X5b; //共阴极 }
[单片机]
C-<font color='red'>51单片机</font>最简单静态数码管显示数字
TMS320VC5402DSP与51单片机的接口设计技术
TMS320VC5402(VC5402)是德州仪器公司推出的具有较高性价比的定点数字信号处理器。VC5402增强外设由软件等待状态发生器、锁相环时钟发生器、6通道直接存储器访问(DMA)控制器、增强型8位并行主机接口(HPI)等组成。两个可编程的多通道缓冲串口(McBSP)能够全双工、快速地与其他同步串口进行数据交换,硬件连接简单,串口的工作模式和传送数据的格式可通过编程实现。DSP和单片机之间的通信一般利用双口RAM,通过串口或DSP的HPI接口实现。 利用双口RAM实现 CY7C026是CYPRESS公司生产的16k×16B高速双口静态RAM,存取速度小于25ns。他具有真正的双端口,可以同时进行数据存取,两个端口具有独立的
[应用]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved