×
单片机 > 单片机程序设计 > 详情

PIC16 PCF8591

发布时间:2023-08-10 发布时间:
|

模拟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 )

;

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机小知识系列-1-485通信