基于单片机的I2C的读写操作实验

发布者:Xiaochen520最新更新时间:2012-11-03 来源: 21ic 关键字:单片机  I2C  读写操作 手机看文章 扫描二维码
随时随地手机看文章

[实验任务]
   利用24C08断电以后存储的数据不消失的特点,可以做一个断电保护装置。首先利用单片机做一个0-99秒的自动计时器。然后随机关断电源,在 通电以后计时器接着断电前的状态继续计时。

[实验原理]
    首先简单的说明以下I2C总线,I2C总线是一种串行数据总线,只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。在 I2C总线上传送的一个数据字节由八位组成。总线对每次传送的字节数没有限制,但每个字节后必须跟一位应答位。数据传送首先传送最高位(MSB),数据传送按图1所示格式进行。首先由主机发出启动信号“S”(SDA在SCL高电平期间由高电平跳变为低电平),然后由主机发送一个字节的数据。启动信号后的第一个字节数据具有特殊含义:高七位是从机的地址,第八位是传送方向位,0表示主机发送数据(写),1表示主机接收数据(读)。被寻址到的从机设备按传送方向位设置为对应工作方式。标准I2C总线的设备都有一个七位地址,所有连接在I2C总线上的设备都接收启动信号后的第一个字节,并将接收到的地址与自己的地址进行比较,如果地址相符则为主机要寻访的从机,应在第九位答时钟脉冲时向SDA线送出低电平作为应答。除了第一字节是通用呼叫地址或十位从机地址之外第二字节开始即数据字节。数据传送完毕,由主机发出停止信号“P”(SDA在SCL高电平期间由低电平跳变为高电平)。
   AT24C系列串行E2PROM具有I2C总线接口功能,功耗小,宽电源电压(根据不同型号2.5V~6.0V),工作电流约为3mA,静态电流随电源电压不同为30μA~110μA,AT24C系列串行E2PROM参数如下
型 号    容 量   器件寻址字节(8位) 一次装载字节数
AT24C01  128×8   1010A2A1A0  R/W         4
AT24C02  256×8   1010A2A1A0   R/W         8
AT24C04  512×8   1010A2A1P0   R/W         16
AT24C08  1024×8  1010A2P1P0   R/W         16
AT24C16  2048×8  1010P2P1P0   R/W         16 
  由于I2C总线可挂接多个串行接口器件,在I2C总线中每个器件应有唯一的器件地址,按I2C总线规则,器件地址为7位数据(即一个I2C总线系统中理论上可挂接128个不同地址的器件),它和1位数据方向位构成一个器件寻址字节,最低位D0为方向位(读/写)。器件寻址字节中的最高4位(D7~D4)为器件型号地址,不同的I2C总线接口器件的型号地址是厂家给定的,如AT24C系列E2PROM的型号地址皆为1010,器件地址中的低3位为引脚地址A2  A1  A0,对应器件寻址字节中的D3、D2、D1位,在硬件设计时由连接的引脚电平给定。
  对AT24C系列 E2PROM的读写操作完全遵守I2C总线的主收从发和主发从收的规则。

[C语言源程序]
#include
#include
#include
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
                         0x6d,0x7d,0x07, 0x7f,0x6f,};
unsigned char sec;        //定义计数值,每过1秒,sec加1
unsigned int tcnt;        //定时中断次数
bit  write=0;             //写24C08的标志;
sbit gewei=P2^0;          //个位选通定义
sbit shiwei=P2^1;         //十位选通定义
/////////24C08读写驱动程序////////////////////
sbit scl=P3^4;   // 24c08 SCL
sbit sda=P3^5;  // 24c08 SDA
void delay1(unsigned char x)
{  unsigned int i;
  for(i=0;i  ;}
void flash()
{  ;  ; }
void x24c08_init()  //24c08初始化子程序
 {scl=1; flash(); sda=1; flash();}
void start()        //启动I2C总线
{sda=1; flash(); scl=1; flash(); sda=0; flash(); scl=0; flash();}
void stop()         //停止I2C总线
{sda=0; flash(); scl=1; flash(); sda=1; flash();}
void writex(unsigned char j)  //写一个字节
{  unsigned char i,temp;
   temp=j;
   for (i=0;i<8;i++)
   {temp=temp<<1; scl=0; flash(); sda=CY; flash(); scl=1; flash();}
   scl=0; flash(); sda=1; flash();
}
unsigned char readx()   //读一个字节
{
   unsigned char i,j,k=0;
   scl=0;  flash();  sda=1;
   for (i=0;i<8;i++)
    { 
flash();  scl=1;  flash();
      if (sda==1) j=1;
      else j=0;
      k=(k<<1)|j;
   scl=0;}
   flash();  return(k);
}
void clock()         // I2C总线时钟
{
   unsigned char i=0;
   scl=1;  flash();
   while ((sda==1)&&(i<255))i++;
   scl=0; flash();
}
////////从24c02的地址address中读取一个字节数据/////
unsigned char x24c08_read(unsigned char address)
{
   unsigned char i;
   start(); writex(0xa0);
   clock(); writex(address);
   clock(); start();
   writex(0xa1); clock();
   i=readx(); stop();
   delay1(10);
   return(i);
}
//////向24c02的address地址中写入一字节数据info/////
void x24c08_write(unsigned char address,unsigned char info)
{
   EA=0;
   start(); writex(0xa0);
   clock(); writex(address);
   clock(); writex(info);
   clock(); stop();
   EA=1;
   delay1(50);
}
/////////////24C08读写驱动程序完/////////////////////
void Delay(unsigned int tc)     //延时程序
{
 while( tc != 0 )   
    {unsigned int i;   
     for(i=0; i<100; i++); 
     tc--;}
}
void LED()                  //LED显示函数
{
   shiwei=0; P0=table[sec/10]; Delay(8); shiwei=1;
   gewei=0;  P0=table[sec%10]; Delay(5); gewei=1;
}
void t0(void) interrupt 1 using 0  //定时中断服务函数
{
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //重装计数初值
tcnt++;        //每过250ust tcnt加一
if(tcnt==20)  //计满20次(1秒)时
   {
    tcnt=0;   //重新再计
    sec++;
    write=1;  //1秒写一次24C08
    if(sec==100) //定时100秒,在从零开始计时
      {sec=0;}
   }
}
void main(void)
{
TMOD=0x01;  //定时器工作在方式1
ET0=1;  EA=1;
x24c08_init();        //初始化24C08
sec=x24c08_read(2);//读出保存的数据赋于sec
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //使定时器0.05秒中断一次
TR0=1;           //开始计时
 while(1)
  {
  LED();
 if(write==1) //判断计时器是否计时一秒
    {
  write=0;              //清零
     x24c08_write(2,sec);  //在24c08的地址2中写入数据sec
 }
   }
}

[硬件电路图]
 


关键字:单片机  I2C  读写操作 引用地址:基于单片机的I2C的读写操作实验

上一篇:89S51单片机PT2221红外解码汇编程序
下一篇:基于单片机的I2C的读写操作实验

推荐阅读最新更新时间:2024-03-16 13:12

如何使用ARM7-LPC2148微控制器中的PWM控制LED的亮度
众所周知,微控制器从模拟传感器获取模拟输入,并使用ADC(模数转换器)来处理这些信号。但是,如果微控制器想要产生模拟信号来控制伺服电机、直流电机等模拟操作设备怎么办?微控制器不会产生像 1V、5V 这样的输出电压,而是使用一种称为 PWM 的技术来操作模拟设备。PWM的一个例子是我们笔记本电脑的冷却风扇(直流电机)需要根据温度进行速度控制,这也是通过在主板中使用脉宽调制(PWM)技术来实现的。 在本教程中,我们将使用 ARM7-LPC2148 微控制器中的 PWM 控制 LED 的亮度。 PWM(脉冲宽度调制) PWM 是一种使用数字值控制模拟设备的好方法,例如控制电机的速度、LED 的亮度等。虽然 PWM 不提供纯模拟输
[单片机]
如何使用ARM7-LPC2148<font color='red'>微控制器</font>中的PWM控制LED的亮度
90%的单片机初学者,都会遇到的10个问题
01、C语言和汇编语言在开发单片机时各有哪些优缺点? 汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言可能有所差异,所以不易移植。 C语言是一种结构化的高级语言。其优点是可读性好,移植容易,是普遍使用的一种计算机语言。缺点是占用资源较多,执行效率没有汇编高。 对于目前普遍使用的RISC架构的8bit MCU来说,其内部ROM、RAM、STACK等资源都有限,如果使用C语言编写,一条C语言指令编译后,会变成很多条机器码,很容易出现ROM空间不够、堆栈溢出等问题。而且一些单片机厂家也不一定能提供C编译器。而汇编语言,一条指令就对应一个机器
[单片机]
单片机51小实验---跑马灯
以下这个程序我在实验箱上运行过,AT89C52功能:根据P2.X口的电平,若输入为1,则有X个灯在P0P1口上循环 ;输入为开关按键 ORG 0000H JMP8: MOV P2,#0FFH ;将所在口置1,即设为输入方式 MOV A,#0 ;初始化R1 MOV R1,A JB P2.0,SHOW1 ;判断P2口,若为1则转入相应的处理程序 JB P2.1,SHOW2 JB P2.2,SHOW3 JB P2.3,SH
[单片机]
用软件延时实现00-59秒单片机
1. 实验任务 如下图所示,在AT89S51单片机的P0和P2端口分别接有两个共阴数码管,P0口驱动显示秒时间的十位,而P2口驱动显示秒时间的个位。 2. 电路原理图 图4.11.1 3.系统板上硬件连线 (1.把“单片机系统”区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:P0.0/AD0对应着a,P0.1/AD1对应着b,……,P0.7/AD7对应着h。 (2.把“单片机系统”区域中的P2.0/A8-P2.7/A15端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:P2.0/A8对应着a,P2.1/A9对应着b,
[单片机]
用软件延时实现00-59秒<font color='red'>单片机</font>计
东芝扩大了基于ARM® Cortex® -M内核的微控制器产品阵容
加强具有多种封装和存储器尺寸的高速微控制器产品组合 东京–东芝公司(东京:6502)存储与电子元器件解决方案公司于今天宣布,基于ARM Cortex-M内核的TXZ™族低功率、高速微控制器将新增第三个产品组——“M3H组(2)”。新产品组中有24个产品,东芝将在5月提供样品的运输服务,产品的量产将于9月份开始。 东芝在2016年5月推出了TXZ族的第一个产品组——“M3H组(1)”,该产品组包括适用于消费品和工业设备应用的30个产品,同年10月又开始提供配有矢量引擎的第二个产品组(“M4K组”)的13个产品样品。 新推出的“M3H组(2)”等级高于第一阶段的“M3H组(1)”。其产品的封装阵容扩大至最高144引脚,并
[电源管理]
东芝扩大了基于ARM® Cortex® -M内核的<font color='red'>微控制器</font>产品阵容
基于MSP430FW42X单片机超声波热量表的设计
1 热量表的系统原理与结构 1.1 热量表的基本原理 热量表的工作原理:在热交换系统中安装热量表,配对温度传感器分别安装在热交换入口和出口管道上。当水流经系统时,流量传感器发出流量信号,配对温度传感器分别检测出入口和出口温度信号,积算器采集流量、温度信号,根据流量传感器给出的流量和配对温度传感器给出的供回水温度,以及水流经的时间,通过积算器计算并显示该系统所释放或吸收的热量,在实际应用中水的质量都是通过测量水的体积换算得出的,因此热量值的计算可使用下面公式: 式中:Q-释放的热量 或 ;V-载热液体流过的体积 ;△θ-热交换回路中载热液体入口处和出口处的温差 ;K-热系数,它是载热液体在相应温度、温差和压力下的函数 或 。
[单片机]
基于MSP430FW42X<font color='red'>单片机</font>超声波热量表的设计
LPC900系列单片机在射频数传模块中的应用与研究
当前许多应用领域都采用无线方式进行数据传输,在无线抄表、工业数据采集、天线遥控、计算机遥测遥控,医疗卫生自动化、家庭自动化、安防、汽车仪表数据读取等各方面无线射频数传模块都有广泛的应用。 1 射频数传模块开发平台的构建 建立软硬件开发平台是模块开发的首要任务,比较了几种射频数传模块方案,最后决定采用由LPC900系列FLASH单片机和CC1000射频传输芯片为主芯片的开发方案。 1.1 主芯片简介 LPC2900 FLASH单片机是Philips公司推出的一款高性能、微功耗(完全掉电模式功耗低于1μA)、高速率(6倍于普通51单片机)、小封装的5l内核单片机,主要集成了字节方式的I2C总线、SPI总线、增强型UART接口、
[单片机]
增强型51单片机和传统51单片机对比分析
前面的内容,我们从传统的51单片机出发,从硬件的基础上,一步步衍生出了增强型51单片机所增强的地方。现在我们可以清楚地了解,增强型51单片机对比传统的51单片机,增强的地方在于存储器的扩展。而51单片机对于片内内存的寻址方式和片外内存的寻址方式有着很大的不同。因此,我们在使用C语言对增强型51单片机编程的时候,也需要按照寄存器位置的不同,采用不同的操作方式。 1寄存器位于内部的特殊功能寄存器区 我们之前介绍传统8051单片机的时候,曾经列出了传统8051单片机已经使用的21个特殊功能寄存器,因此扩展外设寄存器的一个办法就是利于剩余的特殊功能存储器空间。 由于51单片机的特殊功能寄存器寻址方式只能是直接寻址,不可间接寻址,因此在
[单片机]
增强型51<font color='red'>单片机</font>和传统51<font color='red'>单片机</font>对比分析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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