Chinaunix首页 | 论坛 | 博客
  • 博客访问: 965689
  • 博文数量: 175
  • 博客积分: 2788
  • 博客等级: 少校
  • 技术积分: 2060
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-25 12:25
个人简介

知之者不如好之,好之者不如乐之

文章分类

全部博文(175)

文章存档

2016年(1)

2015年(20)

2014年(8)

2013年(68)

2012年(16)

2011年(35)

2010年(1)

2008年(26)

分类: 嵌入式

2013-11-14 20:43:33

原文:

下面是用普通C51实现的I2C基本电平模拟函数和通用函数。

/*  电平模拟函数和基本读写函数
    void IIC_Start(void);
    void IIC_Stop(void);
    void SEND_0(void);
    void SEND_1(void);
    bit Check_Acknowledge(void);
    void Write_Byte(uchar b)reentrant;
    bit Write_N_Bytes(uchar *buffer,uchar n)reentrant;
    bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer);
    uchar Read_Byte(void)reentrant;
*/

    #include
    #include
    #include
    #include"aiic_51.h"

    sbit SCL=P1^6;
    sbit SDA=P1^7;

    void DELAY(uint t)
    {
        while(t!=0)
            t--;
    }

    void IIC_Start(void)
    {
        //启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变
        SDA=1;
        SCL=1;
        DELAY(DELAY_TIME);
        SDA=0;
        DELAY(DELAY_TIME);
        SCL=0;
        DELAY(DELAY_TIME);
    }

    void IIC_Stop(void)
    {
        //终止I2C总线,当SCL为高电平时使SDA产生一个正跳变
        SDA=0;
        SCL=1;
        DELAY(DELAY_TIME);
        SDA=1;
        DELAY(DELAY_TIME);
        SCL=0;
        DELAY(DELAY_TIME);
    }

    void SEND_0(void)
    {
        //发送0,在SCL为高电平时使SDA信号为低
        SDA=0;
        SCL=1;
        DELAY(DELAY_TIME);
        SCL=0;
        DELAY(DELAY_TIME);
    }

    void SEND_1(void)
    {
        //发送1,在SCL为高电平时使SDA信号为高
        SDA=1;
        SCL=1;
        DELAY(DELAY_TIME);
        SCL=0;
        DELAY(DELAY_TIME);
    }

    bit Check_Acknowledge(void)
    {
        //发送完一个字节后检验设备的应答信号
        SDA=1;
        SCL=1;
        DELAY(DELAY_TIME/2);
        F0=SDA;
        DELAY(DELAY_TIME/2);
        SCL=0;
        DELAY(DELAY_TIME);
        if(F0==1)
            return FALSE;
        return TRUE;
    }

    void Write_Byte(uchar b)reentrant
    {
        //向IIC总线写一个字节
        uchar i;
        for(i=0;i<8;i++)
            if((b<
                SEND_1();
            else
                SEND_0();
    }

    bit Write_N_Bytes(uchar *buffer,uchar n)reentrant
    {
        //向I2C总线写n个字节
        uchar i;
        IIC_Start();

        for(i=0;i
        {
            Write_Byte(buffer);
            if(!Check_Acknowledge())
                {
                    IIC_Stop();
                    return(i==n);
                }
        }

        IIC_Stop();
        return TRUE;
    }

    uchar Read_Byte(void)reentrant
    {
        //从I2C总线读一个字节
        uchar b=0,i;
        for(i=0;i<8;i++)
        {
            SDA=1;    //释放总线
            SCL=1;    //接受数据
            DELAY(10);
            F0=SDA;
            DELAY(10);
            SCL=0;
            if(F0==1)
                {
                    b=b<<1;
                    b=b|0x01;
                }
            else
                b=b<<1;
        }
        return b;
    }

    bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer)
    {
        //从I2C总线读n个字节
        uchar i;
        IIC_Start();
        Write_Byte(SlaveAdr);        //向总线发送接收器地址
        if(!Check_Acknowledge())     //等待接收器应答信号
            return FALSE;
        for(i=0;i
            {
                buffer=Read_Byte();
                if(i!=n)
                    SEND_0();    //发送应答
                else
                    SEND_1();    //发送非应答
            }
        IIC_Stop();
        return TRUE;
    }
  
  

使用上述代码,你可以在51上用P1口模拟I2C
阅读(562) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~