单片机C语言DA转换,51单片机PCF8591的DA转换程序详解[含HL-1与HJ-c52 DA代码AD/DA原理图](可直接复......_桂能的博客-程序员资料

技术标签: 单片机C语言DA转换  

以下是补充(能想到的范围有限有没想到的还请谅解)

DA工作原理

基于PCF8591芯片

DA是什么?

n DA指数模转换(Digital to Analog),顾名思义,就是把数字信号转换成模拟信号。与DA

相对应,AD是把模拟信号转换为数字信号,便于计算机等数字控制器处理。

DA有什么作用?

n 1、将数字量转换成模拟量,以便操纵控制对象。n 2、用数字化来控制各种对象。

n 3、可以在单片机中输入数字,来控制输出压力计力的大小。

串行DA芯片与单片机连接方法(两种):

HL-1连接方法

3f829e29e76caa8c3b1f630a6b27d58d.gif

51hei图片20190802095213.png (107.86 KB, 下载次数: 5)

2019-8-2 09:52 上传

HJ-c52连接方法

3f829e29e76caa8c3b1f630a6b27d58d.gif

51hei图片20190802095218.png (109.54 KB, 下载次数: 2)

2019-8-2 09:52 上传

D/A转换器的主要性能指标

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)几档。

应当注意,精度和分辨率具有一定的联系,但概念不同。DAC的位数多时,分辨率会提高,对

应于影响精度的量化误差会减小。但其它误差(如温度漂移、线性不良等)的影响仍会使DAC

的精度变差。

附带三个说明

一,HL-1的AD/DA模块和DS1302时钟模块原理图

3f829e29e76caa8c3b1f630a6b27d58d.gif

51hei图片20190802093741.png (384.8 KB, 下载次数: 2)

2019-8-2 09:50 上传

3f829e29e76caa8c3b1f630a6b27d58d.gif

51hei图片20190802094157.png (199.41 KB, 下载次数: 3)

2019-8-2 09:50 上传

二,HJ-C52的AD/DA原理图

3f829e29e76caa8c3b1f630a6b27d58d.gif

51hei图片20190802094201.png (340.84 KB, 下载次数: 6)

2019-8-2 09:50 上传

三,一个AD/DA单独模块(PCF8951)的说明

3f829e29e76caa8c3b1f630a6b27d58d.gif

51hei图片20190802094210.png (165.37 KB, 下载次数: 3)

2019-8-2 09:51 上传

3f829e29e76caa8c3b1f630a6b27d58d.gif

51hei图片20190802094207.png (245.88 KB, 下载次数: 3)

2019-8-2 09:50 上传

AD/DA独立模块接线说明

1. 可以自己用杜邦线接到你自己的最小系统上,也可以接到慧净HJ-C51智能小车核心板上,接线方法参考源理图接,VCC接学

习板上的VCC,GND接学习板上的GND 其他的信号输入可以自己定义。

AD/DA独立模块简单说明

1. 本板采用全新AD/DA芯片PCF8591,设计合理,性能非常稳定,提供原理图及配套示例代码。

模块说明:

2. 该模块A/D输入和D/A输出定义,模块有4路A/D输入,1路D/A输出:

3. A/D输入通道0:连接外部测试;

4.A/D输入通道1:一路电位器可测变阻器分压;连接外部测试;

5. A/D输入通道2:一路热敏电阻可测温度;连接外部测试;

6. A/D输入通道3:一路光敏电阻可测光强;连接外部测试;

7. D/A输出通道0:一路LED通过亮度显示。

------------------------------------------------(因为有些东西电脑没备份..所以找不到了)-----------------------------------------------------

/*-----------------------------------------------

内容:scl=P3^0;//IIC的时钟线  sda=P3^1;//IIC的数据线分别接J26-7和J26-6上。

J23-5接J26-5上

LED会逐渐变亮后有逐渐变暗

------------------------------------------------*/

#include

#include

#define uc unsigned char

#define ui unsigned int

sbit scl=P3^0;//IIC的时钟线

sbit sda=P3^1;//IIC的数据线

uc code shuju[]={

0x0f,0x1e,0x2d,0x3c,0x4b,0x5a,0x69,0x78,0x87,0x96,0xa5,0xb4,0xc3,0xd2,0xe1,0xf0,0xff,//让电压逐渐升高的数据

0xff,0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87,0x78,0x69,0x5a,0x4b,0x3c,0x2d,0x1e,0x0f,//让电压逐渐下降的数据

};

void delayus(void)

{

;;

}

void delay(ui m)

{

ui i,j;

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

for(j=0;j

}

void init(void)//IIC的初始化

{

scl=1;

delayus();

sda=1;

delayus();

}

void start(void)//IIC的起始信号

{

scl=1;

delayus();

sda=1;

delayus();

sda=0;

delayus();

}

void stop(void)//IIC的停止信号

{

sda=0;

delayus();

scl=1;

delayus();

sda=1;

delayus();

}

void ack(void)//IIC的应答信号

{

uc i;

scl=1;

delayus();

while((sda==1)&(i<255))i++;

scl=0;

delayus();

}

void write_byte(uc date)//向IIC写一个字节的数据

{

uc i,temp;

temp=date;

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

{

temp=temp<<1;

scl=0;

delayus();

sda=CY;

delayus();

scl=1;

delayus();

}

scl=0;

delayus();

sda=1;

delayus();

}

void write(uc add,uc sda,uc date)

{

start();

write_byte(add);//0x90表示器件地址为000的写操作

ack();

write_byte(sda);//0x40表示四路单数入00通道无增益的器件控制指令

ack();

write_byte(date);//表示DA数据

ack();

stop();

}

void main(void)

{ uc i;

init();//I2C总线初始化

while(1)

{

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

{

write(0x90,0x40,shuju[ i]);//向PCF8591里写入数据(即电压量的数据);

delay(100);

}

}

}复制代码以上是一个DA转换例子[我也是也是补充的(上传不了附件....就只能直接上码了

5ec0c4081690782e4dcbb595093e4a9b.gif)

附带两种使LED输出显示DA

1,HJ-52

/*-----------------------------------------------

名称:IIC协议 PCF8591ADDA转换

内容:此程序通过IIC协议对DAAD芯片操作, 并输出模拟量,用LED亮度渐变指示

------------------------------------------------*/

#include    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

#include //包含NOP空指令函数_nop_();

#define AddWr 0x90   //写数据地址

#define AddRd 0x91   //读数据地址

sbit Sda=P1^2;      //定义总线连接端口

sbit Scl=P1^7;

sbit dula=P2^0;

sbit wela=P2^1;

bit ADFlag;          //定义AD采样标志位

unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数共阴码管段码表

data unsigned char  Display[8];//定义临时存放数码管数值

/*------------------------------------------------

延时程序

------------------------------------------------*/

void mDelay(unsigned char j)

{

unsigned int i;

for(;j>0;j--)

{

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

{;}

}

}

/*------------------------------------------------

初始化定时器1

------------------------------------------------*/

void Init_Timer1(void)

{

TMOD |= 0x10;

TH1=0xff;                              /* Init value */

TL1=0x00;

//PT1=1;                   /* 优先级    */

EA=1;                      /* interupt enable */

ET1=1;                     /* enable timer1 interrupt */

TR1=1;

}

/*------------------------------------------------

启动IIC总线

------------------------------------------------*/

void Start(void)

{

Sda=1;

_nop_();

Scl=1;

_nop_();

Sda=0;

_nop_();

Scl=0;

}

/*------------------------------------------------

停止IIC总线

------------------------------------------------*/

void Stop(void)

{

Sda=0;

_nop_();

Scl=1;

_nop_();

Sda=1;

_nop_();

Scl=0;

}

/*------------------------------------------------

应答IIC总线

------------------------------------------------*/

void Ack(void)

{

Sda=0;

_nop_();

Scl=1;

_nop_();

Scl=0;

_nop_();

}

/*------------------------------------------------

非应答IIC总线

------------------------------------------------*/

void NoAck(void)

{

Sda=1;

_nop_();

Scl=1;

_nop_();

Scl=0;

_nop_();

}

/*------------------------------------------------

发送一个字节

------------------------------------------------*/

void Send(unsigned char Data)

{

unsigned char BitCounter=8;

unsigned char temp;

do

{

temp=Data;

Scl=0;

_nop_();

if((temp&0x80)==0x80)

Sda=1;

else

Sda=0;

Scl=1;

temp=Data<<1;

Data=temp;

BitCounter--;

}

while(BitCounter);

Scl=0;

}

/*------------------------------------------------

读入一个字节并返回

------------------------------------------------*/

unsigned char Read(void)

{

unsigned char temp=0;

unsigned char temp1=0;

unsigned char BitCounter=8;

Sda=1;

do

{

Scl=0;

_nop_();

Scl=1;

_nop_();

if(Sda)

temp=temp|0x01;

else

temp=temp&0xfe;

if(BitCounter-1)

{

temp1=temp<<1;

temp=temp1;

}

BitCounter--;

}

while(BitCounter);

return(temp);

}

/*------------------------------------------------

写入DA数模转换值

------------------------------------------------*/

void DAC(unsigned char Data)

{

Start();

Send(AddWr); //写入芯片地址

Ack();

Send(0x40);  //写入控制位,使能DAC输出

Ack();

Send(Data);  //写数据

Ack();

Stop();

}

/*------------------------------------------------

读取AD模数转换的值,有返回值

------------------------------------------------*/

unsigned char ReadADC(unsigned char Chl)

{

unsigned char Data;

Start();        //写入芯片地址

Send(AddWr);

Ack();

Send(0x40|Chl);//写入选择的通道,本程序只用单端输入,差分部分需要自行添加

//Chl的值分别为0、1、2、3,分别代表1-4通道

Ack();

Start();

Send(AddRd);    //读入地址

Ack();

Data=Read();    //读数据

Scl=0;

NoAck();

Stop();

return Data;   //返回值

}

void cmg(void)//数码管锁存函数                   关时钟DS1302

{

dula=1;

P0=0x00;

dula=0;

wela=1;

P0=0x00;

wela=0;

}

/*------------------------------------------------

主程序

------------------------------------------------*/

void main()

{

unsigned char num;                   //DA数模输出变量

unsigned char ADtemp;                //定义中间变量

Init_Timer1();

cmg();//关数码管函数

while(1)

{

DAC(num);       //DA输出,可以用LED模拟电压变化

num++;          //累加,到256后溢出变为0,往复循环。显示在LED上亮度逐渐变化

mDelay(20);     //延时用于清晰看出变化

if(ADFlag)      //定时采集输入模拟量

{

ADFlag=0;

}

}

}

2,HL-1

/*-----------------------------------------------

名称:IIC协议 PCF8591ADDA转换

内容:此程序通过IIC协议对DAAD芯片操作, 并输出模拟量,用LED亮度渐变指示

------------------------------------------------*/

#include    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

#include //包含NOP空指令函数_nop_();

#define AddWr 0x90   //写数据地址

#define AddRd 0x91   //读数据地址

sbit RST=P2^4;   //关掉时钟芯片输出

sbit Sda=P2^0;      //定义总线连接端口

sbit Scl=P2^1;

sbit Fm=P2^3;          //FM

sbit dula=P2^6;

sbit wela=P2^7;

bit ADFlag;          //定义AD采样标志位

unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数共阴码管段码表

data unsigned char  Display[8];//定义临时存放数码管数值

/*------------------------------------------------

延时程序

------------------------------------------------*/

void mDelay(unsigned char j)

{

unsigned int i;

for(;j>0;j--)

{

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

{;}

}

}

/*------------------------------------------------

初始化定时器1

------------------------------------------------*/

void Init_Timer1(void)

{

TMOD |= 0x10;

TH1=0xff;                              /* Init value */

TL1=0x00;

//PT1=1;                   /* 优先级    */

EA=1;                      /* interupt enable */

ET1=1;                     /* enable timer1 interrupt */

TR1=1;

}

/*------------------------------------------------

启动IIC总线

------------------------------------------------*/

void Start(void)

{

Sda=1;

_nop_();

Scl=1;

_nop_();

Sda=0;

_nop_();

Scl=0;

}

/*------------------------------------------------

停止IIC总线

------------------------------------------------*/

void Stop(void)

{

Sda=0;

_nop_();

Scl=1;

_nop_();

Sda=1;

_nop_();

Scl=0;

}

/*------------------------------------------------

应答IIC总线

------------------------------------------------*/

void Ack(void)

{

Sda=0;

_nop_();

Scl=1;

_nop_();

Scl=0;

_nop_();

}

/*------------------------------------------------

非应答IIC总线

------------------------------------------------*/

void NoAck(void)

{

Sda=1;

_nop_();

Scl=1;

_nop_();

Scl=0;

_nop_();

}

/*------------------------------------------------

发送一个字节

------------------------------------------------*/

void Send(unsigned char Data)

{

unsigned char BitCounter=8;

unsigned char temp;

do

{

temp=Data;

Scl=0;

_nop_();

if((temp&0x80)==0x80)

Sda=1;

else

Sda=0;

Scl=1;

temp=Data<<1;

Data=temp;

BitCounter--;

}

while(BitCounter);

Scl=0;

}

/*------------------------------------------------

读入一个字节并返回

------------------------------------------------*/

unsigned char Read(void)

{

unsigned char temp=0;

unsigned char temp1=0;

unsigned char BitCounter=8;

Sda=1;

do

{

Scl=0;

_nop_();

Scl=1;

_nop_();

if(Sda)

temp=temp|0x01;

else

temp=temp&0xfe;

if(BitCounter-1)

{

temp1=temp<<1;

temp=temp1;

}

BitCounter--;

}

while(BitCounter);

return(temp);

}

/*------------------------------------------------

写入DA数模转换值

------------------------------------------------*/

void DAC(unsigned char Data)

{

Start();

Send(AddWr); //写入芯片地址

Ack();

Send(0x40);  //写入控制位,使能DAC输出

Ack();

Send(Data);  //写数据

Ack();

Stop();

}

/*------------------------------------------------

读取AD模数转换的值,有返回值

------------------------------------------------*/

unsigned char ReadADC(unsigned char Chl)

{

unsigned char Data;

Start();        //写入芯片地址

Send(AddWr);

Ack();

Send(0x40|Chl);//写入选择的通道,本程序只用单端输入,差分部分需要自行添加

//Chl的值分别为0、1、2、3,分别代表1-4通道

Ack();

Start();

Send(AddRd);    //读入地址

Ack();

Data=Read();    //读数据

Scl=0;

NoAck();

Stop();

return Data;   //返回值

}

void fmg(void)//fm关

{

Fm=1;        //                关 fm

}

void cmg(void)//数码管锁存函数                   关时钟DS1302

{

dula=1;

P0=0x00;

dula=0;

wela=1;

P0=0x00;

wela=0;

RST=0;                //                关时钟DS1302

}

/*------------------------------------------------

主程序

------------------------------------------------*/

void main()

{

unsigned char num;                   //DA数模输出变量

unsigned char ADtemp;                //定义中间变量

Init_Timer1();

cmg();//数码管锁存

fmg();

while(1)

{

DAC(num);       //DA输出,可以用LED模拟电压变化

num++;          //累加,到256后溢出变为0,往复循环。显示在LED上亮度逐渐变化

mDelay(20);     //延时用于清晰看出变化

if(ADFlag)      //定时采集输入模拟量

{

ADFlag=0;

}

}

}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33330157/article/details/117212961

智能推荐

黑马程序员——OC三大特性之封装_want_heima的博客-程序员资料

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------封装:隐藏内部细节,提高安全性

易安卓E4A_yiqi186的博客-程序员资料

www.uzzf.com/soft/348281.html易安卓是一款专为安卓系统开发、编程打造的工具,小编这里带来的易安卓E4A5.8破解版,新版加入了新的数据库,增加了一些新的命令和扩展组件等内容,有需要的欢迎下载。...

SSL详解_枫追忆-sunny的博客-程序员资料

SSL介绍:安全套接字(Secure Socket Layer,SSL)协议是Web浏览器与Web服务器之间安全交换信息的协议,提供两个基本的安全服务:鉴别与保密。SSL是Netscape于1994年开发的,后来成为了世界上最著名的web安全机制,所有主要的浏览器都支持SSL协议目前有三个版本:2、3、3.1,最常用的是第3版,是1995年发布的。SSL协议的三个特性① 保密:在握手协议中定义了会...

php函数_那年夏天KEEP的博客-程序员资料

usleep() 函数延迟代码执行若干微秒。unpack() 函数从二进制字符串对数据进行解包。uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID。time_sleep_until() 函数延迟代码执行直到指定的时间。time_nanosleep() 函数延迟代码执行若干秒和纳秒。sleep() 函数延迟代码执行若干秒。show_source() 函数对文件进行语法高亮显

Spring代码实例系列-10:通过Spring Mail发送简单邮件、附件和HTML邮件_hanchao5272的博客-程序员资料

超级通道:Spring代码实例系列-绪论本章通过Spring Mail实现了简单邮件、附件和HTML邮件的发送,涉及的主要知识点: 1. Spring mail实现:JavaMailSenderImpl 2. 简单消息:SimpleMailMessage 3. 扩展:MimeMessage 4. MIME(Multipurpose Internet Mail Extensions)多用

随便推点

手动生成rancher的kube-config_vah101的博客-程序员资料

使用rancher自带的kubeconfig的方法如https://blog.csdn.net/vah101/article/details/90789540 所示本文讨论在不经过rancher UI手动生成kube config的方法:首先,下载kubectl文件,执行如下命令,其中local为之前创建集群是采用的名称:cd /etc/kubernetes/ssl/kubectl config set-cluster local --certificate-authority=kube-.

Oracle数据块结构概述_cuibu1997的博客-程序员资料

整理自Oracle 11g R2官方文档《concepts》001 概述 Oracle数据库以数据块(也称为Oracle块或页)为单位,来管理数据库数据文件中的逻辑存储空间。数据块是数据库I/O的最小...

深度学习进行分布式训练(模型并行和数据并行优缺点)_深度学习并行计算‘的优劣_天天撸代码的博客-程序员资料

深度学习进行分布式训练(模型并行和数据并行优缺点):https://blog.csdn.net/qq_29462849/article/details/81185126

[安全攻防进阶篇] 八.那些年的熊猫烧香及PE病毒行为机理分析_熊猫烧香原理_Eastmount的博客-程序员资料

如果你想成为一名逆向分析或恶意代码检测工程师,或者对系统安全非常感兴趣,就必须要认真分析一些恶意样本。熊猫烧香病毒就是一款非常具有代表性的病毒,当年造成了非常大的影响,并且也有一定技术手段。本文将详细讲解熊猫烧香的行为机理,并通过软件对其功能行为进行分析,这将有助于我们学习逆向分析和反病毒工作。后续作者还将对其进行逆向调试,以及WannaCry勒索蠕虫、各种恶意样本及木马的分析。基础性文章,希望您喜欢!技术路上哪有享乐,加油~

云服务器被DDOS攻击该如何防御?_沃通WoTrus的博客-程序员资料

相信很多大型网站遭遇到DDoS攻击,导致网站无法访问而又难以解决,包括个人博客也会遭遇DDOS的“洗礼”,对此感同身受。所以,本文我们一起来了解下DDOS攻击并分享一些在一定程度范围内的应对方案。关于DDOS攻击分布式拒绝服务(DDoS:Distributed Denial of Service)攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力。通常,攻击者将攻击程序通过代理程序安装在网络上的各个“肉鸡”上,代理程

docker默认配置文件不存在问题解决_docker.service 不存在_z_qifa的博客-程序员资料

Docker默认的配置文件/etc/default/docker或者/etc/sysconfig/docker都不起作用,查看了一下/lib/systemd/system/docker.service文件,发现里面没有加载默认配置文件,一些配置不知道要怎么弄了~~~解决办法是:$ vi /lib/systemd/system/docker.service#添加一行$ Environment

推荐文章

热门文章

相关标签