打印
[51单片机]

IIC协议笔记,以及51的源程序

[复制链接]
1103|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
p_neletric|  楼主 | 2015-5-16 00:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
I^2C总线通过上拉电阻接电源
电阻一般选择10k
每个器件有唯一地址
由总线仲裁
时钟信号为高电平期间,数据线上的数据必须稳定,只有在时钟为低电平期间,数据线上的电平才可以改变

起始信号

SCL为高电平期间,SDA由高电平变为低电平的变化为起始信号

终止信号

SCL为高电平期间,SDA由低电平变为高电平的变化为终止信号

起始终止信号有主机发出

接收器件接受完一个字节信号后,有可能需要处理一些内部事务,这时接收器件可以将SCL拉为低电平,使主机处于等待状态。直到接收器件完成内部事务可以进行下一字节的接收再将SCL拉为高电平。

字节传送必须为8位
先传送最高位MSB
每一个字节传送后必须跟随一位应答位
应答信号为从机发出的

一帧数据有9位
若主机等待一段时间没有等到从机应答主机默认接收到了



数据帧的格式
传送数据既有地址信号又有数据信号
寻址找到元器件再传送数据
起始信号后必须转送从机的地址(7位)

第8位为数据传送方向(R/T)
用0表示(下一字节)主机发送数据(T)
用1表示主机接受数据(R)

每次数据总是由主机产生终止信号结束
可以不发送终止信号再次发送起始信号进行寻址

IIC总线规定采用7位的寻址字节
即起始信号后的第一个字节

从机地址由固定部分和可编程部分组成
一般可编程的有三位

如何编程?
(有3个编程引脚,接的电平即为该芯片的地址)

EEPROM
eletrcic elmation program
(电可擦除存储芯片)

AT24C02:256字节

连续读写操作
每8个字节连续,在该连续区域内每连续读写一次地址自动加1,读写超出8个字节时地址计数器将翻转,再次从0开始。将覆盖原来数据。

连续区域
0~8        [0 1 2 3 4 5 6 7]
8~16    [8 9 10 11 12 13 14 15]
16~24    [16 17 18 19 20 21 22 23]
.
.
.
(起始地址为8的倍数,终止地址为起始地址加8)该区域内含左不含右。)


#include<reg52.h>
#include<intrins.h>

#define NOP() _nop_
#define uchar unsigned char
#define uint unsigned int

sbit SDA=P2^0;
sbit SCL=P2^1;

void Delay_IIC();
void IIC_Start();//起始信号
void IIC_End();//结束
void Respons();//应答信号
void Init();
void Send_Byte(uchar dat1);
uchar Read_Byte();
void Write_date(uchar *buffer,first_address,uchar lenth); //24wc16 lenth max 16
void Read_date(uchar *buffer,uchar first_address,uchar lenth); //24wc16 lenth max 16

uchar code LED_CODE[9]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00};

void main()
{
    uchar date[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    Write_date(LED_CODE,8,8); //24wc16 lenth max 16
    Read_date(date,8,8);
while(1)
{
     uchar i=0;
    for(i=0;i<8;i++)
    {
        uchar a=200;
        //P0=LED_CODE[i];
        P0=date[i];
        while(a--)
        {
        Delay_IIC();
        Delay_IIC();
        Delay_IIC();
        Delay_IIC();
        Delay_IIC();
        Delay_IIC();
        Delay_IIC();
        Delay_IIC();
        }
        P0=0x00;

    }

}
}

void Delay_IIC()
{
    uchar a=0,b=0;
    for(a=10;a>0;a--)
    {
        for(b=10;b>0;b--);
    }
}
void IIC_Start()//起始信号
{
    SDA=1;
    Delay_IIC();
    SCL=1;
    Delay_IIC();
    SDA=0;
    Delay_IIC();

}
void IIC_End()//结束
{
    SDA=0;
    Delay_IIC();
    SCL=1;
    Delay_IIC();
    SDA=1;
    Delay_IIC();

}
void Respons()//应答信号
{
    uchar i=0;
    SCL=1;//while response sda=0
    Delay_IIC();
    SDA=1;
    Delay_IIC();
    while((SDA==1)&&(i<200))
        i++;
    SCL=0;
    Delay_IIC();

}
void Init()
{
    SDA=1;
    Delay_IIC();
    SCL=1;
    Delay_IIC();
}
void Send_Byte(uchar dat1)
{
    uchar i=0,j=0,dat;
    dat=dat1;
    SCL=0;
    Delay_IIC();
    for(i=0;i<8;i++)
    {
        SDA=dat>>7;
        dat<<=1;

//        dat<<=1;
//        SDA=CY;
        Delay_IIC();
        SCL=1;
        Delay_IIC();
        SCL=0;
        Delay_IIC();
    }
    SDA=1;
    Delay_IIC();
}
uchar Read_Byte()
{

    uchar i,k,dat;
    SCL=0;
    Delay_IIC();
    SDA=1;
    Delay_IIC();
    for(i=0;i<8;i++)
    {
        SCL=1;
        Delay_IIC();
        k=SDA;
        dat=(dat<<1)|k;
        SCL=0;
        Delay_IIC();
    }
    return dat;
}
void Write_date(uchar *buffer,first_address,uchar lenth) //24wc16 lenth max 16
{
    uchar i=0;
    Init();
    IIC_Start();
    Send_Byte(0xa0);//器件地址 最后一位为0表示写数据
    Respons();
    Send_Byte(first_address);//存储器 内存地址 example 36
    Respons();
    Send_Byte(*buffer);
    Respons();
    for(i=1;i<lenth;i++)
    {
    Send_Byte(*(buffer+i));// 写入数据0xfe
    Respons();//应答后进行擦写操作,在此期间不答应任何主机请求
    }
    IIC_End();
}
void Read_date(uchar *buffer,uchar first_address,uchar lenth) //24wc16 lenth max 16
{
    uchar i=0;
    SDA=1;
    Delay_IIC();
    SCL=1;
    Delay_IIC();
   
    IIC_Start();
    Send_Byte(0xa0);//器件地址  最后一位为0表示写  进行读之前的伪写操作。
    Respons();
    Send_Byte(first_address);//存储器 内存地址0x03
    Respons();
    IIC_Start();
    Send_Byte(0xa1);
    Respons();
    *buffer=Read_Byte(); //读取第一个字节完毕
     SCL=0;
    Delay_IIC();
    SDA=1;   
    Delay_IIC();
    SDA=0;//主机向从机应答 表明要读多个字节   
    Delay_IIC();
    SCL=1;
    for(i=1;i<lenth;i++)
    {
        Delay_IIC();
        *(buffer+i)=Read_Byte();
        SCL=0;
        Delay_IIC();
        SDA=1;
        Delay_IIC();
        SDA=0;//主机向从机应答 表明要读多个字节
        Delay_IIC();
        SCL=1;   
    }
    IIC_End();
}



相关帖子

沙发
dirtwillfly| | 2015-5-16 11:52 | 只看该作者
感谢分享

使用特权

评论回复
板凳
p_neletric|  楼主 | 2015-5-22 22:36 | 只看该作者

新手写的。。让您见笑了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝