原创 菜农用LabWindows写的I2C程序,望白沙烟酒同志笑纳

2007-6-18 13:49 4820 5 5 分类: MCU/ 嵌入式
HotPower 发表于 2007-6-18 13:29 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

楼主: 菜农用LabWindows写的I2C程序,望白沙烟酒同志笑纳


HRESULT CVIFUNC I2C_Start(void)
{
    HRESULT __result = S_FALSE;
    int i;
    unsigned char ack;
    for (i = 0; i < I2C_waitStartDelay;i ++) {
        ack = I2C_GetSDA();//释放数据总线读数据总线
        I2C_SetSCL();//首先拉高SCL, 保证SDA在SCL=1时跳变,拉高时钟(必须在SDA=1时)
        I2C_ClrSDA();//首先拉低SDA.必须按次序!!!
        I2C_ClrSCL();//然后拉低SCL,构成I2C从机内部中断并唤醒
        if (ack) {//测试成功!!!总线已释放
            __result = S_OK;//
            break;
        }
    }
    if (__result == S_OK)
    {
        Hot_I2CErrorState = I2C_START;//已发送起始条件
    }
    else
    {
        Hot_I2CErrorState = -1;//未发送起始条件
        I2C_Stop ();
    }
    return __result;
}

HRESULT CVIFUNC I2C_ReStart(unsigned char addrss)
{
    HRESULT __result;
//入口:SDA=SCL=0
    I2C_SetSDA();//首先拉高SDA, 这样才能保证在SCL=1时SDA下跳构成再次复位条件即复位
    I2C_SetSCL();//然后拉高SCL, 保证SDA在SCL=1时跳变,拉高时钟(必须在SDA=1时)
    I2C_ClrSDA();//首先拉低SDA.必须按次序!!!
    I2C_ClrSCL();//然后拉低SCL,构成I2C从机内部中断并唤醒
    I2C_ReadWriteByte (addrss | 1);//强行发送I2C读地址,SDA=SCL=0
    __result =I2C_GetAck();//取从机ACK信号
    if (__result == S_OK)
    {
        Hot_I2CErrorState = I2C_MT_SLA_ACK;//已发送SLA+W,且已接收ACK
    }
    else
    {
        Hot_I2CErrorState = I2C_MT_SLA_NACK;//已发送SLA+W,且未接收ACK
        I2C_Stop ();
    }
    return __result;
}

void CVIFUNC I2C_Stop (void)
{
    I2C_ClrSCL();
    I2C_ClrSDA();
      I2C_SetSCL();//在SCL为高时准备Stop信号,拉高时钟(必须在SDA=1时,故本例形成Stop())
      I2C_SetSDA();//STOP信号结束
}

void CVIFUNC I2C_WriteAck(unsigned char ack)
{
    if (ack) {
        I2C_ClrSDA();//给从机ACK信号
    }
    else
    {
        I2C_SetSDA();//给从机nACK信号
    }
    I2C_SetSCL();//拉高时钟信号,拉高时钟(必须在SDA=1时)
    I2C_ClrSCL();//拉低时钟信号,防止START信号产生
    I2C_ClrSDA();//给从机ACK信号
}


HRESULT CVIFUNC I2C_GetAck(void)
{
    HRESULT __result = S_FALSE;
    int i;
    for (i = 0; i < I2C_waitAckDelay; i ++)
    {
        if (I2C_GetSDA() == 0) //释放数据总线读数据总线
        {
            __result = S_OK;
            break;
        }
    }
    I2C_SetSCL();//拉高时钟(必须在SDA=1时)???
    I2C_ClrSCL();//拉低时钟
    I2C_ClrSDA();//保证SDA=SCL=0///pwy(拉低SDA便于发送停止喜欢)
    return __result;//SDA=1,SCL=0
}

/*-----------------------------------------------------------
    I2C一体化读写程序
-------------------------------------------------------------*/
unsigned char CVIFUNC I2C_ReadWriteByte(unsigned char value)
{
    int i;
    for (i = 0; i < 8; i ++)//每个字节8位
    {
        if (value >= 0x80) //D7位=1
        {
             value <<= 1;//I2C协议先出D7位
            I2C_SetSDA();
            if (I2C_GetSDA())//GetSDA()内带释放数据总线SetSDA()
            {
                value ++;//读回1位I2C数据1
            }
        }
        else//D7=0
        {
             value <<= 1;//I2C协议先出D7位
            I2C_ClrSDA();//写入1位I2C数据0
        }
        I2C_SetSCL();//拉高I2C时钟
        I2C_ClrSCL();//拉低I2C时钟
    }
    I2C_ClrSDA();//保证出口SDA=SCL=0
    return value;//返回数据
}

unsigned char CVIFUNC I2C_ReadByte (unsigned char ack)
{
    unsigned char value;
    value = I2C_ReadWriteByte (0xff);//取数据
    I2C_WriteAck(ack);//向从机发送ACK/nACK信号  
    return value;//返回接收数据
}

unsigned short CVIFUNC I2C_ReadWord (unsigned char ack)
{
    unsigned short value;
    unsigned char ch, cl;
    cl = I2C_ReadByte (I2C_ACK);
    if (ack) ch = I2C_ReadByte (I2C_ACK);
    else ch = I2C_ReadByte (I2C_nACK);
    value = (ch << 8) | cl;
    return value;
}

void CVIFUNC I2C_ReadBlock (unsigned char *str, int size)
{
    int i;
    for (i = 0; i < size; i ++)
    {
        if (i == size - 1)
        {
            str = I2C_ReadByte(I2C_nACK);
        }
        else
        {
            str = I2C_ReadByte(I2C_ACK);
        }
    }
}

HRESULT CVIFUNC I2C_WriteByte (unsigned char value)
{
    HRESULT __result = S_FALSE;
    I2C_ReadWriteByte (value);//写数据,SDA=SCL=0
    __result = I2C_GetAck();//取从机ACK信号
    if (__result == S_OK)
    {
        Hot_I2CErrorState = I2C_MT_DATA_ACK;//已发送I2DAT 中的数据字节,且已接收ACK
    }
    else
    {
        Hot_I2CErrorState = I2C_MT_DATA_NACK;//已发送I2DAT 中的数据字节,且未接收ACK
        I2C_Stop();
    }
    return __result;
}

HRESULT CVIFUNC I2C_WriteWord (unsigned short value)
{
    HRESULT __result = S_FALSE;
    unsigned char ch, cl;
    ch = value  >> 8;
    cl = value & 0xff;
    __result = I2C_WriteByte (cl);
    if (__result == S_OK)
    {
        __result = I2C_WriteByte (ch);
    }
    return __result;
}

HRESULT CVIFUNC I2C_WriteBlock (unsigned char *str, int size)
{
    HRESULT __result = S_FALSE;
    int i;
    for (i = 0; i < size; i ++)
    {
        __result = I2C_WriteByte(str);
        if (__result != S_OK) break;
    }
    return __result;
}

附该程序效果图:
1.读出EEPROM数据文件
点击看大图

2.写入EEPROM数据文件
点击看大图

3.单/双字节EEPROM读出
点击看大图

4.单/双字节EEPROM写入
点击看大图

5.整片EEPROM读出
点击看大图

6.整片EEPROM写入
点击看大图





签名:


●█〓██▄▄▄▄▄▄ ●●●●●●→ ''''╭WWWW╮
▄▅██████▅▄▃▂ 灌水入坛传播非典 ( ●_●)
██████████████ '''',,,;,;,;'''/▇\''
◥⊙▲⊙▲⊙▲⊙▲⊙▲⊙▲◤ 东戳西顶一片天/MMMM\
点击遨游水上蔬菜批发市场
2006224191826181.gif

打造21IC晕汁晕味晕菜的BLOG
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
5
关闭 站长推荐上一条 /3 下一条