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

📄 iic.h

📁 万年历数字钟是一种用万年历时钟芯片实现年、月、日、时、分、秒计时
💻 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 + -