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

发布者:Serendipitous33最新更新时间:2019-05-21 来源: eefocus关键字:IIC读写  AT24C02  串口  命令控制  多页读写 手机看文章 扫描二维码
随时随地手机看文章

通过串口输入 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

 

#include

#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 来自单片机!rn";

code const char str2[] = "Author: louis rn";

 

//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]!='')

    {

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("rn");

 

  }

 

 }//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(":rn");

   }

   else

     TI = 0; //串口发中断是发送完缓冲区数据之后产生

}

 


 


 


 


 


uart.h头文件


 


 

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

  编写:刘宗铭 

  邮箱:kaly.liu@163.com

  日期:2015.05

  修改:无

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

 

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

 

/*******************************************************************

请提前计算一下所选晶振能达到的最高速度,波特率不能超过最高速度

(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!='';ptr++)

{

   SendOneByte(*ptr);

}

}

 


 


 


 


 


IIC.h头文件


 


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

  编写:Louis

  邮箱:kaly.liu@163.com

  日期:2015.05

  修改:添加多页读写功能

  器件的型号 我用的是AT24C02   32PAGE*8BYTE = 2Kbit

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

#include

#include

 

 

#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;

[1] [2]
关键字:IIC读写  AT24C02  串口  命令控制  多页读写 引用地址:IIC读写AT24C02代码2——串口命令控制多页读写

上一篇:DS18B20-Onewire Bus-单总线 单片机读取温度
下一篇:IIC读写AT24C02代码1——通过串口命令控制R/W

推荐阅读最新更新时间:2024-11-17 10:28

STM32 串口通信OLED屏幕显示(IIC)心得体会
主机:单片机 从机:oled 当主机向从机写入数据时,从机需要向主机返回应答信号 每写入一个字节,则需等待应答信号:在scl和sda都为高时 当主机向从机中读取数据时,主机需要向从机给应答信号 此时,给应答信号,则表示还需要读取数据;如果给非应答信号,则表示不再读取数据 IIC模式 SDA PA1 //D1 SCL PA2 //D0 DC PA3 //地址选择 0 地址为0x78 1 地址为0x7A RES PA4 //复位引脚 CS PA5 //默认接地 电阻R3换到R1 R8短接 16(8x16)号字体 一个字符纵向占两个字节 横向占一个字节 12(6x8)号字体 一个字符纵向占1个字节 横向占6bit 主
[单片机]
STM8S使用外部时钟引起串口数据传输错误
最近有个小东西用到STM8S来驱动,之前用STM8S使用的是内部自带的16MHz RC时钟,尚未尝试过使用外部晶振作为主时钟。今天记录一下使用外部晶振时遇到的一个问题。 老规矩,在进行程序设计时,首先初始化时钟,本次使用的是STM8S103F3P6芯片,8MHz的外部晶振,为了方便内外部时钟切换,结合资料写了两个切换函数 /*********************************************** *描述:采用内部16MHz的RC时钟为主时钟 * 初始化时钟为1分频 16M,无外部晶振 *版本:V1.0 *作者: *********************************************
[单片机]
工程师STM32单片机学习手记(3):修修改改玩串口
  STM学习笔记——用定时器实现荧火虫灯   在第6篇笔记中,我用软件延时的方法实现了荧火虫,学了定时器,当然就要用一用定时器了,这里仍是用荧火虫灯为例。   用ST库所带的例子Tim中的TimBase为例来修改,这个例子的位置以及如何建立工程请参考第7篇笔记,这里就不再重复了,下面简述一下修改的过程。   (1) 由于我的板子上的灯是由PD8~PD11来控制的,因此,要将   void RCC_Configuration(void)   中的:   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //打开GPIOC的时钟   改为   RCC_APB2Peri
[单片机]
工程师STM32单片机学习手记(3):修修改改玩<font color='red'>串口</font>
linux的串口驱动分析
1、串口驱动中的数据结构 • UART驱动程序结构:struct uart_driver 驱动 • UART端口结构: struct uart_port 串口 • UART相关操作函数结构: struct uart_ops 串口操作函数集 • UART状态结构: struct uart_state 串口状态 • UART信息结构: struct uart_info 串口信息 2、串口驱动程序-初始化 3、串口驱动分析-打开设备 static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport =
[单片机]
linux的<font color='red'>串口</font>驱动分析
STM32 USB虚拟串口
串口调试在项目中被使用越来越多,串口资源的紧缺也变的尤为突出。很多本本人群,更是深有体会,不准备一个USB转串口工具就没办法进行开发。本章节来简单概述STM32低端芯片上的USB虚拟串口的移植。在官方DEMO中已经提供了现成的程序,这里对修改方法做简单说明。 首先打开官方demo我们开始进行移植,第一步复制我们可用的文件,操作如下: Projects\Virtual_COM_Port文件夹下,复制红线部分 图1 图2 我为了方便演示统放在usb/src文件夹下: 图3 现在复制USB的库文件,这些文件不需要我们修改: 图4 上图中的文件统一放在usb/lib文件夹下: 图5 好了现在所需要的文件我们以复制完
[单片机]
STM32 USB虚拟<font color='red'>串口</font>
串口通过164控制三个数码管
/*****************************************/ /*功能:按键控制数码管显示数; /*作者:oych /* 日期:2011.4.30 /****************************************/ #include reg52.h #define uchar unsigned char #define uint unsigned int sbit setup=P1^0; sbit add=P1^1; sbit sub=P1^2; uchar data_in ={0}; uchar sign=10,gw=0,sw=0,value=0; uchar code list
[单片机]
#51单片机#UART串口通信的初步认识
UART串口通信 UART,全称Universal Asynchronous Receiver/Transmitter,即通用异步收发器。 串口通信是单片机中最常用的一种技术,通常用于单片机和计算机之间以及单片机和单片机之间的通信。 UART的通信类型可分为两种,并行通信和串行通信。 并行通信:数据各个位同时传送,可实现以字节为单位来通信。缺点:通信线占用资源多,成本高。 串行通信:一次只传输一个字节的数据。 STC89C52有两个专门的UART通信引脚,P3.0(RXD)和P3.1(TXD),由它们组成的通信接口叫串行接口,简称串口。 下图体现了两个单片机相互收发信息的过程: 图中两单片机的GND互连
[单片机]
#51单片机#UART<font color='red'>串口</font>通信的初步认识
采用LabVIEW的PC机与变频器的串口通信
  1 引言   本文针对摩擦学试验研究的特点,采用广泛使用的LabVIEW编程语言,开发用于东元7200MA 变频器 运行频率的控制串口通讯程序。   由于摩擦学试验机和摩擦学测试的特殊性,摩擦学试验中的变频器调速有着不同于一般工业变频控制的特点。一方面,要求变频器调速能够在较大范围内满足摩擦学测试的要求,使得试验结果具有可比性;另一方面,摩擦磨损试验过程中,对控制有一些特殊的要求,例如需要特殊的速度、运动的非周期性以及设备的快速启动和停止等。在一些疲劳试验中,甚至要求电机进行寸动或者往复运动以检测材料的性能,有的试验现场对人体的损害比较大,需要远距离进行控制和检测电机的运转情况。所以,必须利用 计算机 程序控制变频器实
[测试测量]
采用LabVIEW的PC机与变频器的<font color='red'>串口</font>通信
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved