I2C官方提供的参考代码:
有一小部分进行了改写
#include "iic.h"
#include <reg52.h>
#include "intrins.h"
sbit SDA = P2^1;
sbit SCL = P2^0;
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
//I2C总线内部延时函数
void Delay5us()
{
unsigned char i;
_nop_();
i = 11;
while (--i);
}
//I2C总线启动信号
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
Delay5us();
SDA = 0;
Delay5us();
SCL = 0;
}
//应答位控制
void IIC_Ack(bit ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
Delay5us();
SCL = 1;
Delay5us();
SCL = 0;
SDA = 1;
Delay5us();
}
//I2C总线停止信号
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
Delay5us();
SDA = 1;
Delay5us();
}
//发送应答或非应答信号
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit;
Delay5us();
SCL = 1;
Delay5us();
SCL = 0;
SDA = 1;
Delay5us();
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
Delay5us();
ackbit = SDA;
SCL = 0;
Delay5us();
return ackbit;
}
//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
Delay5us();
if(byt & 0x80) SDA = 1;
else SDA = 0;
Delay5us();
SCL = 1;
byt <<= 1;
Delay5us();
}
SCL = 0;
}
//I2C总线接收一个字节数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
Delay5us();
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
Delay5us();
}
return da;
}
PCF8591
ADC:
ADC输入参数(0x01,0x03)。分别检测了光敏电阻和滑动变阻器RB2输入的模拟电压的值。、
void adc_init(unsigned char ch)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(ch);
IIC_WaitAck();
IIC_Stop();
}
unsigned char get_adc()
{
unsigned char value;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
value=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return value;
}
读出的值范围在(0~255)。
//换算代码
unsigned int adc_value;
unsigned char d;
d = get_adc();
adc_vlaue = (unsigned int)(d*100/51);
//此时输出的值是原本的100倍,方便小数点显示,只想取整数部分只要去掉(*100)
判断光敏电阻是否被遮挡:
函数get_adc();返回的值应该小于60。
DAC:
函数输入参数值在(0~255):
同样输出的值在(0~5V)。
void dac_output(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
Delay5ms();
}
AT24C02
写入的地址范围在(0x00~0xff),写入数据的大小也在(0~255)
//写
void Write_24C02(unsigned char addr, unsigned char dat)//最大255
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
Delay5ms();
}
//读
unsigned char Read_24C02(unsigned char addr)
{
unsigned char tmp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
tmp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
Delay5ms();
return tmp;
}
建议在写入完成时进行一个极短的延时,确保,数据正常写入。