/* 程序说明: IIC总线驱动程序 软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台 8051,12MHz 日 期: 2011-8-9 */ #include "iic.h" #include "intrins.h" #define DELAY_TIME 5 #define Photo_Res_Channel 0x41 #define Adj_Res_Channel 0x43 //总线引脚定义 sbit SDA = P2^1; /* 数据线 */ sbit SCL = P2^0; /* 时钟线 */ void IIC_Delay(unsigned char i) { do { _nop_(); } while(i--); } //总线启动条件 void IIC_Start(void) { SDA = 1; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 0; IIC_Delay(DELAY_TIME); SCL = 0; } //总线停止条件 void IIC_Stop(void) { SDA = 0; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 1; IIC_Delay(DELAY_TIME); } //发送应答 void IIC_SendAck(bit ackbit) { SCL = 0; SDA = ackbit; // 0:应答,1:非应答 IIC_Delay(DELAY_TIME); SCL = 1; IIC_Delay(DELAY_TIME); SCL = 0; SDA = 1; IIC_Delay(DELAY_TIME); } //等待应答 bit IIC_WaitAck(void) { bit ackbit; SCL = 1; IIC_Delay(DELAY_TIME); ackbit = SDA; SCL = 0; IIC_Delay(DELAY_TIME); return ackbit; } //通过I2C总线发送数据 void IIC_SendByte(unsigned char byt) { unsigned char i; for(i=0; i<8; i++) { SCL = 0; IIC_Delay(DELAY_TIME); if(byt & 0x80) SDA = 1; else SDA = 0; IIC_Delay(DELAY_TIME); SCL = 1; byt <<= 1; IIC_Delay(DELAY_TIME); } SCL = 0; } //从I2C总线上接收数据 unsigned char IIC_RecByte(void) { unsigned char i, da; for(i=0; i<8; i++) { SCL = 1; IIC_Delay(DELAY_TIME); da <<= 1; if(SDA) da |= 1; SCL = 0; IIC_Delay(DELAY_TIME); } return da; } unsigned char Ad_Read(unsigned char addr) { unsigned char temp; IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(addr); IIC_WaitAck(); IIC_Start(); IIC_SendByte(0x91); IIC_WaitAck(); temp = IIC_RecByte(); IIC_SendAck(1); IIC_Stop(); return temp; } void Da_Write(unsigned char dat) { IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(0x41); IIC_WaitAck(); IIC_SendByte(dat); IIC_WaitAck(); IIC_Stop(); } //函数名:写EEPROM函数 //入口参数:需要写入的字符串,写入的地址(务必为8的倍数),写入数量 //返回值:无 //函数功能:向EERPOM的某个地址写入字符串中特定数量的字符。 void EEPROM_Write(unsigned char* EEPROM_String, unsigned char addr, unsigned char num) { IIC_Start();//发送开启信号 IIC_SendByte(0xA0);//选择EEPROM芯片,确定写的模式 IIC_WaitAck();//等待EEPROM反馈 IIC_SendByte(addr);//写入要存储的数据地址 IIC_WaitAck();//等待EEPROM反馈 while(num--) { IIC_SendByte(*EEPROM_String++);//将要写入的信息写入 IIC_WaitAck();//等待EEPROM反馈 IIC_Delay(200); } IIC_Stop();//停止发送 } //函数名:读EEPROM函数 //入口参数:读到的数据需要存储的字符串,读取的地址(务必为8的倍数),读取的数量 //返回值:无 //函数功能:读取EERPOM的某个地址中的数据,并存放在字符串数组中。 void EEPROM_Read(unsigned char* EEPROM_String, unsigned char addr, unsigned char num) { IIC_Start();//发送开启信号 IIC_SendByte(0xA0);//选择EEPROM芯片,确定写的模式 IIC_WaitAck();//等待EEPROM反馈 IIC_SendByte(addr);//写入要读取的数据地址 IIC_WaitAck();//等待EEPROM反馈 IIC_Start();//发送开启信号 IIC_SendByte(0xA1);//选择EEPROM芯片,确定读的模式 IIC_WaitAck();//等待EEPROM反馈 while(num--) { *EEPROM_String++ = IIC_RecByte();//将要写入的信息写入 if(num) IIC_SendAck(0);//发送应答 else IIC_SendAck(1);//不应答 } IIC_Stop();//停止发送 }