历史上的今天
返回首页

历史上的今天

今天是:2024年11月24日(星期日)

正在发生

2021年11月24日 | DA转换(IIC总线)

2021-11-24 来源:eefocus

项目描述

向PCF8591芯片的AN2通道输入一个电压模拟量,经过AD转换后,单片机通过IIC总线读取转换后的数据,并将其量化后实时显示在LCD上。然后将AD转换后的数据写入PCF8591中进行DA转换,并用LED灯的亮度来显示模拟量的大小。

仿真原理图如下:

在这里插入图片描述

C语言代码如下:


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

FileName: DAC.h

Function: 头文件

Author: Zhang Kaizhou

Date: 2019-6-13 17:12:49

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

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

#define FACTOR 0.01953125 // 量化单位(用一个字节来量化表示5V的电压值,共为256个量化等级; FACTOR = 5 / 256)

/*IIC总线端口定义*/

sbit SDA = P2^0;

sbit SCL = P2^1;


/*LCD1602显示模块端口定义*/

sbit lcdrs = P1^0;

sbit lcdrw = P1^1;

sbit lcden = P1^2;


/*IIC总线模块函数声明*/

void initIIC();

void startIIC();

void responseIIC();

void stopIIC();

void writeDataIIC(uchar dat);

void readDataIIC(uchar * dat);


/*DAC模块函数声明*/

void writeData8591(uchar dat);

void readData8591(uchar channel, uchar * dat);


/*LCD1602显示模块函数声明*/

void writeCommand(uchar command);

void writeDataLCD(uchar dat);

void delay(uint xms);

void LCDInit();

void display(uchar dat);


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

FileName: main.c

Function: ADC IIC

Description: 向PCF8591芯片的AN2通道输入一个电压模拟量,

经过AD转换后,单片机通过IIC总线读取转换后的数据,

并将其量化后实时显示在LCD上。

然后将AD转换后的数据写入PCF8591中进行DA转换,

并用LED灯的亮度来显示模拟量的大小。

Author: Zhang Kaizhou

Date: 2019-6-13 17:12:40

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

#include "DAC.h"


void main(){

uchar dat = 0;

initIIC();

LCDInit();

while(1){

/*AD转换*/

readData8591(2, &dat); // 读取通道2模拟输入量化后的数据

display(dat);

delay(10);

/*DA转换*/

writeData8591(dat);

delay(10);

}

}


/*向PCF85991写数据*/

void writeData8591(uchar dat){

/*向PCF8591写入地址字节和控制字节*/

startIIC();

writeDataIIC(0x90); // 向IIC总线发送寻址信号(PCF8591器件地址位90H),并声明要进行写操作

responseIIC();

writeDataIIC(0x40); // 向PCF8591写入控制字节(DA允许; AD为4路单端输入; 禁止自动增益)

responseIIC();

/*向PCF8591中写入要进行DA转换的数据*/

startIIC();

responseIIC();

writeDataIIC(0x90);

responseIIC();

writeDataIIC(dat);

responseIIC();

stopIIC();

}


/*从PCF8591的channel模拟输入所对应的ADC数据寄存器中读出数据到变量dat*/

void readData8591(uchar channel, uchar * dat){

/*向PCF8591写入地址字节和控制字节*/

startIIC();

writeDataIIC(0x90); // 向IIC总线发送寻址信号(PCF8591器件地址位90H),并声明要进行写操作

responseIIC();

writeDataIIC(0x40 | channel); // 向PCF8591写入控制字节(DA允许; AD为4路单端输入; 禁止自动增益; 选择通道channel)

responseIIC();

/*从PCF8591读取数据*/

startIIC();

writeDataIIC(0x91); // 向IIC总线发送寻址信号,并声明要进行读操作

responseIIC();

readDataIIC(dat);

stopIIC(); // 注意此处无响应信号,直接关闭IIC总线即可(否则会导致读取的数据不稳定)

}


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

FileName: IIC.c

Function: 实现IIC总线基本操作

Author: Zhang Kaizhou

Date: 2019-6-13 17:13:07

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

#include "DAC.h"


/*IIC总线初始化*/

void initIIC(){

SCL = 1;

_nop_();

SDA = 1;

_nop_();

}


/*IIC总线启动信号*/

void startIIC(){ // 在SCL高电平期间,SDA产生一个下降沿表示启动

SDA = 1;

_nop_();

SCL = 1;

_nop_();

SDA = 0;

_nop_();

}


/*IIC总线应答信号*/

void responseIIC(){ // 从机在SCL高电平期间将SDA拉低表示应答

SDA = 0;

_nop_();

SCL = 1;

_nop_();

SCL = 0;

_nop_();

}


/*IIC总线停止信号*/

void stopIIC(){ // 在SCL高电平期间,SDA产生一个上升沿表示停止

SDA = 0;

_nop_();

SCL = 1;

_nop_();

SDA = 1;

_nop_();

}


/*向IIC总线写一个字节数据*/

void writeDataIIC(uchar dat){

uchar i, temp;

temp = dat;

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

temp = temp << 1;

SCL = 0;

_nop_();

SDA = CY;

_nop_();

SCL = 1;

_nop_();

}

SCL = 0;

_nop_();

SDA = 1;

_nop_();

}


/*从IIC总线读一个字节数据*/

void readDataIIC(uchar * dat){

uchar i;

SCL = 0;

_nop_();

SDA = 1;

_nop_();

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

SCL = 1;

_nop_();

* dat = ((* dat) << 1) | SDA;

SCL = 0;

_nop_();

}

}


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

FileName:display.c

Function: LCD1602显示函数

Author: Zhang Kaizhou

Date: 2019-6-13 17:12:59

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

#include "DAC.h"


uchar code table0[] = {"ADC"};

uchar code table1[] = {"Voltage:"};

uchar code table2[] = {"0123456789"};

uchar num = 0;


/*初始化LCD1602的设置*/

void LCDInit(){

uchar i;

lcden = 0; // 拉低使能端,准备产生使能高脉冲信号

writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口)

writeCommand(0x0c); // 开显示,不显示光标

writeCommand(0x06); // 写一个字符后地址指针自动加1

writeCommand(0x01); // 显示清零,数据指针清零

/*LCD上电界面*/

writeCommand(0x80); // 将数据指针定位到第一行首

for(i = 0; i < strlen(table0); i++){

writeDataLCD(table0[i]);

delay(5);

}

writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首

for(i = 0; i < strlen(table1); i++){

writeDataLCD(table1[i]);

delay(5);

}

}


/*LCD显示函数*/

void display(uchar dat){

/*数据的量化*/

float temp = FACTOR * dat;

uchar i, j;

if(dat == 255){

i = 5;

j = 0;

}else{ // 分离整数和小数部分

i = (uchar)temp;

j = (temp - i) * 10;

}

/*数据显示*/

writeCommand(0x80 + 0x40 + strlen(table1));

writeDataLCD(table2[i]);

delay(5);

writeCommand(0x80 + 0x40 + strlen(table1) + 1);

writeDataLCD('.');

delay(5);

writeCommand(0x80 + 0x40 + strlen(table1) + 2);

writeDataLCD(table2[j]);

delay(5);

}


/*写指令函数*/

void writeCommand(uchar command){

lcdrs = 0; // 命令选择

lcdrw = 0;

P0 = command;

delay(5);

lcden = 1; // 产生一个正脉冲使能信号

delay(5);

lcden = 0;

}


/*写数据函数*/

void writeDataLCD(uchar dat){

lcdrs = 1; // 数据选择

lcdrw = 0;

P0 = dat;

delay(5);

lcden = 1;

delay(5);

lcden = 0;

}


/*延时xms函数*/

void delay(uint xms){

uint i, j;

for(i = xms; i > 0; i--)

for(j = 110; j > 0; j--);

}

推荐阅读

史海拾趣

Conxall公司的发展小趣事

在国内市场取得一定成绩后,Conxall公司开始将目光投向海外市场。公司积极参加国际电子展,与海外客户建立联系,拓展销售渠道。同时,公司还针对不同国家和地区的市场需求,推出定制化产品,赢得了海外客户的青睐。

Fenwal Controls公司的发展小趣事

Fenwal Controls深知,只有与合作伙伴携手共进,才能实现共赢。因此,公司积极寻求与产业链上下游企业的合作机会。通过与原材料供应商、设备制造商、分销商等合作伙伴的紧密合作,Fenwal Controls不仅降低了采购成本、提高了生产效率,还拓展了销售渠道、增强了品牌影响力。这些合作关系的建立,为Fenwal Controls的长期发展奠定了坚实基础。

Advanced Analog公司的发展小趣事

随着技术的不断进步和市场需求的多样化,Advanced Analog的产品逐渐应用于更广泛的领域。从最初的TFT-LCD面板,到后来的数字相机、手持装置、网络通讯装置等领域,Advanced Analog都提供了完整的解决方案和优质的服务。通过与各行业合作伙伴的紧密合作,Advanced Analog的产品助力众多电子设备实现了更高效、更稳定的性能,推动了整个电子行业的发展。

Collins Electronics Corp公司的发展小趣事

随着公司规模的扩大,Collins Electronics Corp开始将目光投向国际市场。他们积极参加国际电子展会,与世界各地的潜在客户和合作伙伴交流。通过与不同国家的企业合作,公司成功打入了国际市场,产品销量大幅提升。这一过程中,他们不仅学习了国际先进的电子技术,还积累了丰富的跨国运营经验。

BAND-IT公司的发展小趣事

随着电子行业的全球化发展,BAND-IT公司也开始了其全球布局的步伐。作为IDEX Corporation的子公司,BAND-IT在全球范围内建立了销售和制造设施网络,为全球客户提供服务。其产品线不断丰富和完善,涵盖了从扎带、扎扣到紧带机、打包机等各类紧固解决方案。同时,BAND-IT公司还积极投入研发,不断创新产品和技术,以适应电子行业日新月异的发展需求。在全球化的浪潮中,BAND-IT以其卓越的品质和创新能力,赢得了全球客户的信赖和认可。

以上五个故事分别从初创挑战、深海钻探、太空探索、大型基础设施建设以及全球布局等方面展现了BAND-IT公司在电子行业中的发展历程。这些故事基于事实性的描述,旨在展示BAND-IT在电子行业中的发展和贡献,不涉及主观评价。

BLACK&DECKER公司的发展小趣事

BLACK&DECKER在技术创新方面一直走在行业前列。公司不断投入研发资源,推动电动工具技术的进步。例如,1979年,BLACK&DECKER发布了第一台手提式充电吸尘器Dustbuster,这一创新产品迅速成为市场上的热销产品,并推动了整个吸尘器行业的发展。此外,BLACK&DECKER还积极参与行业标准的制定工作,通过制定严格的产品质量标准和安全规范,为整个电子行业的健康发展做出了贡献。

问答坊 | AI 解惑

protel问题

刚开始学这个东西,麻烦各位高手指点下: 原理图中我想在一根导线的两头分别定义不同的网络标号,但是电气检查的时候总是提示错误,我看英文的意思应该是重复定义或者是多重定义,怎么弄能电气检查不报错呢?…

查看全部问答>

语音芯片

本帖最后由 paulhyde 于 2014-9-15 09:28 编辑 基于ISD4000系列芯片智能录放系统设计(www.nkcpu.cn  …

查看全部问答>

温度是否对单片机有影响

大家好,我是一个新人,前几天我们做的一个电子产品在做低温试验时,整个由单片机控制的部分都失效了,在室温放一段时间后又都正常了,我想问一问这大概是什么原因,是单片机或程序的问题吗,还是外围电路的问题。请大家发表意见,帮忙看一看!谢谢 ...…

查看全部问答>

谁能对比一下国内的几家电源企业?

今年台达,光宝,和powerland都在我们学校招聘,大家能给些这几家公司的意见么?…

查看全部问答>

自己在家用什么东西做串口通信的实验呢?求大虾指教

毕业了,老师让给做个串口通信的东西。在家没办法做实验,请高手指教啊!…

查看全部问答>

EVC的编译错误,主要是error LNK2019,高手请进,轻松拿分

ps2keybd.obj : error LNK2019: unresolved external symbol \"int __cdecl KernelIoControl(unsigned long,void *,unsigned long,void *,unsigned long,unsigned long *)\" (?KernelIoControl@@YAHKPAXK0KPAK@Z) referenced in function \"public: ...…

查看全部问答>

WINCE里面,自己写的流接口驱动,怎么实现可以让应用程序向驱动里面注册一个回调函数?看到WINCE驱动里面有很多注册回调函数的驱动程序!

WINCE里面,自己写的流接口驱动,怎么实现可以让应用程序向驱动里面注册一个回调函数?看到WINCE驱动里面有很多注册回调函数的驱动程序! 所以想实现这个机制,这样很方便的,也不用驱动给AP发消息了!!!…

查看全部问答>

时钟芯片的比较

对时间精度要求很高的情况下,典型的时钟芯片有:DS1302,DS12887,X1203等都可以满足高精度的要求 精度比较高的就是深圳威帆电子公司生产的SD2000系列 精度到底那个更好点啊,要做个类似万年历的,显示年,月,日,时,分,秒,并可调整…

查看全部问答>

minicom启动后停在Uncompressing Linux......后不动了,为什么

虚拟机已经添加了串口设备,minicom的设置也已经设置好. 串口设置成/dev/ttyS0, BPS设置成:1152008N1. Hardware Flow Control:No. 启动minicom时出现以下这些字符,然后就停在那儿不动了,为什么? Uncompressing Linux.......................... ...…

查看全部问答>

用3.7V的锂电池供电,要得到2.5V,2.8V,3.3V的输出需要用电源芯片吗?

在做个mp3,想用3.7V的锂电池供电,要得到2.5V,2.8V,3.3V的输出需要用电源芯片吗?串联电阻或是二极管降压可以吗?…

查看全部问答>