加载中…
个人资料
Tifnan
Tifnan
  • 博客等级:
  • 博客积分:0
  • 博客访问:2,195
  • 关注人气:87
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

AVR模拟I2C读写24C02的相关函数(已测)

(2011-02-19 20:27:13)
标签:

i2c

模拟

avr

24c02

协议

it

分类: AVR_ARM

//文件名:I2C.h

//描述:AVR模拟I2C读写24C02的相关函数

#include<iom16v.h>
#include<macros.h>
#include"I2C.h"

//外部上拉电阻,PORTC.0--SCL,PORTC.1--SDA,模拟I2C协议
//当DDRC.0和DDRC.1置为输出时,拉低SDA;置为输入时,外部上拉拉高SDA

#define SCL_0 DDRC|=BIT(0)
#define SCL_1 DDRC&=~BIT(0)
#define SDA_0 DDRC|=BIT(1)
#define SDA_1 DDRC&=~BIT(1)
#define SDA_in (PINC&0X02)  //判断SDA的电平
#define Page_size 8   //一页大小,8字节

//函数名;I2C_inti
//输入:无
//输出:无
//描述:初始化SDA和SCL

void I2C_inti(void)
{
    PORTC&=~(BIT(0)|BIT(1));
    SCL_1;
    SDA_1;
}

//函数名;Delay
//输入:无
//输出:无
//描述:延时1us

void Delay(void)  
{
    NOP();
    NOP();
    NOP();
    NOP();
}

//函数名;delay_ms
//输入:无
//输出:无
//描述:延时1ms

void delay_ms(uint ms)
   
    uint i,j;
    for(i=0;i<ms;i++)
        for(j=0;j<564;j++);
}

//函数名;I2C_Start
//输入:无
//输出:无
//描述:I2C起始条件

uchar I2C_Start(void)
{
    SDA_1;
    SCL_1;
    Delay();
    SDA_0;
    Delay();
    SCL_0;
    Delay();
    return 1;
}

//函数名;I2C_Stop
//输入:无
//输出:无
//描述:I2C结束条件

void I2C_Stop(void)
{
    SDA_0;
    SCL_1;
    Delay();
    SDA_1;
    Delay();
}

//函数名;Write_I2C
//输入:待写的一字节数据data
//输出:有无应答,有应答--1;无应答--0
//描述:发送一字节,返回有无应答

uchar Write_I2C(uchar data)
{
    uchar ack,i;
    for(i=0;i<8;i++)
    {
        if(data&0X80)
        {
            SDA_1;
        }
        else
        {
            SDA_0;
        }
        SCL_1;
        Delay();
        SCL_0;
        data<<=1;
        Delay();
    }
    Delay();
    SDA_1;
    Delay();
    SCL_1;
    Delay();
    if(SDA_in)
    {
        ack=0;
    }
    else
    {
        ack=1;
    }
    SCL_0;
    Delay();
    return ack;
}

//函数名;Read_I2C
//输入:是否应答ack,0--不应答,1--应答
//输出:接受的一字节数据
//描述:接收一字节数据

uchar Read_I2C(uchar ack)
{
    uchar i,temp;
    temp=0;
    SDA_1;
    for(i=0;i<8;i++)
    {
        Delay();
        SCL_0;
        Delay();
        SCL_1;
        Delay();
        temp<<=1;
        if(SDA_in)
        {
            temp++;
        }
    }
    SCL_0;
    Delay();
    if(!ack)
    {
        SDA_1;
    }
    else
    {
        SDA_0;
    }
    Delay();
    SCL_1;
    Delay();
    SCL_0;
    Delay();
    return temp;
}

//函数名;Write_24c02
//输入:存储地址add,待写的一字节数据data
//输出:无
//描述:向24c02指定地址写一字节的数据

void Write_24c02(uchar add,uchar data)
{
    I2C_Start();
    Write_I2C(0XAE);
    Write_I2C(add);
    Write_I2C(data);
    I2C_Stop();
    delay_ms(10);
}

//函数名;Read_24c02
//输入:存储地址add
//输出:读出的一字节数据
//描述:向24c02指定地址读一字节的数据

uchar Read_24c02(uchar add)
{
    uchar data;
    I2C_Start();
    Write_I2C(0XAE);
    Write_I2C(add);
    I2C_Start();
    Write_I2C(0XAF);
    data=Read_I2C(0);
    I2C_Stop();
    return data;
}

//函数名;Write_24c02_page
//输入:存储地址add,待写缓冲区的首地址arr
//输出:无
//描述:主机写24c02指定地址开始n个字节的数据(n<8),在一页内

void Write_24c02_page(uchar add,uchar n,uchar* arr)
{
    uchar i;
    I2C_Start();
    Write_I2C(0XAE);
    Write_I2C(add);
    for(i=0;i<n;i++)
    {
        Write_I2C(*arr++);
    }
    I2C_Stop();
    delay_ms(10);
}
   
//函数名;Write_m_24c02
//输入:存储地址add,待写缓冲区的首地址arr,待写字节数n
//输出:无
//描述:主机写24c02指定地址开始n个字节的数据

void Write_m_24c02(uchar add,uchar n,uchar* arr)
{
    uchar n_left;
    n_left=(uchar)Page_size-(uchar)(add&0X07);    //本页剩余空间
    if(n<=n_left)
    {
        Write_24c02_page(add,n,arr);
    }
    else
    {
        Write_24c02_page(add,n_left,arr);      //写完本页
        add+=n_left;
        n-=n_left;
        arr+=n_left;
        while(n>=Page_size)             // 连续写一整页
        {
            delay_ms(150);
            Write_24c02_page(add,Page_size,arr);
            add+=Page_size;
            n-=Page_size;
            arr+=Page_size;
        }
        if(n!=0)
        {
            Write_24c02_page(add,n,arr);
        }
    }
}

//函数名;Read_m_24c02
//输入:存储地址add,存储缓冲区的首地址arr,待读字节数n
//输出:无
//描述:主机读24c02指定地址开始n个字节的数据

void Read_m_24c02(uchar add,uchar n,uchar* arr)
   
    uchar i;
    I2C_Start();
    Write_I2C(0XAE);
    Write_I2C(add);
    I2C_Start();
    Write_I2C(0XAF);
    for(i=0;i<n-1;i++)
    {
        *arr++=Read_I2C(1);
    }
    *arr=Read_I2C(0);
    I2C_Stop();
  

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有