模拟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 )
;
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』