`

IIC读写AT24C02代码2——串口命令控制多页读写

 
阅读更多

通过串口输入 R 、W 进行控制程序读写IIC设备。波特率9600bps,晶振115200HZ。

main.c

 

/*-----------------------------------------------
  IIC编程 1
  编写:Louis 
  邮箱:kaly.liu@163.com
  日期:2015.06.01
  修改:通过串口命令R/W,控制EEPROM的读R写W。并从串口提示。
  改进:增加对页读写功能
  晶振:11.0592MHZ
NOTE:*通过实测发现,AT24C02可以连续写入16BYTE字节,而且地址要连续的两个页。就是0~15,16~31,。。。
------------------------------------------------*/
#include <REG52.H>

#include<string.h>
#include"uart.h"
#include "iic.h"

sbit WP=P1^0;
sbit LED7=P1^7;

unsigned char idata temp[8];
unsigned char rxnum;
unsigned char flag2;
unsigned char EEPROM_WR_FLAG=0;

code const char str1[] = "The string is 来自单片机!\r\n";
code const char str2[] = "Author: louis \r\n";

//const  限定一个变量不允许被改变。在一定程度上提高程序安全性和可靠性
//code 存储区间为 程序存储区
/***************函数声明*******************/
void InitUART(void);
void SendOneByte(uint8);
void SendrStr(uint8 *ptr);


void main(void)
{
  unsigned char Control,*p1,*p2;
  unsigned char buf1[]="The first page!!The second page!The third page!!"; /* 发送缓冲区 */
  unsigned char idata buf2[49]; /* 接收缓冲区 */


  unsigned char Length;
  unsigned int addr ,i=0; /* 24Cxx片内地址 */
       WP=0;
//    P4SW|= 0x10;
	LED7=1;
    InitUART();

    while(str2[i]!='\0')
    {
	SendOneByte(str2[i++]);	
    }
    SendrStr(str1);

	ES =1;
	EA =1;


  p1=buf1;
  p2=buf2;


  addr=0; ////片内地址 AT24C02为0~255 , 32page*8byte = 256个字节/////
  Length=48; ////// 读写长度 //////
  enumer=AT2402; /// 读写AT24C02////

while(1){
if(EEPROM_WR_FLAG=='W'){
  Control=0xae; ///  1010 1110 写操作///
  RW24xx(p1,Length,addr,Control,enumer); // 写操作 //
  for(i=0;i<10000;i++);	   
  //要加入延时···才可正确的读取数据!  
  //在STOP和START之间有个 write cycle,一般有个最大值Twr.这是设备内部进行写入数据需要的时间,所以此处的延迟需要 大于这个 最大值Twr。
  // Delay(1000);//1:6.18us; 2:8.36us 3:10.55us △=2.18us
   EEPROM_WR_FLAG=0;
  }

 if(EEPROM_WR_FLAG=='R'){
  Control=0xaf; ///读操作///
  RW24xx(p2,Length,addr,Control,enumer);// 读 
   EEPROM_WR_FLAG=0;
  SendrStr(p2);
  SendrStr("\r\n");

  }

 }//while

}


/****************中断服务函数***************/
void UART_ISR(void) interrupt 4
{
    uint8 RX_Data;
    //只响应"接收"中断,"发送"中断来了就直接抹掉
    if(RI)
   {
     RI = 0;	//串口中断标志不能自己清除,需要手动清除
     RX_Data=SBUF;
	 EEPROM_WR_FLAG = RX_Data;
     SendOneByte(EEPROM_WR_FLAG);
	 SendrStr(":\r\n");
   }
   else
     TI = 0;		//串口发中断是发送完缓冲区数据之后产生
}



 

uart.h头文件

 

 
/*-----------------------------------------------

  编写:刘宗铭 
  邮箱:kaly.liu@163.com
  日期:2015.05
  修改:无

------------------------------------------------*/

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义                        

/*******************************************************************
请提前计算一下所选晶振能达到的最高速度,波特率不能超过最高速度
(1) 波特率加倍(SMOD=1):  Max_Baud = FOSC/12/16
(2) 波特率不加倍(SMOD=0):Max_Baud = FOSC/12/32
例如:22.1184MHz晶振,波特率加倍时,最大波特率=22118400/12/16=115200
*******************************************************************/
#define FOSC	11059200		//振荡频率
#define BAUD	9600			//波特率
#define SMOD	1			//是否波特率加倍
#if SMOD
	#define TC_VAL	(256-FOSC/16/12/BAUD)
#else
	#define TC_VAL	(256-FOSC/32/12/BAUD)
#endif

typedef unsigned char uint8;
typedef unsigned int uint16;





/****************串口初始化函数*************/
void InitUART(void)
{
    TMOD = 0x20;    //定时器1,模式2工作模式	   
    SCON = 0x50;    //串口工作模式1,允许REN   /* SCON: 模式 1,  8-bit UART, 使能接收         */
    TH1 = TC_VAL;
    TL1 = TH1;
    PCON = 0x80; 	//发送速率加倍
    ES = 1;
    EA = 1;
    TR1 = 1;
}
/**************串口发送字符函数*************/
void SendOneByte(uint8 c)
{
    ES = 0;			//禁止中断,让串口安心工作啊
    SBUF = c;
    while(!TI);		//等待发送完毕
    TI = 0;			//清TI中断
    ES = 1;			//打开中断
}
/**************串口发送字符串函数*************/

/**************串口发送字符串函数*************/
void SendrStr(const uint8 *ptr)
{
    
	for(;*ptr!='\0';ptr++)
	{
	   SendOneByte(*ptr);
	}
}



 

IIC.h头文件

 

/*-----------------------------------------------

  编写:<span style="font-family: Arial, Helvetica, sans-serif;">Louis </span>

  邮箱:kaly.liu@163.com
  日期:2015.05
  修改:添加多页读写功能
  器件的型号 我用的是AT24C02   32PAGE*8BYTE = 2Kbit
------------------------------------------------*/
#include <intrins.h>
#include<reg52.h>


#define  ERROR 10     //允许ERROR的最大次数  
	     
sbit     SDA=P1^2;
sbit     SCL=P1^1;


enum  eepromtype {AT2401,AT2402,AT2404,AT2408,AT2416,AT2432,AT2464,AT24128,AT24256};/*器件的型号 我用的是AT24C02*/
enum  eepromtype enumer;   //定义一个枚举变量




/* * * * * * * * 一个简单延时程序 * * * * * * * * * * * * */
void Delay(unsigned char DelayCount)
{ while(DelayCount--);		  //判断 + 执行 2个机器周期
}
/* * * * * 以下是对IIC总线的操作子程序 * * * * */
/* * * * * * 启动总线 * * * * */
void Start(void)
{ SCL=0; /* SCL处于高电平时,SDA从高电平转向低电平表示 */
  SDA=1; /* 一个"开始"状态,该状态必须在其他命令之前执行 */
  Delay(2);
  SCL=1;
  Delay(2);
  SDA=0;
  Delay(2);
  SCL=0;
  SDA=1;
  Delay(2);     
}



/* * * * * 停止IIC总线 * * * * */
void Stop(void)
{ SCL=0; /*SCL处于高电平时,SDA从低电平转向高电平 */
  SDA=0; /*表示一个"停止"状态,该状态终止所有通讯 */
  Delay(2);
  SCL=1;
  Delay(2); /* 空操作 */
  SDA=1;
  Delay(2);
  SCL=0;
  Delay(1000);
}


/* * * * * 检查应答位 * * * * */
bit RecAck(void)
{ SCL=0;
  SDA=1;
  Delay(20);
  SCL=1;
  Delay(2);
  Delay(2);
  CY=SDA;     /* 因为返回值总是放在CY中的 */
  SCL=0;
  Delay(20);
  return(CY);
}


/* * * * *对IIC总线产生应答 * * * * */
void Ack(void)
{ SDA=0; /* EEPROM通过在收到每个地址或数据之后, */
  SCL=1; /* 置SDA低电平的方式确认表示收到读SDA口状态 */
  Delay(2);
  SCL=0;
  Delay(2);
  SDA=1;
}


/* * * * * * * * * 不对IIC总线产生应答 * * * * */
void NoAck(void)
{ SDA=1;
  SCL=1;
  Delay(2);
  SCL=0;
}

/* * * * * * * * * 向IIC总线写数据 * * * * */
void Send(unsigned char sendbyte)
{ unsigned char data j=8;
  for(;j>0;j--)
  { SCL=0;
    sendbyte <<= 1; /* 使CY=sendbyte^7; */
    SDA=CY; /* CY 进位标志位 */
	Delay(2);
    SCL=1;
	Delay(20);
  }
  SCL=0;
  Delay(2);
}

/* * * * * * * * * 从IIC总线上读数据子程序 * * * * */
unsigned char Receive(void)
{ register receivebyte,i=8;
  SCL=0;
  while(i--)
  { SCL=1;
    receivebyte = (receivebyte <<1 ) | SDA;
	Delay(2);
    SCL=0;
 //  receivebyte = (receivebyte <<1 ) | SDA;	  //不能放在这里啊,放这里接受数据出错··!!
	Delay(2);
  }
  return(receivebyte);
}

/* -----  AT24C01~AT24C256 的读写程序 ------ */
bit   RW24xx(unsigned char *DataBuff,unsigned char Length,unsigned int Addr,
                     unsigned char Control,enum eepromtype enumer)
{ 

  unsigned char data j,i=ERROR;
  unsigned int k;
  bit errorflag=1;  /*   出错标志   */
  while(i--)
  { Start();  /*   启动总线   */
    Send(Control & 0xfe); /*   向IIC总线写数据,器件地址 */
    if(RecAck()) continue; /*   如写不正确结束本次循环   */
    if(enumer > AT2416)
    	{ Send((unsigned char)(Addr >> 8));//把整型数据转换为字符型数据:弃高取低,只取低8位.如果容量大于32K位,使用16位地址寻址,写入高八位地址
 	     if(RecAck())  continue;
  		  }
    Send((unsigned char)Addr); /*   向IIC总线写数据   */
    if(RecAck())  continue; /*   如写不正确结束本次循环   */
    if(!(Control & 0x01))   //判断是读器件还是写器件 如果是写 0 就进去执行
  	  { j=Length;
   	   errorflag=0;         /* 清错误特征位 */
   	   while(j--)
     		 {
			  //******************此段判断页***多页读写功能***********************// 
 				  if(Addr%16==0)
					   {
					   	Stop();
						for(k=0;k<10000;k++);
						Start();               /*启动总线*/ 
				   		Send(Control & 0xfe);             /*发送器件地址*/
 					    if(RecAck())  continue; /*   如写不正确结束本次循环   */

 				  		if(enumer > AT2416)
						{ 
							Send((unsigned char)(Addr >> 8));//把整型数据转换为字符型数据:弃高取低,只取低8位.
 				                                                //如果容量大于32K位,使用16位地址寻址,写入高八位地址
 				   			 if(RecAck())  continue; /*   如写不正确结束本次循环   */	  
						}
  						Send((unsigned char)Addr);            /*发送器件子地址*/
   						 if(RecAck())  continue; /*   如写不正确结束本次循环   */
	 				  }
				 Addr++;
  			 //********************此段判断页***多页读写功能**************************//
			
			
			   /*发送数据*/      
			   Send(*DataBuff++); /*   向IIC总线写数据   */
     		   if(!RecAck()) continue; /*   如写正确结束本次循环   */
    		   errorflag=1;
   			   break;
   			   }
     	 if(errorflag==1) continue;
//		 SendOneByte('O');
      break;
    }
    else
    { Start();  /*   启动总线   */
      Send(Control); /*   向IIC总线写数据   */
      if(RecAck()) continue;//器件没应答结束本次本层循环
      while(--Length)  /*   字节长为0结束   */
     	 { *DataBuff ++= Receive();
     		   Ack();   /*   对IIC总线产生应答   */
   		   }
      *DataBuff=Receive(); /* 读最后一个字节 */
      NoAck();  /*   不对IIC总线产生应答   */
      errorflag=0;
      break;
    }
  }
  Stop();  /*   停止IIC总线   */
  if(!(Control & 0x01))
  { 
  Delay(255);
  Delay(255);
  Delay(255);
  Delay(255); 
  }
  return(errorflag);
}



 

分享到:
评论

相关推荐

    STM32-模拟IIC读写24C02程序代码

    本篇文章将详细解读一个使用STM32微控制器通过模拟I2C接口对AT24C02 EEPROM进行读写的程序。AT24C02是一种非易失性存储器(EEPROM),它可以通过I2C总线进行数据交换。在实际应用中,由于STM32并不一定具备硬件I2C...

    IIC总线读写AT24C02B(EEPROM)源程序 有详细的注释

    清晰明确的操作思路 详细的注释 通过IIC总线读写AT24C02B(EEPROM),同时用LED反映读出数据状态

    模拟IIC读写at24c512

    在提供的压缩包文件“模拟IIC读写at24c512总结”中,可能包含了上述问题的解决方案和具体代码实现,建议详细阅读以加深理解。在实践中,不断调试和优化是解决问题的关键,这将帮助你更好地掌握模拟IIC与AT24C512的...

    IIC之AT24C256 多页读写关键程序段

    在提供的"UART09600+AT24C256多页连续读写TEST2 20130511"文件中,可能包含了示例代码,用于演示如何通过UART(通用异步收发传输器)接口配合IIC协议实现与AT24C256的通信。该代码可能包括了初始化、发送命令、读写...

    硬件IIC读写AT24C02工程模版.rar

    总之,这个"硬件IIC读写AT24C02工程模版"提供了一个完整的STM32与AT24C02交互的实例,适用于学习和快速应用IIC通信协议以及如何在STM32平台上操作EEPROM。通过理解和实践这个模版,开发者可以深入理解嵌入式系统中的...

    stm32f103硬件IIC读写24c02的代码

    在本项目中,我们关注的是如何使用STM32F103的硬件IIC(Inter-Integrated Circuit)接口与24C02存储器进行通信。24C02是一款常见的I2C总线接口的E2PROM(电可擦除可编程只读存储器),通常用于存储小量非易失性数据...

    按字节读写AT24C02

    AT24C02是一种常见的I²C接口的电可擦除可编程只读存储器(EEPROM),常用于各种嵌入式系统中存储小量数据。本文将深入讲解如何通过字节级读写操作与AT24C02进行通信,并探讨其在不同平台上的移植性。 首先,I²C...

    AT24C02与AT24C08 EEPROM存储芯片驱动代码

    AT24C02与AT24C08是两种常见的串行EEPROM芯片,广泛应用于嵌入式系统,如STM32微控制器平台。这些芯片提供了非易失性存储,即使在电源断开后也能保持数据。下面将详细介绍这两款芯片以及如何在STM32上进行驱动。 AT...

    STC12C和C51单片机IIC读写AT24C02

    【STC12C和C51单片机IIC读写AT24C02】涉及的是微控制器与外部存储器之间的通信技术。STC12C和89C5A是两种常见的51系列单片机,它们在电子系统设计中广泛用于数据处理和控制任务。而AT24C02是一款I²C(Inter-...

    基于verilog的 IIC(AT24C16)读写测试程序

    1、基于IIC协议,采用verilog编写AT24C16驱动程序。 2、实现功能:在AT24C16的地址0~99之间顺序写入数据0~99,然后在读取出来,读取的数据通过串口调试助手显示出来。 3、测试平台Quartus 17.1

    STM32 HAL 读写 AT24C02

    STM32 HAL 读写 AT24C02 是一个基于STM32F103VET6微控制器,利用HAL库实现I2C通信协议,针对AT24C02 EEPROM芯片进行数据读写操作的技术。AT24C02是一种常见的串行EEPROM,具有256字节(32字节×8位)的存储空间,常...

    IIC_24C02 AT24C02 读写数据.zip_IIC_Table_at24c02_valuableggp_串口 24c0

    标题中的"IIC_24C02 AT24C02 读写数据"涉及到的是一个基于IIC协议与AT24C02 EEPROM进行数据交互的项目。IIC(Inter-Integrated Circuit)是一种用于电子设备间通信的简单、低速的串行接口,常用于微控制器与外部设备...

    STM32 IIC软件模拟读写24C02

    总之,STM32通过软件模拟IIC协议读写24C02是一个涉及硬件配置、IIC协议理解以及通信函数编写的过程。熟练掌握这一技术,不仅能够加深对STM32和I2C协议的理解,还能为其他类似任务的开发打下坚实基础。

    AVR单片机教程--IIC接口与AT24C02教程.rar

    通过本教程《AVR单片机教程--IIC接口与AT24C02教程》的深入学习,你将能够熟练地运用AVR单片机的IIC功能,进行AT24C02的读写操作,从而在你的项目中实现高效的数据存储。此外,这也将有助于你理解其他IIC设备的工作...

    STM32f103VE通过IIC读写24C02存储器

    STM32f103VE通过IIC读写24C02存储器,完成对于存储器的数据读写和写入。使用Cortex-M3 IIC通讯方法;Cortex-M3数据从24C02存储器进行读写;使用STM32CubMX软件,正确配置STM32 IIC;操控STM32 实现对24C02存储器的...

    s3c2440 IIC 读写 AT24C08A 实验代码

    本实验代码将展示如何利用S3C2440的IIC接口与AT24C08A进行通信,实现数据的读写操作。 AT24C08A是一款8K位的电可擦除只读存储器(EEPROM),工作于I²C协议下,通常用于存储配置信息或非易失性数据。其特点是容量...

    AT24C1024读写程序

    在写入过程中,需要确保每次写入的数据不超过一页(256字节),因为AT24C1024在跨越页边界时需要额外的命令和延迟。 移植到STM32或STC51等其他单片机时,主要关注的是单片机的I²C接口库和编程模型的差异。STM32是...

    读写AT24c02的程序

    3. **IIC接口**:AT24C02使用IIC接口,需要连接SCL(时钟线)和SDA(数据线)到微控制器的相应引脚上。 4. **操作模式**:支持读取和写入操作,写入操作前需要先执行读周期以防止意外覆盖数据。 5. **电源电压**:...

    ICC_.zip_FPGA iic读取_FPGA实现lpc读写_at24c02_icc读写AT24C02

    AT24C02是一款2Kb的E2PROM,具有8位并行数据接口,适用于存储小量非易失性数据。其内部组织为256个8位字节,通常用于配置参数、设置数据等场景。IIC通信时,需要设定相应的地址来定位AT24C02,并进行读写操作。 ...

    软件模拟IIC总线读写24C02程序_软件模拟IIC总线读写24C02程序_

    以下是一些关于软件模拟IIC总线读写24C02程序的关键知识点: 1. **IIC协议详解**:IIC协议采用两根信号线,分别是SCL(Serial Clock)时钟线和SDA(Serial Data)数据线。数据传输由主设备(如MSP430F149)控制,...

Global site tag (gtag.js) - Google Analytics