PIC16 PCF8591

模拟IIC的方式 PIC16F887 XCV1.41


#define SCL_H	TRISC0	= 0, RC0 = 1    /* SCL管脚置高  IIC两个通信端口 */
#define SCL_L	TRISC0	= 0, RC0 = 0    /* SCL管脚置低 */
#define SDA_H	TRISC1	= 0, RC1 = 1    /* SDA管脚置高 */
#define SDA_L	TRISC1	= 0, RC1 = 0    /* SDA管脚置低 */

#define SDA_IN	TRISC1	= 1             /* SDA输入模式 */
#define SDA_OUT TRISC1	= 0             /* SDA输出模式 */
#define SDA_VAL RC1                     /* SDA的位值读取 */

#define TRUE	1
#define FALSE	0

#define PCF8591Address	0x90            /*PCF8591的设备地址*/
#define PCF8591Control	0x40            /*   AD转换 开启   */

void start( void )
{
	SCL_H;
	SDA_H;
	NOP();
	SDA_L;
	NOP();
	SCL_L;
	NOP();
}


void stop( void )
{
	SDA_L;
	NOP();
	SCL_H;
	NOP();
	SDA_H;
	NOP();
}


void mack( void )
{
	SDA_L;
	NOP(); NOP();
	SCL_H;
	NOP();
	SCL_L;
	NOP(); NOP();
	SDA_H;
	NOP();
}


void mnack( void )
{
	SDA_H;
	NOP(); NOP();
	SCL_H;
	NOP();
	SCL_L;
	NOP(); NOP();
	SDA_L;
	NOP();
}


char check( void )
{
	char slaveack;

	SDA_H;
	NOP(); NOP();
	SCL_H;
	NOP(); NOP();
	SDA_IN;
	NOP(); NOP();
	slaveack = SDA_VAL;     /* 读入SDA数值 */
	SCL_L;
	NOP();
	SDA_OUT;
	if ( slaveack )
		return(FALSE);
	else return(TRUE);      /* 从机0代表有应答 注意!! */
}


/********************************************************************
*  函数名称:write1
*  功    能:向I2C总线发送一个1
*  参    数:无
*  返回值  :无
********************************************************************/
void write1( void )
{
	SDA_H;
	NOP();
	SCL_H;
	NOP();
	SCL_L;
	NOP();
}


/********************************************************************
*  函数名称:write0
*  功    能:向I2C总线发送一个0
*  参    数:无
*  返回值  :无
********************************************************************/
void write0( void )
{
	SDA_L;
	NOP();
	SCL_H;
	NOP();
	SCL_L;
	NOP();
}


/********************************************************************
*  函数名称:write1byte
*  功    能:向I2C总线发送一个字节的数据
*  参    数:WriteData -- 发送的数据
*  返回值  :无
********************************************************************/
void write1byte( unsigned char WriteData )
{
	unsigned char i;
	for ( i = 8; i > 0; i-- )
	{
		if ( WriteData & 0x80 )
			write1();
		else write0();
		WriteData <<= 1;
	}
	SDA_H;
	NOP();
}


/********************************************************************
*  函数名称:writeNbyte
*  功    能:向I2C总线发送N个字节的数据
*  参    数:outbuffer -- 指向发送数据存放首地址的指针
*         n         -- 数据的个数
*  返回值  :1--发送成功,0--失败
********************************************************************/
unsigned char writeNbyte( unsigned char * outbuffer, unsigned char n )
{
	unsigned char i;
	for ( i = 0; i < n; i++ )
	{
		write1byte( *outbuffer );
		if ( check() )
		{
			outbuffer++;
		}else {
			stop();
			return(FALSE);
		}
	}
	stop();
	return(TRUE);
}


/********************************************************************
*  函数名称:read1byte
*  功    能:从I2C总线读取一个字节
*  参    数:无
*  返回值  :读取的数据
********************************************************************/
unsigned char read1byte( void )
{
	unsigned char	ReadData = 0x00, i;
	unsigned char	flag;
	for ( i = 0; i < 8; i++ )
	{
		SDA_H;
		NOP();
		SCL_H;
		SDA_IN;
		NOP();
		flag		= SDA_VAL;
		ReadData	<<= 1;
		if ( flag )
			ReadData |= 0x01;
		SDA_OUT;
		SCL_L;
		NOP();
	}

	return(ReadData);
}


/********************************************************************
*  函数名称:readNbyte
*  功    能:从I2C总线读取N个字节的数据
*  参    数:inbuffer -- 读取后数据存放的首地址
*         n        -- 数据的个数
*  返回值  :无
********************************************************************/
void readNbyte( unsigned char * inbuffer, unsigned char n )
{
	unsigned char i;
	for ( i = 0; i < n; i++ )
	{
		inbuffer[i] = read1byte();
		if ( i < (n - 1) )
			mack();
		else mnack();
	}

	stop();
}


/********************************************************************
*  函数名称:PCF_Write_DAC()
*  功    能:向PCF8591 DAC中写入待转换数据
*  参    数:DACdata   -- 写入的数据
*  返回值  :1--写入成功,0--失败
********************************************************************/
unsigned char PCF_Write_DAC( unsigned char DACdata )
{
	start();
	write1byte( PCF8591Address );           /* 器件地址 */
	if ( check() )
		write1byte( PCF8591Control );   /* 写入控制字 */
	else
		return(0);
	if ( check() )
		write1byte( DACdata );          /* 待转换DAC数据 */
	else
		return(0);
	if ( check() )
		stop();
	else return(0);
	delay_ms( 10 );                         /* 等待DAC完成内部写入 */
	return(1);
}

想DAC可以更简单的方式:
首先初始化硬件IIC:

    TRISC	= 0b00011000;
	SSPCON	= 0b00101000;
	SMP	= 0;
	SSPADD	= 4;

想要DAC就发送电压:

            SEN = 1;
            iic_send_char( 0x90 );//iic写入iic器件地址
			iic_send_char( 0x40 );//写入DAC转换信号
			iic_send_char( zhengxian[ccc] );//写入电压
            PEN	= 1;

其中:

void iic_send_char( char R )
{
	SSPBUF = R;
	while ( R_nW == 1 )
		;
}

在这里插入图片描述

发布了82 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/x1131230123/article/details/103093048