找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5601|回復(fù): 3
收起左側(cè)

[轉(zhuǎn)帖]8051.通用的I2C總線程序

[復(fù)制鏈接]
ID:43499 發(fā)表于 2012-8-2 21:41 | 顯示全部樓層 |閱讀模式

對(duì)于死太慘"1T"的單片機(jī)需要加快延時(shí)。建議直接在后面加一個(gè)0,I2C就沒(méi)有問(wèn)題了。

這個(gè)程序并不是我原創(chuàng)。是ourDEV中某個(gè)24C串口操作里面剝離的。感覺(jué)蠻好用。不過(guò)稍微改變語(yǔ)法,讓它在SDCC中通過(guò)。

這個(gè)函數(shù)支持TEA5767/24C系列串行儲(chǔ)存器的操作。理論是只要是I2C的器件都沒(méi)有問(wèn)題。

該程序在89C52/SDCC v3.1.0中通過(guò),上代碼。

 

#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總線的時(shí)鐘信號(hào)
#define I2C_SDA  P1_2             // I2C總線的數(shù)據(jù)信號(hào)
//---------------------------------------------------------------                                   



#define DELAY_nT    1   // 延時(shí)1個(gè)機(jī)器周期(2+2*DELAY_nT),
                                // (延時(shí)時(shí)間大于5us,因此機(jī)器個(gè)數(shù)
                                // 根據(jù)晶振頻率而定)
void Delay_I2C()
{
    unsigned char t=DELAY_nT;
    while(--t);
}
//***********************************************************************
// 函數(shù)名稱(chēng):I2C_Start()
// 功    能:?jiǎn)?dòng)I2C總線
// 入口參數(shù):無(wú)
// 出口參數(shù):無(wú)
//***********************************************************************
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
}

//***********************************************************************
// 函數(shù)名稱(chēng):I2C_Stop()
// 功    能:終止I2C總線
// 入口參數(shù):無(wú)
// 出口參數(shù):無(wú)
//***********************************************************************
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
}

//***********************************************************************
// 函數(shù)名稱(chēng):I2C_Send_Bit_0()
// 功    能:發(fā)送比特0
// 入口參數(shù):無(wú)
// 出口參數(shù):無(wú)
//***********************************************************************
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
}

//***********************************************************************
// 函數(shù)名稱(chēng):I2C_Send_Bit_1()
// 功    能:發(fā)送比特1
// 入口參數(shù):無(wú)
// 出口參數(shù):無(wú)
//***********************************************************************
void I2C_Send_Bit_1(void)
{
    
    I2C_SDA_1;
    I2C_SCL_1;
    Delay_I2C(); // 大于5us
    I2C_SCL_0;
//    Delay_I2C(); // 大于5us
}

//***********************************************************************
// 函數(shù)名稱(chēng):I2C_Check_Ack()
// 功    能:發(fā)送完一個(gè)字節(jié)后檢驗(yàn)設(shè)備的應(yīng)答信號(hào)
// 入口參數(shù):無(wú)
// 出口參數(shù):返回值為T(mén)rue,成功
//           返回值為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;
}

//***********************************************************************
// 函數(shù)名稱(chēng):I2C_Write8Bit()
// 功    能:向I2C總線寫(xiě)入8bit數(shù)據(jù)
// 入口參數(shù):I2C_data     將要寫(xiě)入I2C總線的8bit數(shù)據(jù) 
// 出口參數(shù):無(wú)
//***********************************************************************
void I2C_Write8Bit(unsigned char I2C_data)
{
    unsigned char i;
    
    for( i=0;i<8;i++ )//秒懂。好猥瑣的寫(xiě)法,致遠(yuǎn)吐糟ing
    {
        if( (I2C_data<<i)&0x80 )
            I2C_Send_Bit_1();
          else
            I2C_Send_Bit_0();
    }
}

//***********************************************************************
// 函數(shù)名稱(chēng):I2C_Read8Bit()
// 功    能:從I2C總線接收8bit數(shù)據(jù)
// 入口參數(shù):無(wú)
// 出口參數(shù):返回值為從I2C總線上接收到的8bit數(shù)據(jù)
//***********************************************************************
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



萬(wàn)致遠(yuǎn)原創(chuàng),轉(zhuǎn)載注明出處:http://www.rwzy.co.cc
回復(fù)

使用道具 舉報(bào)

ID:70330 發(fā)表于 2015-1-30 14:04 | 顯示全部樓層
請(qǐng)問(wèn):建議直接在后面加一個(gè)0,是什么意思?
回復(fù)

使用道具 舉報(bào)

ID:70330 發(fā)表于 2015-1-30 14:04 | 顯示全部樓層
這是12T的機(jī)器的嗎?
回復(fù)

使用道具 舉報(bào)

ID:84375 發(fā)表于 2015-6-30 17:00 | 顯示全部樓層
很清晰。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表