基于PCF8591设计的数字电压表.doc

上传人:夺命阿水 文档编号:14124 上传时间:2022-06-28 格式:DOC 页数:14 大小:77.50KB
返回 下载 相关 举报
基于PCF8591设计的数字电压表.doc_第1页
第1页 / 共14页
基于PCF8591设计的数字电压表.doc_第2页
第2页 / 共14页
基于PCF8591设计的数字电压表.doc_第3页
第3页 / 共14页
基于PCF8591设计的数字电压表.doc_第4页
第4页 / 共14页
基于PCF8591设计的数字电压表.doc_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《基于PCF8591设计的数字电压表.doc》由会员分享,可在线阅读,更多相关《基于PCF8591设计的数字电压表.doc(14页珍藏版)》请在课桌文档上搜索。

1、学习情境1-数字电压表的设计之 基于PCF8591设计的数字电压表 点名,复习1、 ADC0832的引脚及其功能,以及与单片机的硬件连接?2、 ADC0808的引脚及其功能,以及与单片机的硬件连接?引言:PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行IC总线接口。PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,允许在同一个IC总线上接入8个PCF8591器件,而无需额外的硬件。在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向IC总线以串行的方式进展传输。 新课讲授3.

2、3 基于PCF8591设计的数字电压表3.31PCF8591简介PCF8591的功能包括多路模拟输入、置跟踪保持、8-bit模数转换和8-bit数模转换。PCF8591的最大转化速率由IC总线的最大速率决定。1、主要技术指标和特性 单独供电 PCF8591的操作电压围2.5V-6V 低待机电流 通过I2C总线串行输入/输出 PCF8591通过3个硬件地址引脚寻址 PCF8591的采样率由I2C总线速率决定 4个模拟输入可编程为单端型或差分输入 自动增量频道选择 PCF8591的模拟电压围从Vss到VDD PCF8591置跟踪保持电路 8-bit逐次逼近A/D转换器 通过1路模拟输出实现DAC增

3、益 2、PCF8591引脚功能图3-3-1 PCF8591引脚图AIN0AIN3:模拟信号输入端。 A0A3:引脚地址端。 VDD、VSS:电源端。 2.56V SDA、SCL:I2C 总线的数据线、 时钟线。 OSC:外部时钟输入端,部时钟输出端。 E*T:部、外部时钟选择线,使用部时钟时 E*T 接地。 AGND:模拟信号地。 AOUT:D/A 转换输出端。 VREF:基准电源端。3、PCF8591部构造图图3-3-2 PCF8591部构造图4 功能描述1地址IIC总线系统中的每一片PCF8591通过发送有效地址到该地址器件来激活。该地址包括固定局部和可编程局部。可编程局部必需根据地址引脚

4、A0、A1和A2来设置。在IIC总线协议中地址必需是起始条件后作为第一个字节发送。地址字节的最后一位是用于设置以后数据传输方向的读/写。1001A0A1A2R/ 固定局部 可编程局部2控制字控制字节用于实现器件的各种功能,如模拟信号由哪几个通道输入等。控制字节存放在控制存放器中。总线操作时为主控器发送的第二字节。其格式如下所示:其中:D1、D0两位是A/D通道00通道0,01通道1,10通道2,11通道3D2 自动增益选择有效位为1D5、D4模拟量输入选择:00为四路单端数入、01为三路差分输入、10为单端与差分配合输入、11为模拟输出允许有效当系统为A/D转换时,模拟输出允许为0。模拟量输入

5、选择位取值由输入方式决定:四路单端输入时取00,三路差分输入时取01,单端与差分输入时取10,二路差分输入时取11。最低两位时通道编号位,当对0通道的模拟信号进展A/D转换时取00,当对1通道的模拟信号进展A/D转换时取01,当对2通道的模拟信号进展A/D转换时取10,当对3通道的模拟信号进展A/D转换时取11。在进展数据操作时,首先是主控器发出起始信号,然后发出读寻址字节,被控器做出应答后,主控器从被控器读出第一个数据字节,主控器发出应答,主控器从被控器读出第二个数据字节,主控器发出应答一直到主控器从被控器中读出第n个数据字节,主控器发出非应答信号,最后主控器发出停顿信号。3A/D转换A/D

6、转换器采用逐次逼近转换技术。在A/D转换周期将临时使用片上转换器和高增益比拟器。一个A/D转换周期总是开场于发送一个有效读模式地址给PCF8591之后。A/D转换周期子在应答时钟脉冲的后延被触发。并在传输前一次转换结果时执行见图3-3-3图3-3-3 A/D转换一旦一个转换周期被触发,所选通的输入电压采样将保存到芯片并被转换为对应的8位二进制码,取自差分输入的采样将被转换为8位二进制补码 转换结果被保存在ADC数据存放器等待传输。如果自动增量标志被置1,将选择下一个通道。在读周期传输的第一个字节包含前一次读周期的转换结果代码,以上电复位之后读取的第一个字节是0*80。最高A/D转换速率取决于实

7、际的IIC总线速度。4D/A转换发送给PCF8591的第三个字节被存储到DAC数据存储器,并使用片D/A转换器转换成对应的模拟电压。这个D/A 转换器由连接到外部参考电压的具有256个接头的电阻分压电路和选择开关组成。接头译码器切换一个接头至DAC输出线。模拟输出电压由自动清零单位增益放大器缓冲。这个缓冲放大器可通过设置控制存放器的模拟输出允许标志来翻开或关闭。在激活状态,输出电压将保持到新的数据字节被发送。提供应模拟输出AOUT的输出电压由下式给出。D/A转换顺序的波形图如图3-3-5= +图3-3-4 D/A转换5振荡器片上振荡器产生A/D转换周期和刷新自动清零缓冲放大器需要的时钟信号。在

8、使用这个振荡器时E*T引脚必须连接到VSS。在OSC引脚振荡频率是可用的。如果E*T引脚被连接到VDD,振荡输出OSC将切换到高阻态以允许用户连接外部时钟信号至OSC。6 I2C总线特性I2C总线是不同的IC或模块之间的双向两线通信,这两条线是串行数据线SDA和串行时钟线SCL,这两条线必须通过上拉电阻连接至正电源。数据传输只能是在总线不忙时启动。1位传输 一个数据位在每一个时钟脉冲期间传输。SDA线上的数据必须在时钟脉冲的高电平期间保持稳定。这个期间数据线上的改变被当作控制信号。图3-3-5 位传输2开场或停顿条件 数据和时钟线在总不忙时保持高电平。在时钟为高电平时,数据线上的一个由高到低的

9、变化被定义为开场条件。时钟为高电平时,数据线上的一个由低到高的变化被定义为停顿条件。图3-3-6 开场和停顿条件3系统配置 产生信息的器件称作“发送机,接收信息的器件称作“接收机。控制信息的器件称作“主机,被控制的器件称作“从机。图3-3-7 系统配置4应答在开场和停顿条件之间从发送机传输到接收机的数据字节数是没有限制的。每个8位数据字节之后紧跟着一个应答位。应答位是由发送机放在总线的一个高电平,而主机也产生一个额外的与应答有关的时钟脉冲。地址匹配的从接收机必须在接收每一个字节后产生一个应答。在应答时钟脉冲期间,应答的器件必须将SDA线拉低。因此在应答相应的时钟脉冲的高电平期间,SDA线必须保

10、持稳定的低电平。在由从机终止的最后一个字节,主接收机必须通过产生一个低电平应答向发送机发送一个数据完毕信号,这样发送机必须将数据线SDA拉高以允许主机产生停顿条件。 图3-3-8 I2C 总线应答5总线协议在开场条件后一个有效的硬件地址必须发送至PCF8591。读/写位定义了以后单个或多个字节数据传输的方向。开场条件、停顿条件和应答位的格式应定时参考I2C总线特性。在写模式数据传输通过发送下一个数据的停顿条件或开场条件来约束。图3-3-9 写模式的总线协议,D/A转换图3-3-10 读模式的总线协议,A/D转换 系统硬件设计 硬件电路主要包含单片机最小系统、PCF8591电压数据采集模块电路、

11、LCD1602显示模块。它们之间的具体连接如图6-3-11所示。图3-3-11 系统硬件连接图 系统软件设计本工程在软件设计方面主要有三个源程序:PCF8591.C、LCD1602.C和MAIN.C。在此我们主要介绍PCF8591.C源程序的设计。根据对PCF8591芯片的详细分析,PCF8591.C源程序由以下8个子程序构成:1、启动I2C总线子程序void IIC_Start(void) /EA=0; /时钟保持高,数据线从高到低一次跳变,I2C通信开场 SDA = 1; SCL = 1; delay4us(); / 延时5us SDA = 0; delay4us(); SCL = 0;2

12、、停顿I2C总线子程序void IIC_Stop(void) SDA = 0; /时钟保持高,数据线从低到高一次跳变,I2C通信停顿 SCL = 1; delay4us(); SDA = 1; delay4us(); SCL = 1;3、从机发送应答子程序void Slave_ACK(void) SDA = 0; SCL = 1; delay4us(); SCL = 0; SDA = 1;4、从机发送非应答子程序void Slave_NOACK(void) SDA = 1; SCL = 1; delay4us(); SDA = 0; SCL = 0;5、主机应答位检查子程序void check

13、_ACK(void) SDA = 1; / 将p1.0设置成输入,必须先向端口写1 SCL = 1; F0 = 0; if(SDA = 1) / 假设SDA=1说明非应答,置位非应答标志F0 F0 = 1; SCL = 0;6、发送一个字节子程序void IIC_SendByte(uchar ch) uchar idata n=8; / 向SDA上发送一位数据字节,共八位 while(n-) if(ch&0*80) = 0*80) / 假设要发送的数据最高位为1则发送位1 SDA = 1; / 传送位1 SCL = 1; delay4us(); SDA = 0; SCL = 0; else S

14、DA = 0; / 否则传送位0 SCL = 1; delay4us(); SCL = 0; ch = ch1; / 数据左移一位 7、接收一个字节子程序uchar IIC_ReceiveByte(void) uchar i,rd = 0*00;for(i=0;i8;i+) SCL = 1;rd = 1;rd |= SDA;delay4us();SCL = 0;delay4us();/SCL = 1;delay4us();return rd; 8、A/D转换子程序void ADC_PCF8591(uchar controlbyte) uchar idata receive_data,i=0;

15、IIC_Start(); IIC_SendByte(PCF8591_WRITE); /控制字 check_ACK(); if(F0 = 1) IIC_Error = 1; return; IIC_SendByte(controlbyte); /控制字 check_ACK(); if(F0 = 1) IIC_Error = 1; return; IIC_Start(); /重新发送开场命令IIC_SendByte(PCF8591_READ); /控制字 check_ACK(); if(F0 = 1) IIC_Error = 1; return; while(i4) receive_data=II

16、C_ReceiveByte(); receive_bufi+=receive_data; Slave_ACK(); / 收到一个字节后发送一个应答位 Slave_NOACK(); / 收到最后一个字节后发送一个非应答位 IIC_Stop();9、D/A转换子程序void DAC_PCF8591(uchar controlbyte,uchar wdata) IIC_Start(); / 启动I2C IIC_SendByte(PCF8591_WRITE); / 发送地址位 check_ACK(); / 检查应答位 if(F0 = 1) IIC_Error = 1; return; / 假设非应答说

17、明器件错误或已坏,置错误标志位SystemError IIC_SendByte(controlbyte&0*77); /Control byte check_ACK(); / 检查应答位 if(F0 = 1) IIC_Error = 1; return; / 假设非应答说明器件错误或已坏,置错误标志位SystemError IIC_SendByte(wdata); /data byte check_ACK(); / 检查应答位 if(F0 = 1) IIC_Error = 1; return; / 假设非应答说明器件错误或已坏,置错误标志位SystemError IIC_Stop(); / 全

18、部发完则停顿 delay4us(); delay4us(); delay4us(); delay4us();需要注意的是,在PROTEUS7.5仿真条件下无法把4路模拟通道的效果仿真出来,只有AINO通道有效。但在PROTEUS7.8仿真有效。 课堂小结本节课主要详细介绍了pcf8591芯片的有关技术资料和具体用法,重点分析了PCF8591.C源程序的设计。 完整程序代码1、MAIN.C源程序*include *include *define uchar unsigned char*define uint unsigned intuint Disp_Voltage=0,0,0;uchar LC

19、D_Line1=1- . V 2- . v;uchar LCD_Line2=3- . V 4- . v;e*tern uchar idata receive_buf; / 数据接收缓冲区e*tern void Initialize_LCD1602(); /液晶初始化函数e*tern void ADC_PCF8591(uchar controlbyte);/连续读入4路通道的A/D转换结果到receive_bufe*tern void DAC_PCF8591(uchar controlbyte,uchar wdata);e*tern void LCD_Display(uchar p,uchar

20、*str);/在LCD上显示字符串/函数申明void Convert_To_Voltage(uchar result);/将模数转换结果得到的数值分解后放入缓冲数组中void Refesh_LCD(); /显示刷新函数,把ADC转换结果送入显示缓冲数组/-/ 函数名称: main/ 函数功能: 主程序/-void main() Initialize_LCD1602(); while(1) ADC_PCF8591(0*04); Refesh_LCD(); /液晶2行显示4个通道的转换结果 LCD_Display(0*00,LCD_Line1);LCD_Display(0*40,LCD_Line2

21、);/将0通道模拟转换后的结果重新转换为模拟量并从Aout引脚输出/结果通过LED的亮度表现出来,在真实的硬件上该函数调用才有效,在Proteus中看不到效果 DAC_PCF8591(0*40,receive_buf0);/-/ 函数名称:Convert_To_Voltage()_/将模数转换结果得到的数值分解后放入缓冲数组中/-void Convert_To_Voltage(uchar result) uchar temp; /最大值为255,对应5V,255/5=51 Disp_Voltage2 =result/51+0; /整数局部 temp=result%51*10; /第1位小数 D

22、isp_Voltage1 =temp/51+0; temp=temp%51*10; /第2位小数 Disp_Voltage0 =temp/51+0; /-/显示刷新函数,把ADC转换结果送入显示缓冲数组/-void Refesh_LCD() /将4个模拟通道模数转换结果放入LCD显示缓冲LCD_Line1和LCD_Line2 Convert_To_Voltage(receive_buf0); LCD_Line12=Disp_Voltage2; LCD_Line14=Disp_Voltage1; LCD_Line15=Disp_Voltage0; Convert_To_Voltage(recei

23、ve_buf1); LCD_Line111=Disp_Voltage2; LCD_Line113=Disp_Voltage1; LCD_Line114=Disp_Voltage0; Convert_To_Voltage(receive_buf2); LCD_Line22=Disp_Voltage2; LCD_Line24=Disp_Voltage1; LCD_Line25=Disp_Voltage0; Convert_To_Voltage(receive_buf3); LCD_Line211=Disp_Voltage2; LCD_Line213=Disp_Voltage1; LCD_Line2

24、14=Disp_Voltage0;2、PCF8591.C源程序/-/ pcf8591驱动程序/-函数声明,变量定义-*include *include *define uchar unsigned char*define uint unsigned intsbit SDA=P11; / 将p1.0口设置为模拟数据口sbit SCL=P10; / 将p1.1口设置为模拟时钟口*define delay4us(); _nop_();_nop_();_nop_();_nop_();_nop_(); bit bdata IIC_Error; / 从机错误标志位/PCF8591专用变量定义-*defin

25、e PCF8591_WRITE 0*90*define PCF8591_READ 0*91*define NUM 4 / 接收和发送缓存区的深度uchar idata receive_bufNUM; / 数据接收缓冲区/- 具体函数参见本文正文。3、 LCD1602.C源程序/液晶控制与显示驱动程序*include *include *include *define uchar unsigned char*define uint unsigned int*define delay4us() _nop_();_nop_();_nop_();_nop_();sbit RS = P20;sbit R

26、W = P21;sbit E = P22;/ 延时void Delay(uint *) uchar i; while(*-)for(i=0;i120;i+)delay4us()/-忙检查-/uchar LCD_Busy_Check() uchar LCD_Status;RS = 0;RW = 1;E = 1;delay4us();LCD_Status = P0;E = 0;return LCD_Status;/-向LCD写入命令-/void Write_LCD_mand(uchar cmd) while(LCD_Busy_Check()& 0*80)=0*80); /忙等待RS = 0;RW

27、= 0;E = 0;P0 = cmd;delay4us();E = 1;delay4us();E = 0;/-向LCD写入一个字节的数据函数-*/void Write_LCD_Data(uchar dat) while(LCD_Busy_Check()&0*80)=0*80);RS = 1;RW = 0;E = 0;P0 = dat;delay4us();E = 1;delay4us();E = 0;/-LCD初始化-*/void Initialize_LCD1602() /液晶初始化函数 Write_LCD_mand(0*38);Delay(5);/功能设置,数据长度为8位,双行显示,57点

28、阵字体 Write_LCD_mand(0*0C);Delay(5);/字符进入模式:屏幕不动,字符后移 Write_LCD_mand(0*06);Delay(5); / 显示开,关光标 Write_LCD_mand(0*01);Delay(5); /清屏/设置显示位置void Set_LCD_Position(uchar pos) Write_LCD_mand(pos|0*80);/-在LCD上显示字符串-*/void LCD_Display(uchar p,uchar *str) uchar i; Set_LCD_Position(p); for(i=0;istrlen(str);i+) Write_LCD_Data(stri);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 在线阅读 > 生活休闲


备案号:宁ICP备20000045号-1

经营许可证:宁B2-20210002

宁公网安备 64010402000986号