zoukankan      html  css  js  c++  java
  • 十天学会单片机Day5 IIC总线AT2402芯片(EEPROM)应用

    1.采用串行总线技术可以使系统的硬件设计大大简化、系统的体积减小、可靠性提高。同时,系统的更改和扩充极为容易。
     常用的串行扩展总线有: IIC (Inter IC BUS)总线、单总线(1-WIRE BUS)、SPI(Serial Peripheral Interface)总线及Microwire/PLUS等。
     
    2.IIC
      IIC总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。
      IIC总线通过上拉电阻接正电源。当总线空闲时,两根线均为高电平。连到总线上的任一器件输出的低电平,都将使总线的信号变低。
      即各器件的SDA及SCL都是线“与”关系。
       
     
    3.数据位的有效性规定
      I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
    4.起始信号 终止信号

      SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。  

     1 void Start()
     2 {
     3     SDA = 1;
     4     delay();
     5     SCL = 1;
     6     delay();  
     7     SDA = 0;
     8     delay();    
     9 }
    10 
    11 void Stop()
    12 {
    13     SDA = 0;
    14     delay();
    15     SCL = 1;
    16     delay();
    17     SDA = 1;
    18     delay();
    19 }
    View Code

    5.数据传送格式

    ①字节传送与应答

      每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。

      由于某种原因从机不对主机寻址信号应答时(如从机正在进行实时性的处理工作而无法接收总线上的数据),它必须将数据线置于高电平,而由主机产生一个终止信号以结束总线的数据传送。

      如果从机对主机进行了应答,但在数据传送一段时间后无法继续接收更多的数据时,从机可以通过对无法接收的第一个数据字节的“非应答”通知主机,主机则应发出终止信号以结束数据的继续传送。

      如果从机对主机进行了应答,但在数据传送一段时间后无法继续接收更多的数据时,从机可以通过对无法接收的第一个数据字节的“非应答”通知主机,主机则应发出终止信号以结束数据的继续传送。

    ②数据帧格式

          在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/T),用“0”表示主机发送数据(T),“1”表示主机接收数据(R)。每次数据传送总是由主机产生的终止信号结束。但是,若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。

    a.主机向从机发送数据,数据传送方向在整个传送过程中不变:

      有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。

       A表示应答, A非表示非应答(高电平)。S表示起始信号,P表示终止信号。

    b.主机在第一个字节后,立即从从机读数据

    c.在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读/写方向位正好反相。

    6.总线的寻址

      IIC总线协议有明确的规定:采用7位的寻址字节(寻址字节是起始信号后的第一个字节)

    寻址字节的位定义

      

      D7-D1位组成从机的地址。D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据。

      主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据R/T位将自己确定为发送器或接收器。
      从机的地址由固定部分和可编程部分组成。在一个系统中可能希望接入多个相同的从机,从机地址中可编程部分决定了可接入总线该类器件的最大数目。如一个从机的7位寻址位有4位是固定位,3位是可编程位,这时仅能寻址8个同样的器件,即可以有8个同样的器件接入到该IIC总线系统中。
     
     
    7.AT2402(EEPROM)
    EEPROM(Electrically Erasable Programmable Read-Only Memory)
    WP(write protect):写保护,高电平有效。
    地址:高四位1010     A2A1A0如图 000
     
     1 void write_byte(unsigned char dat)
     2 {
     3     unsigned char i = 0;
     4     for(i = 0; i < 8; i++) {
     5         dat = dat<<1;
     6         SCL = 0;
     7         delay();
     8         SDA = CY;    //类似于8086的PSW的CF位 即左移data溢出位进入CY
     9         delay();
    10         SCL = 1;
    11         delay();    
    12     }
    13     SCL = 0;
    14     delay();
    15     SDA = 1;
    16     delay();
    17 }
    View Code

     1 unsigned char read_byte()
     2 {
     3     unsigned char i = 0, dat;
     4     SCL = 0;
     5     delay();
     6     SDA = 1;
     7     for(i = 0; i < 8; i++) {
     8         SCL = 1;
     9         delay();
    10         dat = (dat<<1) | SDA;
    11         SCL = 0;
    12         delay();
    13     }
    14     return dat;
    15 }
    View Code

    8.应答信号

     1 void Respons()
     2 {
     3     unsigned char i = 0;
     4     SCL = 1;
     5     delay();
     6     while( (SDA == 1) && (i < 250) )
     7         i++;
     8     SCL = 0;
     9     delay();
    10 }
    View Code

    9.向2402读写数据

      1 //IIC 2402(EEPROM)读写数据 并把读数据赋值给P1
      2 #include <reg52.h>
      3 #define uchar unsigned char
      4 sbit SDA = P2^0;
      5 sbit SCL = P2^1;
      6 
      7 void delay()
      8 {;;}
      9 
     10 void delayms(unsigned int n)   //误差 -0.651041666667us
     11 {
     12     unsigned char a,b;
     13     unsigned int i;
     14     for(i = 0; i < n; i++) {
     15         for(b=4;b>0;b--)
     16             for(a=113;a>0;a--);
     17     }
     18 }
     19 
     20 void Init()
     21 {
     22     SCL = 1;
     23     delay(); 
     24     SDA = 1;
     25     delay();     
     26 }
     27 
     28 void Start()
     29 {
     30     SDA = 1;
     31     delay();
     32     SCL = 1;
     33     delay();  
     34     SDA = 0;
     35     delay();    
     36 }
     37 
     38 void Stop()
     39 {
     40     SDA = 0;
     41     delay();
     42     SCL = 1;
     43     delay();
     44     SDA = 1;
     45     delay();
     46 }
     47 
     48 void Respons()
     49 {
     50     unsigned char i = 0;
     51     SCL = 1;
     52     delay();
     53     while( (SDA == 1) && (i < 250) )
     54         i++;
     55     SCL = 0;
     56     delay();
     57 }
     58 
     59 void write_byte(unsigned char dat)
     60 {
     61     unsigned char i = 0;
     62     for(i = 0; i < 8; i++) {
     63         dat = dat<<1;
     64         SCL = 0;
     65         delay();
     66         SDA = CY;    //类似于8086的PSW的CF位 即左移data溢出位进入CY
     67         delay();
     68         SCL = 1;
     69         delay();    
     70     }
     71     SCL = 0;
     72     delay();
     73     SDA = 1;
     74     delay();
     75 }
     76 
     77 unsigned char read_byte()
     78 {
     79     unsigned char i = 0, dat;
     80     SCL = 0;
     81     delay();
     82     SDA = 1;
     83     for(i = 0; i < 8; i++) {
     84         SCL = 1;
     85         delay();
     86         dat = (dat<<1) | SDA;
     87         SCL = 0;
     88         delay();
     89     }
     90     return dat;
     91 }
     92 
     93 void write_add(unsigned char address, unsigned char dat)
     94 {
     95     Start();
     96     write_byte(0xa0);      //前四位地址1010 后三位根据硬件000 最后一位R/W(上划线) 写信号
     97     Respons();
     98     write_byte(address);
     99     Respons();
    100     write_byte(dat);
    101     Respons();
    102     Stop();
    103 }
    104 
    105 unsigned char read_add(unsigned char address)
    106 {
    107     unsigned char dat;
    108     Start();
    109     write_byte(0xa0);      //前四位地址1010 后三位根据硬件000 最后一位R/W(上划线) 写信号
    110     Respons();
    111     write_byte(address);
    112     Respons();
    113     Start();
    114     write_byte(0xa1);      //前四位地址1010 后三位根据硬件000 最后一位R/W(上划线) 读信号
    115     Respons();
    116     dat = read_byte();
    117     Stop();
    118     return dat;
    119 }
    120 
    121 int main()
    122 {
    123     Init();
    124     delayms(100);
    125     write_add(0x03, 0x55);
    126     delayms(100);
    127     P1 = read_add(0x03);
    128     while(1);
    129     return 0;
    130 }

     
  • 相关阅读:
    使用WCF建立起Silverlight客户端与服务端的桥梁
    Silverlight WCF RIA服务(三十三)身份验证、角色、个性化 4
    陶哲轩实分析习题 12.1.3
    Asymptote 学习记录(6) 练习用模块roundedpath画出一个图
    使用Asymptote的循环功能画出绿叶阵
    使用Asymptote的循环功能画出绿叶阵
    度量空间的一个例子:离散度量空间
    练习: 使用Asymptote 画出字母R的轮廓曲线
    练习: 使用Asymptote 画出字母R的轮廓曲线
    陶哲轩实分析命题 11.10.7
  • 原文地址:https://www.cnblogs.com/kuotian/p/5457006.html
Copyright © 2011-2022 走看看