⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 ds1307的程序
💻 C
字号:
//===================================================================
//      文件名称:	i2c.c
//===================================================================
#define 	I2C_SCL  	PIN_C0
#define		I2C_SDA  	PIN_C1

//------------------- 私有宏定义 开始-------------------------
#define I2CWAIT8 delay_us(8)
#define I2CWAIT4 delay_us(5)

//#define EMAX_POLL	10		// Maximum nunber of polls
#define EMAX_POLL	0x96	// Maximum nunber of polls
//------------------- 私有宏定义 结束-------------------------

//===================================================================
//= 函数原型: void i2c_start()
//= 参    数: 无
//= 返 回 值: 无
//= 功    能: 提供I2C总线工作时序中的起始位
//= 函数性质: 私有函数
//= 			SDA ----_____
//= 			I2C_SCL ------____
//===================================================================
void i2c_start()
{
	output_high(I2C_SDA);
	I2CWAIT8;
	output_high(I2C_SCL);
	I2CWAIT8;
	output_low(I2C_SDA);
	I2CWAIT4;
	output_low(I2C_SCL);
	I2CWAIT4;
}
//===================================================================
//= 函数原型: void i2c_stop()
//= 参    数: 无
//= 返 回 值: 发送停止位后DSA线的状态 是'低'则返回
//= 功    能: 提供I2C总线工作时序中的停止位
//= 函数性质: 私有函数
//= 			SDA ______----
//= 			I2C_SCL ___-------
//===================================================================
void i2c_stop()
{

//	int8 i;
	output_low(I2C_SDA);
	I2CWAIT4;
	output_high(I2C_SCL);
	I2CWAIT8;
	output_high(I2C_SDA);
	I2CWAIT4;
//	i = SDA;			// Put port pin into HiZ
}

//===================================================================
//= 函数原型: bit i2c_clock()
//= 参    数: 无
//= 返 回 值: 在时钟电平为高期间SDA信号线上的状态
//= 功    能: 提供I2C总线的时钟信号,并返回在时钟电平为高期间SDA
//=           信号线上的状态.本函数可用于数据发送或数据接收
//= 函数性质: 私有函数
//===================================================================
int1 i2c_clock()
{
	int1 sample;

	output_high(I2C_SCL);

	I2CWAIT8;

	sample = input(I2C_SDA);

	output_low(I2C_SCL);

	return(sample);
}

//===================================================================
//= 函数原型: bit i2c_send_8bit(int8 I_data)
//= 参    数: I_data 写入 EEPROM 8_bit
//= 返 回 值: 如果收到应答信号返回TRUE 否则返回FALSE
//= 功    能: 向I2C总线发送8位数据,并请求一个应答信号ACK
//= 函数性质: 私有函数
//===================================================================
int1 i2c_send_8bit(int8 I_data)
{
	int8 i;
	int1 test_bit;

	set_tris_c(0x00);				// I2C_SDA output

	I2CWAIT4;

	for (i=0;i<8;i++)
	{
		output_bit(I2C_SDA, bit_test(I_data,7));

		I_data <<= 1;

		I2CWAIT4;

		i2c_clock();

		I2CWAIT4;
	}

//	output_high(I2C_SDA);			// 请求应答信号ACK

	set_tris_c(0x02);				// I2C_SDA input

	test_bit=i2c_clock();

	set_tris_c(0x00);				// I2C_SDA input

	return(~test_bit);								// 如果收到应答信号返回1 否则返回0

}
//===================================================================
//= 函数原型: int8 i2c_receive_8bit(bit ack)
//= 参    数: 应答信号 0/1(仅在最后一个字节时ACK为1)
//= 返 回 值: I2C总线上收到的一个字节
//= 功    能: 从I2C总线上接收8位数据信号,并将收到的8位数据作为一个字节返回
//= 函数性质: 私有函数
//===================================================================
int8 i2c_receive_8bit(int1 ack)
{
	int8 I_data = 0;
	int8 i;
/*
	SDA = 1;

	for (i=0;i<8;i++)
	{
		I2CWAIT8;
		I_data <<= 1;						// '高位在前读数据'经典'
		if (i2c_clock())
			I_data++;
	}
	I2CWAIT4;

	SDA = ack;								// 发送应答信号
	i2c_clock();
	return(I_data);
*/
	set_tris_c(0x02);				// I2C_SDA input
	delay_cycles(1);

	for(i=0;i<8;i++)
	{
		I2CWAIT8;
		I_data <<= 1;				// '高位在前读数据'经典'
		if (i2c_clock())
			I_data++;
	}

	I2CWAIT4;

	set_tris_c(0x00);				// I2C_SDA output
	delay_cycles(1);
	output_bit(I2C_SDA,ack);		// 发送应答信号
	i2c_clock();

	return(I_data);
}
//===================================================================
//= 函数原型: bit i2c_pkt_write(u_int addr,int8 *s,int8 size)
//= 参    数: ipw_ch:器件地址 ipw_addr:单元地址 *s写数据指针 size:写入数据的个数
//= 返 回 值: 写数据成功返回'TRUE',否则返回'FALSE'
//= 功    能: 从启动总线到发送地址,数据,结束总线的全过程
//= 函数性质: 公有函数
//===================================================================
int1 i2c_pkt_write(int8 ipw_ch,int8 ipw_addr,int8 *s,int8 size)
{
	int8 i;
//    int8 *buf_pt = s;
//    int8 *buf_pt;
    
//	buf_pt = s;

	if (size == 0) return FALSE;

	for (i=EMAX_POLL;;)
	{
		i2c_start();
		if (i2c_send_8bit(ipw_ch)==TRUE)	// 送器件地址,同时检查是否连接
			break;							// 	receive ACK => write finished
		i2c_stop();
		if (--i == 0)						// Try it 1msec
			return FALSE;					// 等待1msec 还没有写完则返回出错
	}

	i2c_send_8bit(ipw_addr);
	do {
		i2c_send_8bit(*s);
		s++;
	} while (--size);
	i2c_stop();
}

//===================================================================
//= 函数原型: bit i2c_pkt_read(int8 ipw_ch,int8 ipw_addr,int8 *s,int8 size)
//= 参    数: addr:EEPROM地址 *s:读数据指针 size:读数据的个数
//= 返 回 值: 读数据成功返回'TRUE',否则返回'FALSE'
//= 功    能: 从启动总线到发送地址,读数据,结束总线的全过程
//= 函数性质: 公有函数
//===================================================================
int1 i2c_pkt_read(int8 ipw_ch,int8 ipw_addr,int8 *s,int8 size)
{
//    int8 *buf_pt = s;
//   int8 *buf_pt;
	int1 ack;
	
//	buf_pt= s;


	if (size == 0) return FALSE;

	i2c_start();
	if (i2c_send_8bit(ipw_ch)==FALSE) {	// 送器件地址,同时检查是否连接
		i2c_stop();
		return FALSE;
	}

	i2c_send_8bit(ipw_addr);
	i2c_stop();

	i2c_start();
	i2c_send_8bit(ipw_ch+1);				// 送读命令
	for (;;)
	{
		ack = --size;				   // last byte or last in page
		*s = i2c_receive_8bit(!ack);  // NACK on last byte
		s++;
		if (!ack) break;				   // 正常情况下ACK应该是1
	}
	i2c_stop();
	return TRUE;
}

//======================= 函数原型定义完毕 ==========================

⌨️ 快捷键说明

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