📄 iic.h
字号:
/*******************************************
I2C总线程序,版权2007,沈佳华所有
MCU:AT89S52
时钟:12MHZ
*******************************************/
#ifndef __IIC_H__
#define __IIC_H__
#include<intrins.h>
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void iic_start(); //1--启动iic总线
void iic_stop(); //2--停止iic总线数据传送
void send_ack(); //3--发送应答位
void nsend_ack(); //4--发送非应答位
void check_ack(); //5--应答位检查
void write_byte(uchar shu); //6--发送一个字节
void write_byte0();
void write_byte1();
uchar read_byte(); //7--读取一个字节
void delay_nop(unsigned char step); //单步延时子程序
extern void write_N_byte(uchar CS_I2C,uchar ic_addr,uchar number,uchar send_data[]); //8--发送N个字节 CS_I2C为24C02 IC地址
//***********************************************************************************
//功能:发送N个数据字节子程序
//描述:CS_I2C,ic_addr,number,send_data,用户只需调用本子程序即可
//参数:发送N个字节 CS_I2C为24C02 IC地址,ic_addr为单元地址,number为连续寻址字节数,
// 但不能超过各种IC的每页字节数. send_data[]为发送数据来源,CS_I2C选中哪个芯片及
// 读写命令
//返回:无
//***********************************************************************************/
extern void read_N_byte(uchar CS_I2C,uchar ic_addr,uchar number,uchar incept_data[]); //9--接收N个字节 CS_I2C为读寻址字节
//***********************************************************************************
//功能:接收N个字数据节子程序
//描述:CS_I2C,ic_addr,number,send_data,用户只需调用本子程序即可
//参数:发送N个字节 CS_I2C为24C02 IC地址,ic_addr为单元地址,number为连续寻址字节数,
// 但不能超过各种IC的每页字节数. send_data[]为发送数据来源,CS_I2C选中哪个芯片及
// 读写命令
//返回:无
//***********************************************************************************/
void write_bytea(uchar CS_I2C,uchar temp[],uchar n); //10-写第N个字节
//***********************************************************************************
//功能:启动I2C总线子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void iic_start()
{
SDA=1; //初始SDA高电平
delay_nop(1);
SCL=1; //初始SCL为高电平才能使SDA开始信号有效 SCL f=100-400KHZ
while(SCL==0){} //检测SCL是否为高电平,若为低电平就不能作为I2C开始等其为高方可
delay_nop(2); //根椐晶振时钟来修订延时时间 SDA=4.7us
SDA=0; //SDA电平从高变低产生一个下降沿来启动I2C总线
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=0; //SCL为低电平
}
//***********************************************************************************
//功能:关闭I2C总线,停止数据传送子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void iic_stop()
{
SDA=0; //初始SDA为低电平为呆会产生上升沿作准备
delay_nop(1); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=1; //初始SCL为高电平才能使SDA停止信号有效 SCL f=100-400KHZ
while(SCL==0){;} //确保SCL是高电平才能发出停止命令
delay_nop(2); //根椐晶振时钟来修订延时时间 SDA=4.7us
SDA=1; //在SCL为高电平的前提条件下,SDA电平从低变高产生一个上升沿作为I2C的停止信号
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=0; //将SCL置低,安全不影响下一次的数据传输
}
//***********************************************************************************
//功能:发送应答信号子程序
//描述?CL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void send_ack()
{
SDA=0; //发送完数据或接收完数据主机都会发出0应答信号ACK
SCL=1;
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=0;
SDA=1;
}
//***********************************************************************************
//功能:发送非应答信号子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void nsend_ack()
{
SDA=1;
SCL=1;
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=0;
SDA=0;
}
//***********************************************************************************
//功能:检查应答信号子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void check_ack()
{
SDA=1;
SCL=1;
F0=0;
if(SDA==0)
{
SCL=0;
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
}
else
{
F0=1;
SCL=0;
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
}
}
//***********************************************************************************
//功能:发送一个数据字节子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void write_byte(uchar shu) //发送一个数据字节
{
uchar i;
if((shu&0x80)>0)
{SDA=1;}
else
{SDA=0;}
SCL=1;
while(SCL==0){;}
delay_nop(2); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=0;
SDA=0;
shu=_crol_(shu,1);
for(i=1;i<8;i++)
{
if((shu&0x80)>0)
{write_byte1();}
else
{write_byte0();}
shu=_crol_(shu,1);
}
}
//***********************************************************************************
//功能:XX子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void write_byte0()
{
SDA=0;
SCL=1;
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=0;
}
//***********************************************************************************
//功能:XX子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void write_byte1()
{
SDA=1;
SCL=1;
delay_nop(4); //根椐晶振时钟来修订延时时间 SDA=4.7us
SCL=0;
SDA=0;
}
//***********************************************************************************
//功能:读取一个字节数据子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
uchar read_byte()
{
uchar nn=0xff,mm=0x80,uu=0x7f;
uchar j;
uint q=0;
for(j=0;j<8;j++)
{
SDA=1;
SCL=1;
if(SDA==0)
{
nn=(nn&uu);
nn=_crol_(nn,1);
SCL=0;
}
else
{
nn=(nn|mm);
nn=_crol_(nn,1);
SCL=0;
}
}
return(nn);
}
//***********************************************************************************
//功能:写第N个字节数据子程序
//描述:SCL=P3^6,SDA=P3^7;特别要留意时序和时钟频率,本子程序,用户无需调用
//参数:无
//返回:无
//***********************************************************************************/
void write_bytea(uchar CS_I2C,uchar temp[],uchar n)
{
do{
iic_start();
write_byte(CS_I2C);
check_ack();
}while(F0==1);
write_byte(temp[n]);
check_ack();
}
//***********************************************************************************
//功能:发送N个数据字节子程序
//描述:CS_I2C,ic_addr,number,send_data,用户只需调用本子程序即可
//参数:发送N个字节 CS_I2C为24C02 IC地址,ic_addr为单元地址,number为连续寻址字节数,
// 但不能超过各种IC的每页字节数. send_data[]为发送数据来源,CS_I2C选中哪个芯片及
// 读写命令
//返回:无
//***********************************************************************************/
void write_N_byte(uchar CS_I2C,uchar ic_addr,uchar number,uchar send_data[])
{
uchar idata k;
do{
iic_start();
write_byte(CS_I2C); //1010 0000/1
check_ack();
}while(F0==1);
do{
write_byte(ic_addr);
check_ack();
}while(F0==1);
for(k=0;k<number;k++)
{
write_byte(send_data[k]);
check_ack();
while(F0==1)
{
write_bytea(CS_I2C,send_data,k);
}
}
iic_stop();
}
//***********************************************************************************
//功能:接收N个字数据节子程序
//描述:CS_I2C,ic_addr,number,send_data,用户只需调用本子程序即可
//参数:发送N个字节 CS_I2C为24C02 IC地址,ic_addr为单元地址,number为连续寻址字节数,
// 但不能超过各种IC的每页字节数. send_data[]为发送数据来源,CS_I2C选中哪个芯片及
// 读写命令
//返回:无
//***********************************************************************************/
void read_N_byte(uchar CS_I2C,uchar ic_addr,uchar number,uchar incept_data[])
//uchar number,ic_addr,CS_I2C,incept_data[];
{
uchar idata data0,l;
do{
iic_start();
write_byte(CS_I2C);
check_ack();
}while(F0==1);
do{
write_byte(ic_addr);
check_ack();
}while(F0==1);
do{
iic_start();
write_byte(CS_I2C+1);
check_ack();
}while(F0==1);
for(l=0;l<number;l++)
{
data0=read_byte();
incept_data[l]=data0;
if(l<(number-1))
{
send_ack();
}
}
nsend_ack();
iic_stop();
}
/**********************************************************************************
功能:单步延时子程序
调用:delay_nop(unsigned char step);
描述:在程序中可通过调用此程序来达到极短时间的延时效果,如:delay_nop(1);
参数:unsigned char step
返回:无
备注:通过更改delay_nop(unsigned char step)中step的值来改变时间的长短
***********************************************************************************/
void delay_nop(unsigned char step)
{
unsigned char i;
for(i=0;i<step;i++);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -