数模转换(芯片PCF8591)
时间:2018-03-08作者:华清远见
一.AD转换的概念 AD转换的功能是把模拟量电压转换为数字量电压。DA转换的功能正好相反,就是将数字量转换位模拟量。 二.芯片PCF8591介绍 PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行I²C总线接口。PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,允许在同个I2C总线上接入8个PCF8591器件,而无需额外的硬件。在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I²C总线以串行的方式进行传输。 PCF8591 是具有I2C 总线接口的8 位A/D 及D/A 转换器。有4 路A/D 转换输入,1 路D/A 模拟输出。这就是说,它既可以作A/D 转换也可以作D/A 转换。A/D 转换为逐次比较型。电源电压典型值为5V。 AIN0~AIN3:模拟信号输入端。 A0~A3:引脚地址端。 VSS:电源负极。 SDA、SCL:I2C 总线的数据线、时钟线。 OSC:外部时钟输入端,内部时钟输出端。 EXT:内部、外部时钟选择线,使用内部时钟时EXT 接地。 AGND:模拟信号地。 VREF:基准电源端。 AOUT:D/A 转换输出端。 VDD:电源端。(2.5~6V)
模块原理图 PCF8591的器件地址: PCF8591 采用典型的I2C 总线接口器件寻址方法,即总线地址由器件地址、引脚地址和方向位组成。飞利蒲公司规定A/D 器件地址为1001。引脚地址A2A1A0,其值由用户选择,因此I2C 系统中最多可接2^3=8 个具有I2C 总线接口的A/D 器件。地址的最后一位为方向位R/w ,当主控器对A/D 器件进行读操作时为1,进行写操作时为0。总线操作时,由器件地址、引脚地址和方向位组成的从地址为主控器发送的第一字节。
D7~D4:1001 D3~D1:分别是A2、A1、A0的电平,我们原理图上面是全部接地,所以为000。 D0:为方向设置,当为1时进行读操作,当为0时进行写操作。 PCF8591的控制寄存器
D1、D0:AD通道选择00通道0,01通道1,10通道2,11通道3 D2:自动增益选择(有效位为1) D5、D4:输入模式选择:00四路单数输入;01三路差分输入;10单端与差分配合输入;11为模拟输入有效 D6:模拟输出使能位。(时能为1) I2C总线的数据传送 起始、终止、应答信号时序图 主机可以采用不带I2C总线接口的单片机,如80C51、AT89C2051等单片机,利用软件实现I2C总线的数据传送,即软件与硬件结合的信号模拟。为了保证数据传送的可靠性,标准的I2C总线的数据传送有严格的时序要求。I2C总线的起始信号、终止信号、发送“0”及发送“1”的模拟时序 :
起始信号程序: void Start_I2c() { sda=1; /*发送起始条件的数据信号*/ _nop_(); scl=1; _nop_(); /*起始条件建立时间大于4.7us,延时*/ _nop_(); _nop_(); _nop_(); _nop_(); sda=0; /*发送起始信号*/ _nop_(); /* 起始条件锁定时间大于4μs*/ _nop_(); _nop_(); _nop_(); _nop_(); scl=0; /*开启I2C总线,准备发送或接收数据 */ _nop_(); _nop_(); } 终止信号程序: void Stop_I2c() { sda=0; /*发送结束条件的数据信号*/ _nop_(); /*发送结束条件的时钟信号*/ scl=1; /*结束条件建立时间大于4μs*/ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda=1; /*发送I2C总线结束信号*/ _nop_(); _nop_(); _nop_(); _nop_(); } 应答信号程序: void Ack_I2c(bit a) { if(a==0)sda=0; /*在此发出应答或非应答信号 */ else sda=1; _nop_(); _nop_(); _nop_(); scl=1; _nop_(); /*时钟低电平周期大于4μs*/ _nop_(); _nop_(); _nop_(); _nop_(); scl=0; /*清时钟线,开启I2C总线以便继续接收*/ _nop_(); _nop_(); } PCF8591的写入 第一个字节是器件地址和读写控制 第二个字节被存到控制寄存器,用于控制器件功能。 第三个字节被存储到DAC数据寄存器,并使用片上D/A转换器转换成对应的模拟电压。(所以不输入D/A时,可以不用输入。) PCF8591发送一个字节的程序 bit PCF8591_SendByte(unsigned char addr,unsigned char channel) { Start_I2c(); //启动总线 I2C_SendByte(addr); //发送器件地址 if(ack==0)return(0); I2C_SendByte(0x40|channel); //发送控制字节 if(ack==0)return(0); Stop_I2c(); //结束总线 return(1); } PCF8591的读取 读取的第一个字节是包含上一次转换结果。将上一个字节读取时,才开始进行这次转换的采样。读取的第二个字节才是这次的转换结果。所以读取转换结果的步骤是:发送转换命令,将上次的结果读走,然后等一会儿,然后读取结果。
PCF8591读取一个字节的程序: unsigned char PCF8591_RcvByte(unsigned char addr) { unsigned char dat; Start_I2c(); //启动总线 I2C_SendByte(addr+1); //发送器件地址 if(ack==0)return(0); dat=I2C_RcvByte(); //读取数据 Ack_I2c(1); //发送非应答信号 Stop_I2c(); //结束总线 return(dat); } PCF8591发送一次转换的程序: bit Pcf8591_DaConversion(unsigned char addr,unsigned char channel, unsigned char Val) { Start_I2c(); //启动总线 I2C_SendByte(addr); //发送器件地址 if(ack==0)return(0); I2C_SendByte(0x40|channel); //发送控制字节 if(ack==0)return(0); I2C_SendByte(Val); //发送DAC的数值 if(ack==0)return(0); Stop_I2c(); //结束总线 return(1); } 相关资讯
发表评论
|