• 51单片机学习笔记(郭天祥版)(9)——IIC、EEPROM


     

    IIC是两根线,单总线,只有一根数据线,发送数据和读取收据都是一根线,像我们之前学的AD、DA都是许多线,许多线的话,这样做系统可以少浪费资源,少浪费控制IO口的资源,这种并行的处理速度快。所以线越多,速度越快。

    我们用的较多的是SIP和IIC,单总线用得少,一般就BS18B20用。

     

    这两条线可以接很多I²C设备,凡是具有I²C通信功能的设备都可以接在这总线上。要和哪个设备通信,先发送一个地址码给总线,总线全会响应这个地址码,这条总线上所有I²C芯片会检测这个地址,哪一个地址和它相符,就和主机建立通信,建立起后只有这个唯一的设备和总线通信。

    I²C比较重要,不过也比较简单,实际上就是时序图。

    凡是I²C总线设备必须接上拉电阻,Rp阻值一般为10K

    先传送最高位记住。

     

    随便两条线都可以模仿I²C总线


    接下来说E²PROM(electronic erase program read only memory)电可擦除可编程只读存储器

    其实就是Flash,例如U盘插上去,数据写完后拔走,就存在里面了。

    这里第二条最高位错了,最高位不是不变,是补0.

    这里用的其实是24C02

     A0~A2就是三位地址线,WP(write protect)写保护,U盘就有这功能,为1时不能写,不知道能不能读。

    接下来看看datasheet

    低电压和标准电压都支持,这里使用的是2.7~5.5V。

    内部构造2K~16K。

    两线接口。

    施密特触发器、滤波用来抑制噪声。

    双向数据传输协议。

    电压越高传输速率越快(电压越高运行速度越快,越快功耗越高),1.8V->100kHz,5V->400kHz

    2K一页,4K+是多页,C02一页的不用管。

    最多可读写1Million次

    数据保存时间100年。

    NC是不连接的意思。

    这里有四种封装

    总线时序图

    写:

    数据有效性:

    起始信号和停止信号:

    应答信号:

    地址:

    写:

    页写(不管)

    当前地址读取(即已经知道了读取的地址):

    随机读取:

    顺序读取:


     现在写程序:

    有起始信号,停止信号,应答信号,写一个字节,读一个字节,从任意字节读,向任意字节写,我们把这些都写成带参数的函数(例如write(地址变量,数据变量)),主函数直接调用就可以了,这就可以当成是一个I²C的模板。

      1 #include<reg51.h>
      2 
      3 #define uchar unsigned char
      4 #define uint unsigned int
      5 
      6 sbit SDA=P2^0;
      7 sbit SCL=P2^1;
      8 
      9 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
     10 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
     11 
     12 void Delay1ms();
     13 void delay1(int n);
     14 void delay();
     15 void start();
     16 void stop();
     17 void responds();
     18 void init();
     19 void write_byte(uchar date);
     20 uchar read_byte();
     21 
     22 void main()
     23 {
     24     init();
     25     start();
     26     write_byte(0xa0);
     27     responds();
     28     write_byte(0);
     29     responds();
     30     write_byte(0xfe);
     31     responds();
     32     stop();
     33     
     34     delay1(1000);//这里要有延时,停止后不能直接启动
     35     
     36     start();
     37     write_byte(0xa0);
     38     responds();
     39     write_byte(0);
     40     responds();
     41     start();
     42     write_byte(0xa1);
     43     responds();
     44     P1=read_byte();
     45     stop();
     46     while(1);
     47 }
     48 void write_byte(uchar date)
     49 {
     50     //写一个字节
     51     uchar i=0,temp;
     52     temp=date;
     53     SCL=0;
     54     delay();
     55     for(i=0;i<8;i++)
     56     {
     57         temp=temp<<1;
     58         SDA=CY;
     59         delay();
     60         SCL=1;
     61         delay();
     62         SCL=0;
     63         delay();
     64     }
     65     SDA=1;
     66     delay();
     67 }
     68 uchar read_byte()
     69 {
     70     //读一个字节
     71     uchar i,j,k;
     72     SCL=0;
     73     delay();
     74     SDA=1;
     75     delay();
     76     for(i=0;i<8;i++)
     77     {
     78         SCL=1;
     79         delay();
     80         j=SDA;
     81         k=(k<<1)|j;
     82         SCL=0;
     83         delay();
     84     }
     85     return k;
     86 }
     87 void init()
     88 {
     89     SDA=1;
     90     SCL=1;
     91 }
     92 void start()
     93 {
     94     //起始信号
     95     SDA=1;
     96     delay();
     97     SCL=1;
     98     delay();
     99     SDA=0;
    100     delay();
    101     
    102 }
    103 void stop()
    104 {
    105     //停止信号
    106     SDA=0;
    107     delay();
    108     SCL=1;
    109     delay();
    110     SDA=1;
    111     delay();
    112 }
    113 void responds()
    114 {
    115     //应答信号
    116     uchar i=0;
    117     SCL=1;
    118     delay();
    119     while((SDA==1)&&(i<250))
    120     {
    121         i++;
    122     }
    123     SCL=0;
    124     delay();
    125 }
    126 void delay()
    127 {
    128     
    129 }
    130 void delay1(int n)
    131 {
    132     while(n--)
    133     {
    134         Delay1ms();
    135     }
    136 }
    137 void Delay1ms()        //@12.000MHz
    138 {
    139     unsigned char i, j;
    140 
    141     i = 2;
    142     j = 239;
    143     do
    144     {
    145         while (--j);
    146     } while (--i);
    147 }

    1.写入时间是在你传入EEPROM数据后才开始进行的,传送数据过程中,不能算写入时间,EEPROM在IIC在停止位后才开始写入动作,从这一刻开始至6MS之间算为写入时间;

    (资料来源https://www.baidu.com/link?url=GmfN6JMOsWVFgIB6hDzhhJcKdWzwvsnfOB6IC8skYfUoabglVRyz1gaWIKND0Xha&wd=&eqid=f1e2a27a000817f9000000025cb9d508)

  • 相关阅读:
    [HAOI2007][SDOI2005]反素数
    [UVa1636]Headshot
    [Codeforces 581D]Three Logos
    [NOIP2014普及组]子矩阵
    洛谷 P3299 [SDOI2013]保护出题人 解题报告
    洛谷 P3965 [TJOI2013]循环格 解题报告
    洛谷 P3989 [SHOI2013]阶乘字符串 解题报告
    [SHOI2013]发牌 解题报告
    洛谷 P3962 [TJOI2013]数字根 解题报告
    LOJ 2664. 「NOI2013」向量内积 解题报告
  • 原文地址:https://www.cnblogs.com/IceHowe/p/10720228.html
Copyright © 2020-2023  润新知