iic.c

来自「温度仪表软件」· C语言 代码 · 共 149 行

C
149
字号
#include"reg52.h"
#include"intrins.h"
#include"interface.h"
#include"my_type.h"
#include"function.h"
#include"global_var.h"

/*******************IIC开始信号**************************/
void start_iic()
{
	IIC_SDA = 1;
	IIC_SCL = 1;
	Wait5us;
	IIC_SDA = 0;//下跳开始
	Wait5us;
	IIC_SCL = 0;//钳住iic总线,准备发送和接收数据
	Wait2us;
}

/*******************IIC结束信号**************************/
void stop_iic()
{
	IIC_SDA = 0;
	IIC_SCL = 1;
	Wait5us;
	IIC_SDA = 1;//上跳结束
	Wait5us;
	IIC_SCL = 0;//只有关闭I2C总线时才使IIC_SCL为低电平
	Wait2us;
}

/*******************IIC应答信号**************************/
void ack_iic()
{
	IIC_SDA = 0;
	IIC_SCL = 1;
	Wait5us;
	IIC_SCL = 0;
	IIC_SDA = 1;
	Wait2us;
}

/******************IIC非应答信号**************************/
void nack_iic()
{
	IIC_SDA = 1;
	IIC_SCL = 1;
	Wait5us;
	IIC_SCL = 0;
	IIC_SDA = 0;
	Wait2us;
}

/*******************IIC主写1字节数据**********************/
void write_byte(uchar c)
{
	uchar i;
	for(i=0;i<8;i++)
	{
		if(c&0x80)
			IIC_SDA = 1;
		else
			IIC_SDA = 0;
		IIC_SCL = 1;
		Wait5us;
		IIC_SCL = 0;
		c<<=1;//准备下一位
	}
	IIC_SDA = 1;
	IIC_SCL = 1;//释放数据线,等待接收从机应答信号
	Wait5us;
	if(IIC_SDA == 0)
		iic_ack = 1;//有应答信号
	else
		iic_ack = 0;
	IIC_SCL = 0;
}




/*******************IIC主读1字节数据**********************/
uchar read_byte()
{
	uchar i;
	uchar r = 0;
	IIC_SDA = 1;//设置数据线为输入方式
	for(i=0;i<8;i++)
	{
		r<<=1;
		IIC_SCL = 1;//时钟高,数据有效
		Wait5us;
		if(1 == IIC_SDA)
			r++;
		IIC_SCL = 0;
	}
	return r;//主机作为接收器,单字节不应答也就相当与产生非应答信号
}
 
 
 
/*******************IIC主发n字节数据**********************/
bit write_nbyte(uchar slave,uchar addr,uchar *s,uchar n)
{
	uchar i;
	start_iic();//发开始信号
	write_byte(slave);//发从器件地址
	if(0 == iic_ack)
		return 0;//没有收到应答信号
	write_byte(addr);//要写的首地址
	if(0 == iic_ack)
		return 0;//没有收到应答信号
	for(i=0;i<n;i++)
	{
		write_byte(*s);//数据地址指向的数据
		if(0 == iic_ack)
			return 0;//没有收到应答信号
		s++;
	}
	stop_iic();
	return 1;
}

/*******************IIC主读n字节数据**********************/
bit read_nbyte(uchar slave,uchar addr,uchar *s,uchar n)
{
	uchar i;
	start_iic();//发开始信号
	write_byte(slave);//写硬件地址
	if(0 == iic_ack)
		return 0;//没有收到应答信号
	write_byte(addr);
	if(0 == iic_ack)
		return 0;//没有收到应答信号
	start_iic();
	write_byte(slave|1)
	;//读硬件地址
	if(0 == iic_ack)
		return 0;//没有收到应答信号
	for(i=0;i<n;i++)
	{
		*s = read_byte();
		ack_iic();//主机应答从机,保证报文顺利进行
		s++;
	}
	nack_iic();
	stop_iic();
	return 1;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?