📄 i2c_div.c
字号:
#include "include.h"
//#define EEpromallbyte 32
#define GCALL 0x80 // Gen. Call flag
#define STOP 0x40 // Stop cond. flag
#define INTR 0x20 // Interrupt cond flag
#define TX_MODE 0x10 // I2C Tx mode flag
#define BBUSY 0x08 // Bus Busy flag
#define BLOST 0x04 // Bus Lost flag
#define _ACKREP 0x02 // ACK response flag
#define SLV 0x01 // Slave Mode flag
// S2CON Equates:
#define CR2 0x80 //
#define ENI 0x40 //
#define STA 0x20 //
#define STO 0x10 //
#define ADDR 0x08 //
#define AA 0x04 //
#define CR1 0x02 //
#define CR0 0x01 //
//extern uchar time_mode_buf;
//extern uchar prt_mode;
//extern uchar write_data_flg;
bit I2C_Busy;
bit I2C_NoAck;
bit I2C_Lost;
bit I2C_Fault;
//int data *Ptr;
char idata *IBuffer;
char xdata *XBuffer;
char data I2C_SendLen;
char data I2C_RcvLen;
bit First,Area;
bit I2C_master, I2C_xmit;
sbit PWROFF=P3^2;
//uchar read_eeprom(uint addr,uchar length,void *eprom_buf);
//extern void delayms(uint t1);
//extern void send_str(uint length,uchar xdata *buffer);
//extern void send_char(uchar ch);
//extern uchar Write_FAU_data(uchar type,uchar result);
//extern void delay_ms(uchar ms);
//extern uchar testbuf[64];
//--------------------------------------------------
// I2C Initialization Routine
//--------------------------------------------------
void I2C_Init(bit Mode) //0,收。1,发
{
if(low_pwr)shut_bat(0);
P3SFS |= 0xC0; // Enable P3.7 for SCL, P3.6 for SDA
IEA |= 0x02; // set EI2C I2C Int. Enable bit
I2C_master = 1;
I2C_xmit = !Mode;
I2C_Busy = 1;
I2C_NoAck = 0;
I2C_Fault = 0;
}
/*================================================*/
BOOL I2C_Send(char SLAVE,bit type,int addr,char I2C_Num)
{
I2C_Init(0);
if ((P3 & 0xc0) != 0xc0)
{
I2C_Fault = 1;
return FALSE;
}
Area = type;
IBuffer = addr;
XBuffer = addr;
I2C_SendLen=I2C_Num;
if (I2C_SendLen == 0)
return TRUE;
I2C_SendLen--;
S2DAT =SLAVE;
S2CON = 0xe1;
while(I2C_Busy);
return TRUE;
/*
I2C_Init(0);
if ((P3 & 0xc0) != 0xc0)
{
I2C_Fault = 1;
return FALSE;
}
Area = type;
//IBuffer = addr;
XBuffer = addr;
I2C_SendLen=I2C_Num;
if (I2C_SendLen == 0)
return TRUE;
I2C_SendLen--;
S2DAT =SLAVE; //写SLAVE 0XA0 地址 启动中断
S2CON = 0xe2; //开启I2C模式置中断标志
Area = type;
//if((low_pwr)&&(SLAVE==0x64))return(POWER_OFF);
while(I2C_Busy);
return TRUE;
// while(I2C_Busy);
//return TRUE;
*/
}
/*================================================*/
BOOL I2C_Rcv(char SLAVE,bit type,int addr, char I2C_Num)
{
I2C_Init(1);
if ((P3 & 0xc0) != 0xc0)
{
I2C_Fault = 1;
return FALSE;
}
Area = type;
IBuffer = addr;
XBuffer = addr;
I2C_RcvLen = I2C_Num;
if (I2C_RcvLen == 0)
return TRUE;
I2C_RcvLen--;
First = 0;
S2DAT = SLAVE | 0x01;
S2CON = 0xe1;
while(I2C_Busy);
return TRUE;
/* I2C_Init(1);
if ((P3 & 0xc0) != 0xc0)
{
I2C_Fault = 1;
return FALSE;
}
Area = type;
//IBuffer = addr;
XBuffer = addr;
I2C_RcvLen = I2C_Num;
if (I2C_RcvLen == 0)
return TRUE;
I2C_RcvLen--;
First = 0;
S2DAT = SLAVE | 0x01;
S2CON = 0xe2; //开启I2C模式置中断标志
while(I2C_Busy);
return TRUE;
*/
}
/*================================================*/
void I2C_Send_data(void)
{
S2CON &= ~STA;
if (I2C_SendLen == 0x00)
{
if ((S2CON & 0x10) != 0)
I2C_Busy=0;
if (!Area)
{
S2DAT = *IBuffer;
}
else
{
S2DAT = *XBuffer;
}
S2CON |= STO;
}
else
{
I2C_SendLen--;
if (!Area)
{
S2DAT = *IBuffer;
IBuffer++;
}
else
{
S2DAT = *XBuffer;
XBuffer++;
}
}
/* S2CON &= ~STA; //~0x20
if (I2C_SendLen == 0x00)
{
if ((S2CON & 0x10) != 0)
I2C_Busy=0;
// I2C_SendLen--;
/*if (!Area)
{
S2DAT = *IBuffer;
}
else
{
S2DAT = *XBuffer;
//}
S2CON |= STO;
}
else
{
I2C_SendLen--;
/*if (!Area)
{
S2DAT = *IBuffer;
IBuffer++;
}
else
{
S2DAT = *XBuffer;
XBuffer++;
//}
}
*/
}
/*================================================*/
I2C_Rcv_data(void)
{
if (!First)
{
First = 1;
S2CON &= ~STA;
S2DAT = 0xff;
S2CON |= AA;
}
else if (I2C_RcvLen == 0x00)
{
if (!Area)
{
*IBuffer = S2DAT;
}
else
{
*XBuffer = S2DAT;
}
// if ((S2CON & 0x10) != 0)
I2C_Busy=0;
S2CON |= STO;
}
else
{
I2C_RcvLen--;
if (I2C_RcvLen == 0x00)
{
S2CON &= ~AA;
S2CON |= STO;
}
if (!Area)
{
*IBuffer = S2DAT;
IBuffer++;
}
else
{
*XBuffer = S2DAT;
XBuffer++;
}
}
/*if (!First)
{
First = 1;
S2CON &= ~STA;
S2DAT = 0xff;
S2CON |= AA;
}
else if (I2C_RcvLen == 0x00)
{
/*if (!Area)
{
*IBuffer = S2DAT;
}
else
{
*XBuffer = S2DAT;
//}
// if ((S2CON & 0x10) != 0)
I2C_Busy=0;
S2CON |= STO;
}
else
{
I2C_RcvLen--;
if (I2C_RcvLen == 0x00)
{
S2CON &= ~AA;
S2CON |= STO;
}
/*if (!Area)
{
*IBuffer = S2DAT;
IBuffer++;
}
else
{
*XBuffer = S2DAT;
XBuffer++;
//}
}
*/
}
//===================================================================================
/*******************************************************
函数名称:initial_time
函数描述:初始化时钟
输入参数:
输出参数:
返回值:
*******************************************************/
/*uchar initial_time(void)
{
uchar I2C_SendBuffer[4];
I2C_SendBuffer[0] = 0x70; // addr
I2C_SendBuffer[1] = 0x00;//set offset
if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,2))
return (1);
I2C_SendBuffer[0] = 0xe0; // addr
I2C_SendBuffer[1] = 0x20;//set control1
I2C_SendBuffer[2] = 0x20;//set control2
if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,3))
return (1);
else
return (0);
}
*/
/*******************************************************
函数名称:set_rtc
函数描述:设置时钟
输入参数:buf[0]-buf[6]=年、月、日、时、分、秒,格式为BCD码
输出参数:
返回值:设置正确返回0,否则返回1
*******************************************************/
uchar set_rtc(uchar *rtc_buf)
{
uchar I2C_SendBuffer[8];
I2C_SendBuffer[0] = 0x00; // addr
I2C_SendBuffer[1] = rtc_buf[5];//秒
I2C_SendBuffer[2] = rtc_buf[4]; //分
I2C_SendBuffer[3] = rtc_buf[3]; //时
I2C_SendBuffer[4] = rtc_buf[6]; //星期
if(I2C_SendBuffer[4]>6)I2C_SendBuffer[4]=0;
I2C_SendBuffer[5] = rtc_buf[2]; //日
I2C_SendBuffer[6] = rtc_buf[1]; //月
I2C_SendBuffer[7] = rtc_buf[0];//年
//write_data_flg=1;
//send_str(8,I2C_SendBuffer);
if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,8))
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return (1);
}
else
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
return (0);
}
}
//=======================================================
/*******************************************************
函数名称:Writ_ctr_rtc
函数描述:写时钟的设置数据
输入参数:地址:rtc_add,数据:rtc_data
输出参数:
返回值:设置正确返回0,否则返回1
*******************************************************/
uchar Writ_ctr_rtc(uchar rtc_add,uchar rtc_data)
{
uchar I2C_SendBuffer[2];
I2C_SendBuffer[0] = rtc_add; // addr
I2C_SendBuffer[1] = rtc_data;//数据
//write_data_flg=1;
if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,2))
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
// write_data_flg=0;
return (1);
}
else
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return (0);
}
}
/*******************************************************
函数名称:read_rtc
函数描述:读时钟
输入参数:无
输出参数:buf[0]-buf[5]=年、月、日、时、分、秒,格式为BCD码
返回值: 设置正确返回0,否则返回1
******************************************************/
uchar read_rtc(uchar *rtc_buf)
{
uchar I2C_SendBuffer[2];
uchar I2C_RcvBuffer[8];
I2C_SendBuffer[0] = 0x00; // ST85 secs=00
//if(low_pwr) return(POWER_OFF);
//write_data_flg=1;
if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,1))
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return (1);
}
if(!I2C_Rcv(0x64,1,(int)&I2C_RcvBuffer,8))
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return (1);
}
else
{
rtc_buf[0]=I2C_RcvBuffer[7]; //年
rtc_buf[1]=I2C_RcvBuffer[6]; //月
rtc_buf[2]=I2C_RcvBuffer[5]; //日
rtc_buf[3]=I2C_RcvBuffer[3]; //时
//if(!time_mode_buf)rtc_buf[3]&=0xdf;//12小时制
rtc_buf[4]=I2C_RcvBuffer[2]; //分
rtc_buf[5]=I2C_RcvBuffer[1]; //秒
rtc_buf[6]=I2C_RcvBuffer[4];
if(rtc_buf[6]>6)rtc_buf[6]=0;
}
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return (0);
}
//======================================================================================
#define MAXLEN 32//24c64 为32 24C256为64
uchar write_eeprom(uint addr,uchar length,void *buf)
{
uchar I2C_SendBuffer[34];
uchar temp_len;
uint addrtemp;
uchar len,j,i;
if(length<255)
{
//write_data_flg=1;
len=(MAXLEN-(uchar)(addr%MAXLEN));
j=1;
//temp_len=(length>(MAXLEN-(uchar)(addr%MAXLEN)))?(MAXLEN-(uchar)(addr%MAXLEN)):length;//防止跨页
addrtemp=addr;
temp_len=len;
if(length>temp_len)
{
if((length-len)%MAXLEN)j+=((length-len)/MAXLEN)+1;
else j+=((length-len)/MAXLEN);
}
else temp_len=length;
i=0;
//offset=0;
while(i<j)
{
I2C_SendBuffer[0] = addrtemp/256; //高位地址
I2C_SendBuffer[1] = addrtemp%256;//低位地址
memcpy(&I2C_SendBuffer[2],((uchar*)buf),temp_len);
if(!PWROFF)shut_bat(0);
if(!I2C_Send(0xa0,1,(int)&I2C_SendBuffer,temp_len+2))
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
return (1);
}
if((j==1)||(i==j))break; //写完退出
delayms(50) ;
addrtemp+=temp_len;
((uchar*)buf)+=temp_len;
i++;
if(i!=j-1)temp_len=MAXLEN;
else temp_len=length-len-MAXLEN*(i-1);
}
//write_data_flg=0;
delayms(50) ;
IEA&= 0xfd;
P3SFS&= 0x3f; // disable P3.7 for SCL, P3.6 for SDA
S2CON&= 0xbf; //关I2C模式
return 0;
}
else return 1;
}
/**********************************
函数功能:向EPROM发读数据命令
函数参数:addr为起始地址,length为读取数据的长度,读出的数据存放在ack_data指向的单元
返回值: 0:正确 否则错误
**********************************/
uchar read_eeprom(uint addr,uchar length,void *eprom_buf)
{
uchar I2C_SendBuffer[2];
I2C_SendBuffer[0] = addr/256; /*高位地址*/
I2C_SendBuffer[1] = addr%256;/*低位地址*/
//write_data_flg=1;
if(!I2C_Send(0xa0,1,(int)&I2C_SendBuffer,2))
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return 1;
}
if(!I2C_Rcv(0xa0,1,(int)((uchar*)eprom_buf),length))
{
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return 1;
}
else
{
delayms(50) ;
IEA&= 0xfd;
P3SFS&= 0x3f;
S2CON&= 0xbf;
//write_data_flg=0;
return 0;
}
}
//===================================================================
/*uchar read_eepromZIKU(ulong addr,uchar length,uchar *eprom_buf)
{
uchar I2C_SendBuffer[2],i;
if(addr>=0x18000)
{
for(i=0;i<length;i++){eprom_buf[i]=xiao[i];}
return (1);
}
I2C_SendBuffer[0] = addr/256; /*高位地址
I2C_SendBuffer[1] = addr%256;/*低位地址
if(!I2C_Send(0xa2,1,(int)&I2C_SendBuffer,2))return (1);
if(!I2C_Rcv(0xa2,1,(int)eprom_buf,length)) return (1);
else return (0);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -