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

📄 i2c.c

📁 这个是汽车制动台控制程序的C语言版本. 用于实际产品中.单片机用的是PIC16F877A.
💻 C
字号:
#include <pic.h>
#include "total.h"	

/******************************************************************************************
* 函数名称: void Check_Idle(void)
* 功能: 检测总线是否处于空闲状态
* 入口参数: 无
* 出口参数: 无
* 全局变量: 无
* 调用模块: 无
* 设计者: 饶阳胜
* 日期: 05/3/1
******************************************************************************************/
void CheckIdle(void)
{
	while(STAT_RW != 0);	//总线正在向外发送数据
	while((SSPCON2 & 0x1F)!= 0);
}

/*****************************************************************************************
* 函数名称: 	void WrtAckTest(void)
* 功能:		检测器件的应答信号
* 入口参数: 	无
* 出口参数: 	无
* 全局变量: 	无
* 调用模块: 	无
* 设计者: 	饶阳胜
* 日期:		05-3-1
*****************************************************************************************/
void WrtAckTest(void)
{
	SSPIF = 0;
	while(SSPIF == 0);	//等待总线应答信号
}

/******************************************************************************************
* 函数名称: 	void I2C_Write_Byte(unsigned char Devive_Address,unsigned char address,unsigned char data)
* 功能: 		向EEPROM中写入一个字节的数据
* 入口参数: 	address,(要写入EEPROM的地址) data(要写入的数据) Device_Address 器件地址
* 出口参数: 	无
* 全局变量:
* 调用模块: 
* 设计者: 	饶阳胜
* 日期: 		05-3-1
******************************************************************************************/
void I2C_Write_Byte(unsigned char Device_Address,unsigned char Address,unsigned char Data)
{
	CheckIdle();				//查询总线状态,是否空闲
	SEN = 1;					//向总线发出起始信号
	while(SSPIF == 0);			//等待总线的应答信号
	SSPBUF = Device_Address;	//向总线发出器件地址
	WrtAckTest();				//查询应答信号
	while(STAT_BF == 1);
	SSPBUF = Address;			//向总线发出要写入的数据存放地址
	WrtAckTest();				//查询应答信号
	while(STAT_BF == 1);
	SSPBUF = Data;				//向总线写入数据
	WrtAckTest();				//查询应答信号
	SSPIF = 0;
	PEN = 1;					//向总线发出停止信号
	while(SSPIF == 0);
	SSPIF = 0;					//清除总线中断标志	
	Delay(16,250);				//延时,让写操作完成
}

/*******************************************************************************************
* 函数名称: 	unsigned char I2C_Read_Byte(unsigned char Device_Address,unsigned char Address)
* 功能: 		从EEPROM中读出一个字节的数据
* 入口参数: 	Device_Address(器件地址),Address(数据在EEPROM中的存放地址)
* 出口参数: 	Data(	读出的数据)
* 全局变量:
* 调用模块: 
* 设计者: 	饶阳胜
* 日期: 		05-3-2
********************************************************************************************/
unsigned char I2C_Read_Byte(unsigned char Device_Address,unsigned char Address)
{
	unsigned char Recieve;

	CheckIdle();
	SSPIF = 0;
	SEN = 1;
	while(SSPIF == 0);
	SSPBUF = Device_Address;		//向总线发送器件地址
	WrtAckTest();					//等待总线的应答信号
	SSPBUF = Address;				//向总线发出数据在EEPROM中的存储地址
	WrtAckTest();					//等待总线的应答信号
	Delay(16,250);	
	CheckIdle();					//等待总线处于空闲状态
	SSPIF = 0;						//清除总线的中断标志
	RSEN = 1;						//发出重启动信号
	while(SSPIF == 0);				//等待总线中断信号,重启动完成
	SSPBUF = (Device_Address + 1);	//发出器件地址(+1)表示读操作
	WrtAckTest();					//等总线的应答信号
	SSPIF = 0;						//清总线中断标志
	RCEN = 1;						//使能接收
	SSPIF = 0;
	while(SSPIF == 0);
	Recieve = SSPBUF;				//存放接收到的数据
	SSPIF = 0;						//清除总线的中断标志
	ACKDT = 1;						//向总线发出应答信号
	ACKEN = 1;
	while(SSPIF == 0);
	PEN = 1;
	while(SSPIF == 0);
	SSPIF = 0;
	return(Recieve);
}
	
/******************************************************************************************
* 函数名称: 	unsigned char MyWrite(unsigned char *Data,unsigned char Number,
*														unsigned char Address)
* 功能: 		向EEPROM中写入标定数据
* 入口参数: 	*Data(指向要写入EEPROM的数据的指针) Number(要写入的数据个数)
*		   	Address(数据在EEPROM中的存放地址)
* 出口参数: 	unsigned char(0: 写入不成功, 1: 写入成功)
* 全局变量: 
* 调用模块: 	I2C_Write_Byte(向EEPROM中写入一个字节的数据)
* 设计者: 	饶阳胜
* 日期: 		05/3/4
* 说明: 		数据在EEPROM中的存储格式为:以字节的形式
*      		而数据在RAM中的存储形式为unsigned short(半字形式),所以要进行转换
******************************************************************************************/
unsigned char My_Write(bank1 short *data,unsigned char number,unsigned char address)
{
	static bit change;			//用于将RAM中以半字形式存储的数据拆成在便于在EEPROM中存储的字节形式
	unsigned char writedata;	//要写入EEPROM中的数据变量

	change = 0;

	for(;number > 0; number--){		//向EEPROM中写入数据循环
		do{	
			if(change == 0){
				writedata = (unsigned char)(*data & 0xFF);	//得到低字节数据	
				change = 1;
			}else{
				writedata = (unsigned char)(*data >> 8);	//得到高字节数据
				change = 0;		
			}	
			I2C_Write_Byte(0xA0,address,writedata);		//向EEPROM写数据
			++address;									//数据在EEPROM中的存放地址加1
		}while(change == 1);
		++data;		//指向下一个数据
	}	
	return(1);
}

/****************************************************************************************
* 函数名称: 	unsigned char MyRead(unsigned short *Data,unsigned char Number,
*										unsigned char Address)
* 功能: 		将EEPROM中的数据读出到RAM中
* 入口参数: 	unsigned short *Data(指向读出数据存放到RAM中的地址指针)
*		   	unsigned char Number 要读出的数据个数
*		   	unsigned char Address 数据在EEPROM中的存放地址
* 出口参数: 	unsigned char(0: 读出不成功,1:读出成功)
* 全局变量:
* 调用模块: 	unsigned char I2C_Read_Byte(unsigned char Device_Address,unsigned char Address)
*           从EEPROM中读出一个字节数据的函数
* 设计者: 	饶阳胜
* 日期: 		05/3/5
* 说明: 		每次从EEPROM中读出的数据是一个字节,而读出的数据在EEPROM中的存储形式是半字形式,所以要进行转换
****************************************************************************************/
unsigned char My_Read(bank1 short *data,unsigned char number,unsigned char address)
{
	static bit change;		//用于将读出的数据合成一个半字形式
	unsigned char readdata;	//从EEPROM中的读出的数据变量

	change = 0;

	for(;number > 0; number--){		//从EEPROM中读出数据的循环
		do{
			readdata = I2C_Read_Byte(0xA0,address);	//从EEPROM中读取数据
			++address;								//EEPROM地址加1
			if(change == 0){
				*data = readdata;					//存储低字节
				change = 1;
			}else{
				*data = (readdata << 8) | (*data & 0xff);	//存储高字节
				change = 0;
			}
		}while(change == 1);
		++data;						//指向一个字节
	}
	return(1);
}

⌨️ 快捷键说明

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