2010-04-01 16:51:00 yu_mi__ 阅读数 3228
  • AD和DA转换-第1季第16部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第16个课程,主要讲解AD转换和DA转换。目标是理解模拟量和数字量的概念,并且学会使用AD转换来采集现实世界的模拟量。

    2626 人正在学习 去看看 朱有鹏

怎样用单片机和DA转换产生一个正波.啊...?需要用C语言编程么..?只知道用汇编,,还有,,貌似听说C语言与汇编可以混编,,怎么编啊..???????

2017-02-09 17:31:42 blue_apolo 阅读数 13779
  • AD和DA转换-第1季第16部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第16个课程,主要讲解AD转换和DA转换。目标是理解模拟量和数字量的概念,并且学会使用AD转换来采集现实世界的模拟量。

    2626 人正在学习 去看看 朱有鹏
一、A/D(模数)、D/A(数模)转换
(一)、引脚

AOUT:模拟输出
Vref:参考电压
AGND:模拟地
EXT:接地
OSC:悬空
SCL,SDA:IIC
AIN0、AIN1、AIN2:模拟输入口

(二)、电路图

从电路图可以看出,A0,A1,A2接地,所以当写入的时候地址应该是0X90,读取的时候应该是0X91

(三)、AGND和DGND

模拟地和数字地隔离开,消除干扰

(四)、控制字节

(五)、AD读数据函数
#include <reg52.h>
#include "delay.h"
#include "iic.h"

#define SUCC 1
#define FAIL 0

unsigned char ad_read_byte(unsigned char device_addr,unsigned char channel)
{
    unsigned char result;
      unsigned char temp;

      iic_start();
      result = iic_send_byte(device_addr);
      if(result == FAIL)
        {
              return FAIL;
        }

      result = iic_send_byte(0x44 + channel);
      if(result == FAIL)
        {
              return FAIL;
        }

        iic_start();

        result = iic_send_byte(device_addr + 1);
      if(result == FAIL)
        {
              return FAIL;
        }

    temp = iic_rcv_byte();

    iic_noack();
        iic_stop();
    return temp;        
}

(六)、AD写数据函数
unsigned char ad_write_byte(unsigned char deviceaddr, unsigned char num)
{
      unsigned char result;
      iic_start();

      result = iic_send_byte(deviceaddr);
      if(result == FAIL) return FAIL;

      result = iic_send_byte(0x40);
      if(result == FAIL) return FAIL;

      result = iic_send_byte(num);
      if(result == FAIL) return FAIL;

      iic_stop();

      return SUCC;
}









2019-05-03 11:05:44 imxlw00 阅读数 490
  • AD和DA转换-第1季第16部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第16个课程,主要讲解AD转换和DA转换。目标是理解模拟量和数字量的概念,并且学会使用AD转换来采集现实世界的模拟量。

    2626 人正在学习 去看看 朱有鹏
  • 模拟量:自然界连续变化的物理量。所谓连续,包含两个方面的含义;

    一方面从时间上来说,它是随时间连续变化的;
    另一方面从数值上来说,它的数值也是连续变化的。这种连续变化的物理量通常称为模拟量。

  • 数字量:计算机中处理的是不连续变化的量,离散性的数字量。

  • D/A 数模转换器 (Digital - Analog Convert)

  • A/D 模拟转换器(Analog - Digital Convert)

A/D转换器的主要技术指标

1、分辨率
ADC的分辨率是指使输出数字量变化一个相邻数码所需输入模拟电压的变化量。常用二进制的位数表示。例如12位ADC的分辨率就是12位,或者说分辨率为满刻度FS的1/2^12。

一个10V满刻度的12位ADC能分辨输入电压变化最小值是10V×1/2^12=2.4mV。
2、量化误差
ADC把模拟量变为数字量,用数字量近似表示模拟量,这个过程称为量化。量化误差是ADC的有限位数对模拟量进行量化而引起的误差。实际上,要准确表示模拟量,ADC的位数需很大甚至无穷大。一个分辨率有限的ADC的阶梯状转换特性曲线与具有无限分辨率的ADC转换特性曲线(直线)之间的最大偏差即是量化误差。
在这里插入图片描述
3、偏移误差
偏移误差是指输入信号为零时,输出信号不为零的值,所以有时又称为零值误差。假定ADC没有非线性误差,则其转换特性曲线各阶梯中点的连线必定是直线,这条直线与横轴相交点所对应的输入电压值就是偏移误差。
4、满刻度误差
满刻度误差又称为增益误差。ADC的满刻度误差是指满刻度输出数码所对应的实际输入电压与理想输入电压之差。
5、线性度
线性度有时又称为非线性度,它是指转换器实际的转换特性与理想直线的最大偏差。
6、绝对精度
在一个转换器中,任何数码所对应的实际模拟量输入与理论模拟输入之差的最大值,称为绝对精度。对于ADC而言,可以在每一个阶梯的水平中点进行测量,它包括了所有的误差。
7、转换速率
ADC的转换速率是能够重复进行数据转换的速度,即每秒转换的次数。而完成一次A/D转换所需的时间(包括稳定时间),则是转换速率的倒数。
A/D转换器的转速速度主要取决于转换电路的类型,不同类型的A/D转换器的转换速度相差很大。

  • 双积分A/D转换器的转换速度最慢,需几百毫秒左右;
  • 逐次逼近式A/D转换器的转换速度最快,需十几微秒;
  • 并行比较型A/D转换器的转换速度最快,仅需几十纳秒。

逐次逼近式ADC的转换原理

在这里插入图片描述
逐次逼近式AD转换器与计数式A/D转换类似,只是数字量由“逐次逼近寄存器SAR”产生。SAR使用“对分搜索法”产生数字量,以8位数字量为例,SAR首先产生8位数字量的一半,即10000000B,试探模拟量Vi的大小,若Vn>Vi,清除最高位,若Vn<Vi,保留最高位。在最高位确定后,SAR又以对分搜索法确定次高位,即以低7位的一半y1000000B(y为已确定位) 试探模拟量Vi的大小。在bit6确定后,SAR以对分搜索法确定bit5位,即以低6位的一半yy100000B(y为已确定位) 试探模拟量的大小。重复这一过程,直到最低位bit0被确定,转换结束。

PCF8591的介绍

PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入、一个输出和一个串行I2C 总线接口。3 个地址引脚A0、A1 和A2 用于编程硬件地址,允许将最多8 个器件连接至I2C总线而不需要额外硬件。PCF8591由于其使用的简单方便和集成度高,在单片机应用系统中得到了广泛的应用。
特点:

  • 单电源供电
  • 工作电压:2.5 V ~ 6 V
  • I2C总线串行输入/输出
  • 通过3个硬件地址引脚编址
  • 采样速率取决于 I2C 总线传输速率决定
  • 4个模拟输入可编程为单端或差分输入
  • 自动增量通道选择
  • 8位逐次比较型A/D 转换
    在这里插入图片描述

管脚定义:

AIN0~AIN3:模拟量输入通道
AOUT:模拟输出通道
A0~A2:硬件设备地址
VDD:电源正极
VSS:电源负极
VREF:参考电压输入。
EXT:振荡器输入时,内部/外部的切换开关。
OSC:振荡器输入/输出。
SCL:I2C BUS时钟输入。
SDA:I2C BUS 数据输入/输出。
AGND:模拟地,模拟信号和基准电源的参考地

控制字格式

在这里插入图片描述
最高位默认为0

第6位是选择是否允许模拟电压输出,在DA转换时设置为1,AD转换时设置为0或1均可

第5/4位是选择模拟电压输出方式,一般选择00单端输入方式,其他的几种方式如下图所示
在这里插入图片描述
第3位默认为0

第2位是自动增量使能位,如果自动增量(auto-increment)标志置1,每次A/D 转换后通道号将自动增加。

第1/0为是在AD转换时选择哪一个通道输入的电压转换为数字量.

PCF8591的器件地址

每一个IIC器件都有一个器件地址,来区分不同的IIC设备,下面是PCF8591的地址
在这里插入图片描述
在这里插入图片描述
它的地址是由1001和A2A1A0组成的,在原理图中可以看出,A2A1A0均为0,所以器件地址为0x90/0x91,最后一位是读写方向位,0表示下一个字节往总线上写数据,1表示下一个字节从总线上读取数据.

2018-07-22 16:23:23 weixin_39569242 阅读数 995
  • AD和DA转换-第1季第16部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第16个课程,主要讲解AD转换和DA转换。目标是理解模拟量和数字量的概念,并且学会使用AD转换来采集现实世界的模拟量。

    2626 人正在学习 去看看 朱有鹏

一、实验目的

1、了解 D/A 转换的基本原理。

2、了解 D/A 转换芯片 0832 的性能及编程方法。

3、了解单片机系统中扩展 D/A 转换的基本方法。

二.实验设备和器件

1.KEIL软件

2.实验箱

三.实验内容

利用 DAC0832,编制程序产生锯齿波、三角波、正弦波。三种波轮流显示,用示波器观看。

  • 电路图及连线:

连线

连线孔1

连线孔2

1

DA_CS

CS2

2

-5V-+5V

电压表测量端

3

电压表地端

实验箱地

                                             

 

  • 代码:

#include<reg51.h>

#include<absacc.h>

#define uchar unsigned char

#define uint unsigned int

#define DAC0832 XBYTE[0x8000]

uchar sindata[64]=

{0x80,0x8c,0x98,0xa5,0xb0,0xbc,0xc7,0xd1,0xda,0xe2,0xea,

 0xf0,0xf6,0xfa,0xfd,0xff,0xff,0xff,0xfd,0xfa,0xf6,0xf0,

 0xea,0xe3,0xda,0xd1,0xc7,0xbc,0xba,0xa5,0x99,0x8c,0x80,

 0x73,0x67,0x5b,0x4f,0x43,0x39,0x2e,0x25,0x1d,0x15,0xf,

 0x9,0x5,0x2,0x0,0x0,0x0,0x2,0x5,0x9,0xe,0x15,0x1c,0x25,

 0x2e,0x38,0x43,0x4e,0x5a,0x66,0x73};

 void delay(uchar m)//延时函数

{uchar i;for(i=0;i<m;i++) ;}

void juchi()   //锯齿函数

{uchar i1;

for (i1=0;i1<0xff;i1++)  DAC0832=i1;

i1=0;}

void sanjiao() //三角函数

{ uchar i2;

for(i2=0;i2<0xff;i2++)  DAC0832=i2;

for(i2=0xff;i2>0;i2--)  DAC0832=i2;

i2=0;}

void zhengxian() //正弦函数

{uchar k;

for(k=0;k<64;k++)

{DAC0832=sindata[k];delay(1);}}

void main()    //主函数

{uchar j=2;

while(1)

{

while(j--)

{juchi();}j=2;

while(j--)

{sanjiao();}j=2;

while(j--)

{zhengxian();}j=2;}}

  • 波形图:

 

  • 分析:
  1. 该实验中,运用DA转换来产生不同的波形,本实验选取的双极性电压(-5V~+5v)

8 位 D/A 转换器的输入数据与输出电压的关系为

U(-5V ~ +5V)=2·Uref/256×N-5V     (这里 Uref 为+5V)

2、本实验DA选择模块地址控制端口DA_CS与实验箱上的CS0相连,根据查实验箱相关资料可知,CS0提供的地址为8000H-8fffH,本实验选取的8000H作为地址

3、第一部分的实验图在本实验中右下角的部分不需要

4、锯齿的形成原理则是输入的数字量从0000到ffff,一直循环,可形成无数个锯齿波

   三角的形成原理则是输入的数字量从0000到ffff,,再从ffff到0000,一直循环,可形成无数个三角波

   正弦的形成原理则是造一张正弦数字量表。即查函数表得到的值转换成十六进制数填表。

5、在本实验形成锯齿波时,用for(i1=0;i1<=0xff;i1++)这条语句时,这个循环跳不出来,会一直在示波器上一直显示锯齿波,改为for(i1=0;i1<0xff;i1++)之后,循环则跳出

6、本实验中,我们把每个波形的形成写为一个函数,然后在主函数中调用这三个函数,为防止波形转换的过快,在主函数中中,while再构成了一个循环,及每个波形图出现两个周期。

2018-03-15 20:39:55 qq_33656619 阅读数 8693
  • AD和DA转换-第1季第16部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第16个课程,主要讲解AD转换和DA转换。目标是理解模拟量和数字量的概念,并且学会使用AD转换来采集现实世界的模拟量。

    2626 人正在学习 去看看 朱有鹏

依旧是借着蓝桥杯的机会,来学习一些模块,和软件模拟一些通信方式。

今天学习的模块是PCF8591,一款AD\DA转换器,使用IIC通信方式。

芯片的内部框图如下所示:


各引脚作用如下表所示:


仍旧和之前DS1302的使用相似,对于这款芯片的使用,依旧是按照先寻地址,再读写相应寄存器的步骤。

PCF8591芯片所能接收的地址包含固定部分和可编程部分。可编程部分必须根据地址引脚A0,A1,和A2来设置,在IIC总线协议中地址必须是起始条件后作为第一个字节发送,地址字节的最后一位用来设置对目标地址的读或写。地址字节格式如下所示:


第一个字节是地址字节,那么第二个字节就是控制字节,控制字节发送到PCF8591的控制寄存器中,用于控制器件的功能,控制字格式如下所示:


其中BIT7和BIT3必须设置为0,BIT6是模拟输出允许位,BIT4和BIT5用于定义模拟输入的方式,有单端和差分输入两种方式。最后三位用于选择模拟输入的通道。

接着就到了第三个字节,如果是D\A转换,发送的第三个字节被存储到DAC数据寄存器,使用D\A转换器转换成相应的模拟电压。

如果是A\D转换,在一个有效模式地址传给PCF8591之后,一个A\D转换周期便开始了,所选通道的采样电压被转换成相应的8位二进制码。

前面说过,单片机与PCF8591之间采用的是IIC的通信方式,所以在这里我想写一下如何用51软件模拟IIC通信。

我这里有蓝桥杯官方给出的IIC库,所以我就配合官方代码来理解IIC通信。

/*首先是IIC的启动,始条件:必须在所有命令之前发送,时钟线保持高电平期间,数据线电平从高到低的跳变作为IIC总线的启动信号。而下面这个函数IIC_Start()就是模拟这个过程*/

void IIC_Start(void)

{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;

}

/*类似地,停止条件:时钟线保持高电平期间,数据线电平从低到高的跳变作为IIC总线的停止信号。*/

void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}

IIC总线协议规定,每传送一个字节数据后,都要有一个应答信号,以确定数据传送是否被对方收到,应答信号由接收设备产生,在SCL为高电平期间,接收设备将SDA拉为低电平表示数据传输正确,即产生了应答。

但当主机为接收设备时,主机对最后一个字节不应答,以向发送设备表示数据传送结束。

void IIC_Ack(unsigned char ackbit)   //当ackbit为1时,表示单片机对从设备发送来数据的应答

{                                                     //当ackbit为0时,表示主机接收了最后一个字节,因此不再应答,结束通信
if(ackbit) 
{
SDA = 0;
}
else 
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1; 
somenop;

}


bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)     //在SCL为高电平期间,因为接收设备未将SDA拉低,所以默认未接收到应答,结束IIC通信
{   
SCL = 0;
IIC_Stop();
return 0;
}
else     //接收到应答,返回1,继续下一个数据字节的传输

SCL = 0;
return 1;
}

}

//IIC传送一个字节的函数,高位在前,应当注意的是IIC进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定

void IIC_SendByte(unsigned char byt)

{
unsigned char i;
for(i=0;i<8;i++)
{   
if(byt&0x80) 
{
SDA = 1;
}
else 
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}

}

//IIC接收字节函数,原理同发送

unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;

for(i=0;i<8;i++)
{   
SCL = 1;
somenop;
da <<= 1;
if(SDA) 
da |= 0x01;
SCL = 0;
somenop;
}
return da;

}

以上就是蓝桥杯官方给出的全部IIC函数。

对于PCF8591的初始化与通信函数还需要我们自己编写。

初始化函数如下:

void init_pcf8591(void)
{
IIC_Start();

IIC_SendByte(0x90);    //大家可以看看IAP15F2K61S2的原理图,就知道为什么是0x90了

IIC_WaitAck();
IIC_SendByte(0x03);  //选择ADC通道3
IIC_WaitAck();
IIC_Stop();

}

//接收PCF8591转换过的采样电压值

unsigned char adc_pcf8591(void)
{
unsigned char temp;


IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Ack(0);
IIC_Stop();

return temp;

}

以上就是PCF8591的使用以及对IIC通信的理解,在IAP15F2K61S2上还有EEPROM---AT24C02,它用的也是IIC通信,原理相同,不再多说。

没有更多推荐了,返回首页