STM32 IIC通信往24C02写数据、读数据

1、24C02模块的原理图:从图中可以看出,A0、A1、A2三个引脚全部接地,说明表示器件地址7位数据后三位全部是0
     

注:当上一个数据写完之后,若发送停止信号,则至少停下10ms时间后,才能再发送起始信号,这个时间就叫做写周期。

3、器件寻址:
  
         
     
4、字节写:
       
       

5、写页:
     (1)、用页写,CAT24WC01可一次写入8个字节的数据,CAT24C02/04/08/16可以一次写入16个字节的数据。
     (2)、页写操作的启动和字节写一样,不同在于传送了一字节数据后并不产生停止信号,主器件还可以被允许额外再发送7或者15个字节。
     (3)、每发送一个字节数据后CAT24WCxx产生一个应答位,并将字节地址低位加1,高位保持不变。
     (4)、若在发送停止信号之前主器件发送超过8个或16个字节,地址计数器将自动翻转,先前写入的数据被覆盖。
     (5)、接收到P+1字节数据和主器件发送的停止信号后,CAT24Cxx启动内部写周期(10ms)将数据写到数据区,所有接收的数据在一个写周期内写入CAT24Cxx.
               
6、字节读:
     读操作允许主器件对寄存器的任意字节进行读操作。主器件首先通过发送起始信号、从器件地址和它想读取的字节数据的地址执行一个写操作。在从器件应答之后, 主器件重新发送起始信号和从器件地址,此时R/W位置1,从器件响应并随机发送应答信号,然后输出所要求的一个8个字节数据,主器件不发送应答信号但产生一个停止信号。
     
7、连续读:
     在从机给主机发送完一个8位字节数据后,主器件产生一个应答信号来响应,告诉从机主器件要求更多的数据,对应每个主机产生的应答信号,从机将发送一个8位数据字节。当主器件不发送应答信号而发送停止位时结束操作。
     

8、首先定义:
     #define AT24C01     127   
     #define AT24C02     255     // AT24C02有255个字节    
     #define AT24C04     511   
     #define AT24C08     1023  
     #define AT24C016   2047  
     #define AT24C032   4095  
     #define AT24C064   8191   
     #define AT24C028   16383
     #define AT24C0256 32767 

     #define EE_TYPE AT24C02      //从器件的类型

     #define Device_Address   //0xA0

9、读写字节:
     
     (1)、读一个字节:
             
            u8 read_OneByte(u16 addr)  //addr表示主器件想读取的字节数据的地址,是16位的
            {
                 u8 data;
                 I2C_Start();               
                 if( EE_TYPE >AT24C016 )    //读数据时是双字节寻址
                 {
                       send_Byte(0xA0);
                       I2C_Wait_ACK();    
                       send_Byte(addr>>8);   //先发送数据地址高位                                           
                 }

                 else                         //读数据时是单字节寻址
                     send_Byte(0xA0+((addr/256)<<1));  //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
          
                 I2C_Wait_ACK(); 
                 send_Byte(addr%256); //数据地址低字节
                 I2C_Wait_ACK();

                //开始读数据
                 I2C_Start();
                 send_Byte(0xA1);   //最后一位为“1”,表示接下来是要读数据
                 I2C_Wait_ACK();
                 data=rev_Byte(0);  //"0"表示主机不需要给从机应答
                 I2C_Stop();

                 return data;
             }

     (2)、写一个字节
             
           void write_OneByte(u8 data, u16 addr)   //将数据data写到从器件的地址为addr的缓冲区里面
           {
               I2C_Start();
               
               if( EE_TYPE >AT24C016 )    //读数据时是双字节寻址
                 {
                       send_Byte(0xA0);
                       I2C_Wait_ACK();    
                       send_Byte(addr>>8);   //先发送数据地址高位                                           
                 }
                 else                         //读数据时是单字节寻址
                     send_Byte(0xA0+((addr/256)<<1));  //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
          
                 I2C_Wait_ACK(); 
                 send_Byte(addr%256); //数据地址低字节
                 I2C_Wait_ACK();

                 //开始写数据
                 send_Byte(data);
                 I2C_Wait_ACK();
                 I2C_Stop();

                 delay_ms(10ms);   //延时10ms,也叫写周期
           }

     (3)、读两个字节:
             
            u16 read_TwoByte(u16 addr)  //addr表示主器件想读取的字节数据的地址,是16位的
            {
                 u16 data;
                 I2C_Start();               
                 if( EE_TYPE >AT24C016 )    //读数据时是双字节寻址
                 {
                       send_Byte(0xA0);
                       I2C_Wait_ACK();    
                       send_Byte(addr>>8);   //先发送数据地址高位                                           
                 }

                 else                         //读数据时是单字节寻址
                     send_Byte(0xA0+((addr/256)<<1));  //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
          
                 I2C_Wait_ACK(); 
                 send_Byte(addr%256); //数据地址低字节
                 I2C_Wait_ACK();

                //开始读数据
                 I2C_Start();
                 send_Byte(0xA1);   //最后一位为“1”,表示接下来是要读数据
                 I2C_Wait_ACK();

                  //先读高字节
                 data=rev_Byte(1)<<8;  //"1"表示主机需要给从机应答                
                 I2C_Wait_ACK();
                  //读低字节
                 data=data|rev_Byte(1);  //"0"表示主机不需要给从机应答
                 I2C_Stop();

                 return data;
             }

     (4)、写两个字节:
                  
           void write_OneByte(u16 data, u16 addr)   //将数据data写到从器件的地址为addr的缓冲区里面
           {
               I2C_Start();
               
               if(EE_TYPE >AT24C016 )    //读数据时是双字节寻址
                 {
                       send_Byte(0xA0);
                       I2C_Wait_ACK();    
                       send_Byte(addr>>8);   //先发送数据地址高位                                           
                 }
                 else                         //读数据时是单字节寻址
                     send_Byte(0xA0+((addr/256)<<1));  //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
          
                 I2C_Wait_ACK(); 
                 send_Byte(addr%256); //数据地址低字节
                 I2C_Wait_ACK();

                 //先写低位数据
                 send_Byte(data>>8);
                 I2C_Wait_ACK();  
             
                 //再发高字节
                 send_Byte(data&0xFF);
                 I2C_Wait_ACK();
                 I2C_Stop();

                 delay_ms(10ms);   //延时10ms,也叫写周期
           }
 
     




























评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值