zoukankan      html  css  js  c++  java
  • PCF8591读写

     

    PCF85918bitA/DD/A芯片,采用i2c接口,它有四路模拟输入口和一个模拟输出口,采样速率取决于i2c的速率。数据传输是高位在前低位在后(不论是主机写入数据,还是主机读取的数据)。

    写入数据时:起始信号->器件地址->应答信号->控制字节->写入的数据->应答信号(从机)->写入的数据->应答信号(从机)。。。。->停止信号

    读取数据时:起始信号->器件地址()->应答信号(从机)->控制字节->应答信号(从机)->停止信号(这个前提是设置读取的是哪一个通道,采用的哪种模式)    接着再是:起始信号->器件地址()->读取的字节->非应答信号(主机)->停止信号

    下图是AD通道自动增量模式采集数据时的数据格式:

    具体指令格式请参考PCF8591的数据手册。

     

    下面是PCF8591的模拟输出和模拟输入的程序:

    /************************************************************************
    **Describe:PCF85891数模和模数转换
    **    Time: 2015.5.20
    **  Author: zys
    *************************************************************************/
    #include <reg52.h>
    #include <intrins.h>
    
    sbit SCL = P1^5;
    sbit SDA = P3^6;
    
    #define ADONE 0.0198  //5.06/256V	PCF8591的Vref电压是5.06V
    
    /***本程序数码管是共阴极的***/
    const unsigned char smg_dp_yin[ 16 ] = {0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef,
    										0xf7, 0xfc, 0xb9, 0xde, 0xfb, 0xf1};//0. 1. 2. 3......f.
    										//共阴极,显示小数点
    										//不显示小数点:  smg_dp_yin[x] & 0x7f
    									//共阳极显示小数点: ~smg_dp_yin[x]
    								  //共阳极不显示小数点: ~(smg_dp_yin[x] | 0x80)
    
    /****数码管的位是通过74LS138控制的****/
    const unsigned char smg_8_pos[ 8 ] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; //对应P20,P21,P22,高位都为1,则与的时候P2的其他位不变
    const unsigned char smg_sum = 8;  //8位数码管
    
    void i2c_start( void );
    void i2c_stop( void );
    void i2c_ack( void );
    void master_ack();
    void master_notAck();
    void i2c_writeByte( unsigned char byte);
    unsigned char i2c_readByte( void );
    void PCF8591_wirteCommand( unsigned char addr, unsigned char command );
    void PCF8591_AOUT(unsigned char byte);
    unsigned char i2c_readADResult( void );
    void PCF8591_displayADResult( unsigned int ADResult);
    
    void delay( void );
    void i2c_delay( void );
    void delay_xms(unsigned int );
    
    /********************************************************
    **  函数名: void main( void )
    **输入参数:无
    **返回参数:无
    ********************************************************/
    void main( void )
    {
    	int  i = 0;
    	int ch = 0;	
    	while(1)
    	{
    		/*for(i = 0; i <= 255; i++)  //DA输出,呼吸灯效果
    		{
    			PCF8591_AOUT(i);
    			delay();
    		}
    		for(i = 255; i >= 0; i--)
    		{
    			PCF8591_AOUT(i);
    			delay();	   
    		} */
    		for(ch = 0; ch < 4; ch++) //循环采集四路电压
    		{
    			PCF8591_wirteCommand(0x90, 0x00+ch);
    			for(i = 0; i < 1000; i++)
    			{
    				PCF8591_displayADResult(i2c_readADResult());	
    			}
    		}		
    	}
    	
    }
    
    /********************************************************
    **  函数名: void i2c_start( void ),i2c起始信号
    **输入参数:无
    **返回参数:无
    ********************************************************/
    void i2c_start( void )
    {
    	SCL = 1;
    	SDA = 1;
    	i2c_delay();
    	SDA = 0;
    	i2c_delay();
    	SCL = 0;
    	i2c_delay();	
    }
    
    /********************************************************
    **  函数名: void i2c_stop( void ),i2c停止信号
    **输入参数:无
    **返回参数:无
    ********************************************************/
    void i2c_stop( void )
    {
    	SDA = 0;
    	i2c_delay();
    	SCL = 1;
    	i2c_delay();
    	SDA = 1;
    	i2c_delay();	
    }
    
    /********************************************************
    **  函数名: void i2c_ack( void ),i2c应答信号(从机)
    **输入参数:无
    **返回参数:无
    ********************************************************/
    void i2c_ack( void )
    {
    	int i = 0;
    	SCL = 0;
    	i2c_delay();
    	SDA = 1; 
    	i2c_delay();
    	SCL = 1;
    	i2c_delay();
    	while(SDA == 1);
    	/*while((SDA == 1) && ((i++) < 10))
    	{
    		_nop_();
    	}*/	
    } 
    
    /********************************************************
    **  函数名: void master_ack( void ),主机应答信号,在读取数据时
    **输入参数:无
    **返回参数:无
    ********************************************************/
    void master_ack( void )
    {
    	SCL = 0;
    	i2c_delay();  
    	SDA = 0;
    	i2c_delay();
    	SCL = 1;
    	i2c_delay();
    	SCL = 0;
    	i2c_delay();
    	SDA = 1;
    	i2c_delay();	
    }
    
    /********************************************************
    **  函数名: void master_notAck( void ),主机非应答信号,在读取数据时
    **输入参数:无
    **返回参数:无
    ********************************************************/
    void master_notAck( void )
    {
    	SCL = 0;
    	i2c_delay();
    	SDA = 1;
    	i2c_delay();
    	SCL = 1;
    	i2c_delay();  // 没下面四句程序读取不正常
    	SCL = 0;	  //
    	i2c_delay();  //
    	SDA = 0;	  //	
    }
    
    /********************************************************
    **  函数名: void i2c_writeByte,i2c写一个字节
    **输入参数:unsigned char byte
    **返回参数:无
    ********************************************************/
    void i2c_writeByte( unsigned char byte )
    {
    	char loop;
    	for(loop = 0; loop < 8; loop++)
    	{
    		SCL = 0;
    		i2c_delay();
    		if((byte<<loop)&0x80)  //数据是从高位到低位传输
    		{
    			SDA = 1;
    		}
    		else
    		{
    			SDA = 0;
    		}
    		i2c_delay();
    		SCL = 1;
    		i2c_delay();		
    	}
    }
    
    unsigned char i2c_readByte( void )
    {
    	int loop = 0;
    	unsigned char temp = 0;
    	unsigned char tempData = 0;
    	//SDA = 0;
    	for(loop = 7; loop >= 0; loop--)
    	{	
    		SCL = 0;
    		i2c_delay();	
    		temp = SDA;
    		i2c_delay();
    		SCL = 1;
    		i2c_delay();
    		tempData += (temp<<loop);
    		temp = 0;	
    	}
    	return tempData;			
    }
    
    /********************************************************
    **  函数名: void PCF8591_wirteCommand( unsigned char addr, unsigned char command ),PCF8591写控制指令
    **输入参数:unsigned char addr, unsigned char command
    **返回参数:无
    ********************************************************/
    void PCF8591_wirteCommand( unsigned char addr, unsigned char command )
    {								    
    	i2c_start();
    	i2c_writeByte(addr);
    	i2c_ack();
    	i2c_writeByte(command);
    	i2c_ack();
    	i2c_delay();	
    	i2c_stop();
    }
    
    /********************************************************
    **  函数名: unsigned char i2c_readADResult( void ),i2c读出一个字节
    **输入参数:无
    **返回参数:unsigned char
    ********************************************************/
    unsigned char i2c_readADResult( void )
    {	
    	unsigned char temp = 0;
    	i2c_start();
    	i2c_writeByte(0x91);
    	i2c_ack();
    	temp = i2c_readByte();
    	master_notAck();
    	i2c_stop();
    	return temp;	
    }
    
    /********************************************************
    **  函数名: void PCF8591_displayADResult( unsigned int ADResult),显示AD采集的数据
    **输入参数:unsigned int ADResult
    **返回参数:无
    ********************************************************/
    void PCF8591_displayADResult( unsigned int ADResult)
    {
    	char loop = 0;
    	unsigned int temp = ADONE * ADResult * 100; //两位小数取出来
    	unsigned int dec = 1;
    	for(loop = 7; loop >= 5; loop--)
    	{
    		if(loop == 5)
    		{
    			P0 = smg_dp_yin[temp/dec%10];
    		}
    		else
    		{
    			P0 = smg_dp_yin[temp/dec%10]&0x7f;
    		}
    		P2 = smg_8_pos[loop];
    		delay_xms(1);
    		dec *= 10;
    	}
    
    }
    
    /********************************************************
    **  函数名: void PCF8591_AOUT( unsigned char byte ),DA输出
    **输入参数:unsigned char byte
    **返回参数:无
    ********************************************************/
    void PCF8591_AOUT( unsigned char byte )
    {
    	i2c_start();
    	i2c_writeByte(0x90);
    	i2c_ack();
    	i2c_writeByte(0x40); //只有模拟输出AOUT
    	i2c_ack();
    	i2c_writeByte(byte);
    	i2c_ack();
    	i2c_stop();
    }
    
    /************************************************************************
    **函数名:void i2c_delay( void ),i2c专用延时
    **  功能:无
    **  参数: 无
    *************************************************************************/
    void i2c_delay( void )
    {
    	char loop;
    	for(loop = 0; loop < 5; loop++)
    	{
    		_nop_();
    	}
    }
    
    /************************************************************************
    **函数名:void delay_xms( unsigned int x )
    **  功能:延时xms
    **  参数: 无
    *************************************************************************/
    void delay_xms( unsigned int x )
    {
    	unsigned char j = 0;
    	while( x-- )
    	{
    		while( (j++) < 100 );
    		j = 0;
    	}
    }
    
    /************************************************************************
    **函数名:void delay( void ),在输出DA数据时使用的延时
    **  功能:无
    **  参数: 无
    *************************************************************************/
    void delay( void )
    {
    	unsigned int loop;
    	for(loop = 0; loop < 30; loop++)
    	{
    		_nop_();
    	}
    }


     

    不负自己
  • 相关阅读:
    python操作文件
    匿名函数 列表生成式 字典生成式 递归
    pecan API调用
    lvm磁盘分区
    PasteDeploy部署Pecan API 服务
    oslo_service服务
    python pbr 打包
    stevedore动态加载模块
    mongodb 副本集部署
    python装饰器
  • 原文地址:https://www.cnblogs.com/v-BigdoG-v/p/7398656.html
Copyright © 2011-2022 走看看