找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5658|回复: 3
收起左侧

[转帖]8051.通用的I2C总线程序

[复制链接]
ID:43499 发表于 2012-8-2 21:41 | 显示全部楼层 |阅读模式

对于死太惨"1T"的单片机需要加快延时。建议直接在后面加一个0,I2C就没有问题了。

这个程序并不是我原创。是ourDEV中某个24C串口操作里面剥离的。感觉蛮好用。不过稍微改变语法,让它在SDCC中通过。

这个函数支持TEA5767/24C系列串行储存器的操作。理论是只要是I2C的器件都没有问题。

该程序在89C52/SDCC v3.1.0中通过,上代码。

 

#ifndef __I2C_H__
#define __I2C_H__

//---------------------------------------------------------------
#define I2C_SCL_0     I2C_SCL = 0
#define I2C_SCL_1     I2C_SCL = 1
#define I2C_SDA_0     I2C_SDA = 0
#define I2C_SDA_1     I2C_SDA = 1
//--------------------管脚定义-----------------------------------
#define I2C_SCL  P1_1             // I2C总线的时钟信号
#define I2C_SDA  P1_2             // I2C总线的数据信号
//---------------------------------------------------------------                                   



#define DELAY_nT    1   // 延时1个机器周期(2+2*DELAY_nT),
                                // (延时时间大于5us,因此机器个数
                                // 根据晶振频率而定)
void Delay_I2C()
{
    unsigned char t=DELAY_nT;
    while(--t);
}
//***********************************************************************
// 函数名称:I2C_Start()
// 功    能:启动I2C总线
// 入口参数:无
// 出口参数:无
//***********************************************************************
void I2C_Start(void)
{
    
    I2C_SDA_1;
    I2C_SCL_1; 
    Delay_I2C(); // 大于5us
    I2C_SDA_0; 
    Delay_I2C(); // 大于5us
    I2C_SCL_0;
    Delay_I2C(); // 大于5us
}

//***********************************************************************
// 函数名称:I2C_Stop()
// 功    能:终止I2C总线
// 入口参数:无
// 出口参数:无
//***********************************************************************
void I2C_Stop(void)
{
    
    /*I2C_SDA_0;
    I2C_SCL_1;
    t = DELAY_nT;    while(--t);        // 大于4us
    I2C_SDA_1;
    t = DELAY_nT;    while(--t);        // 大于5us
    I2C_SCL_0;
    t = DELAY_nT;    while(--t);         // 大于5us
    I2C_SCL_1;*/
    I2C_SCL_0;
    I2C_SDA_0;
    Delay_I2C(); // 大于5us
    I2C_SCL_1;
    Delay_I2C(); // 大于5us
    I2C_SDA_1;
    Delay_I2C(); // 大于5us
}

//***********************************************************************
// 函数名称:I2C_Send_Bit_0()
// 功    能:发送比特0
// 入口参数:无
// 出口参数:无
//***********************************************************************
void I2C_Send_Bit_0(void)
{
    
    I2C_SDA_0;
    I2C_SCL_1;
    Delay_I2C(); // 大于5us        // tL = 6us 
    I2C_SCL_0;
//    t = DELAY_nT;    while(--t);         // 大于5us
}

//***********************************************************************
// 函数名称:I2C_Send_Bit_1()
// 功    能:发送比特1
// 入口参数:无
// 出口参数:无
//***********************************************************************
void I2C_Send_Bit_1(void)
{
    
    I2C_SDA_1;
    I2C_SCL_1;
    Delay_I2C(); // 大于5us
    I2C_SCL_0;
//    Delay_I2C(); // 大于5us
}

//***********************************************************************
// 函数名称:I2C_Check_Ack()
// 功    能:发送完一个字节后检验设备的应答信号
// 入口参数:无
// 出口参数:返回值为True,成功
//           返回值为False,失败
//***********************************************************************
unsigned char I2C_Check_Ack(void)
{
    
    I2C_SDA_1;
    I2C_SCL_1;
    Delay_I2C(); // 大于5us
    F0 = I2C_SDA;
    Delay_I2C(); // 大于5us
    I2C_SCL_0;
    Delay_I2C(); // 大于5us
    if( F0 == 1 )  return FALSE;
    else                   return TRUE;
}

//***********************************************************************
// 函数名称:I2C_Write8Bit()
// 功    能:向I2C总线写入8bit数据
// 入口参数:I2C_data     将要写入I2C总线的8bit数据 
// 出口参数:无
//***********************************************************************
void I2C_Write8Bit(unsigned char I2C_data)
{
    unsigned char i;
    
    for( i=0;i<8;i++ )//秒懂。好猥琐的写法,致远吐糟ing
    {
        if( (I2C_data<<i)&0x80 )
            I2C_Send_Bit_1();
          else
            I2C_Send_Bit_0();
    }
}

//***********************************************************************
// 函数名称:I2C_Read8Bit()
// 功    能:从I2C总线接收8bit数据
// 入口参数:无
// 出口参数:返回值为从I2C总线上接收到的8bit数据
//***********************************************************************
unsigned char I2C_Read8Bit(void)
{
    unsigned char t,I2C_data = 0,i;
    
    for( i = 0; i < 8; i++ )
    {    
        I2C_data = I2C_data << 1;
        I2C_SDA_1;    
        I2C_SCL_1;    
        t = DELAY_nT;    while(--t);
        F0 = I2C_SDA;
        t = DELAY_nT;    while(--t);
        I2C_SCL_0;
        if( F0 == 1 )    
            I2C_data = I2C_data | 0x01;
    }
    return I2C_data;
}

#endif



万致远原创,转载注明出处:http://www.rwzy.co.cc
回复

使用道具 举报

ID:70330 发表于 2015-1-30 14:04 | 显示全部楼层
请问:建议直接在后面加一个0,是什么意思?
回复

使用道具 举报

ID:70330 发表于 2015-1-30 14:04 | 显示全部楼层
这是12T的机器的吗?
回复

使用道具 举报

ID:84375 发表于 2015-6-30 17:00 | 显示全部楼层
很清晰。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表