模拟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 )
;
}
上一篇:PIC16F887 单片机 PROTEUS 仿真 C程序 测温系统 DS18B20 TC74
下一篇:pic 18f45k80单片机eeprom模块代码
设计资源 培训 开发板 精华推荐
- arduino uno
- 2ED300E17-SFO,评估板为 Eice DRIVER 2ED300C17-S 和 2ED300C17-ST IGBT 驱动器提供基本支持
- EVAL-AD7858CB,用于 AD7858 的评估板,12 位,200KSPS,用于个人数字助理的 8CH ADC
- EP4CE6F17C8原理图+用户手册
- axp173电源模块
- 用于工业应用的 LT3973EMSE-5 5V 降压转换器的典型应用
- 电路显示 LTC4354 和 LTC4355 电池 B 安装不正确
- LTC2946CDE 宽范围 -4V 至 -500V 负电源、电荷和能量监视器(10kHz I2C 接口)的典型应用
- 具有 BLF881 的 174MHz 至 230MHz DVB-T 功率放大器应用电路
- 将 LT3045HMSE 超低噪声电流源用于 RF 偏置应用的典型应用