C51: 2块 24C02 的读写

发布者:草木知秋最新更新时间:2016-10-14 来源: eefocus关键字:C51  24C02  读写 手机看文章 扫描二维码
随时随地手机看文章
/*/函数功能,

向U2写入12345,向U3写入67890,再分别读出,
在 LCD1602 显示  */


#include
#include 


//变量声明
#define uchar unsigned char
#define uint unsigned int

//延时 1ms
void delayms()
{
 uchar i;
 for(i=0;i<250;i++);
 for(i=0;i<80;i++);
}

void delaynms(uint s)
{
 uint tem;
 for(tem=0;tem  {
  delayms();
 }

}

 


//LCD 忙碌查询
sbit LCDbusy=P1^7;

//LCD 操作位 设置
sbit RS=P3^2;
sbit RW=P3^1;
sbit E=P3^0;
sbit BF=P1^7;

 

//------  LCD 程序 ----


//读LCD 状态
uchar BusyTest()
{
 bit result;

 //读LCD 状态
 RS=0;
 RW=1;
 E=1;

 _nop_();
 _nop_();
 _nop_();

 //指令
 result=BF;

 _nop_();
 _nop_();
 _nop_();

 E=0;

 return result;


}

//写 LCD 指令
void WriteInstruction(uchar instruction)
{
 //LCD 忙碌,等待。
 while(BusyTest()==1);

 //写指令
 RS=0;
 RW=0;
 E=0;

 _nop_();   //要求
 _nop_();
 _nop_();

 //指令
 P1=instruction;

 _nop_();
 _nop_();
 _nop_();

 E=1;

 _nop_();
 _nop_();
 _nop_();

 E=0;
}

//初始化 LCD
void InitLCD()
{
 delaynms(15); 
 WriteInstruction(0x38);//  显示模式设置
 delaynms(5);
 WriteInstruction(0x38);
 delaynms(5);
 WriteInstruction(0x38);

 delaynms(5);
 WriteInstruction(0x0d);//显示模式设置: 开显示,不显示光标,闪烁光标

 delaynms(5);
 WriteInstruction(0x06);//显示模式设置: 光标右移,文字不移动。

 delaynms(5);

}

 
//写LCD 数据
void WriteData(uchar d)
{
  //LCD 忙碌,等待。
 while(BusyTest()==1);

 //写数据
 RS=1;
 RW=0;
 E=0;

 _nop_();
 _nop_();
 _nop_();

 //指令
 P1=d;

 _nop_();
 _nop_();
 _nop_();

 E=1;

 _nop_();
 _nop_();
 _nop_();

 E=0;

}

//写地址,属于写指令
void WriteAdd(uchar ad)
{
 uchar addr=ad+0x80;
 WriteInstruction(addr);
 
}

//--- 24C02 ---

sbit SDA=P2^0;          //数据总线SDA位定义在P2^0引脚
sbit SCL=P2^1;         //时钟总线SCL位定义在P2^1引脚    

uchar wdeviceadd; //定义写入器件,寻址地址
uchar rdeviceadd;  // 定义读出器件,寻址地址


//函数功能:开始数据传送  
void start()
{
 SDA = 1;    //SDA初始化为高电平“1”
   SCL = 1;    //开始数据传送时,要求SCL为高电平“1”
 _nop_();    //等待一个机器周期
 _nop_();    //等待一个机器周期
 _nop_();    //等待一个机器周期
 _nop_();    //等待一个机器周期
 SDA = 0;    //SDA的下降沿被认为是开始信号
 _nop_();    //等待一个机器周期
 _nop_();    //等待一个机器周期
 _nop_();    //等待一个机器周期
 _nop_();    //等待一个机器周期
 SCL = 0;    //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)  
}

//函数功能:结束数据传送 
void stop()
{
 SDA = 0;     //SDA初始化为低电平“0” _n
 SCL = 1;     //结束数据传送时,要求SCL为高电平“1”
 _nop_();     //等待一个机器周期
 _nop_();     //等待一个机器周期
 _nop_();     //等待一个机器周期
 _nop_();     //等待一个机器周期
 SDA = 1;    //SDA的上升沿被认为是结束信号
 _nop_();     //等待一个机器周期
 _nop_();     //等待一个机器周期
 _nop_();     //等待一个机器周期
 _nop_();     //等待一个机器周期
 SDA=0;
 SCL=0;
}         

//应答检查
bit testack()
{
 bit ack_bit;
 SDA = 1;     // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
                 //以让SDA线转由接收设备(AT24Cxx)控制
 _nop_();        //等待一个机器周期 
 _nop_();        //等待一个机器周期 
 SCL = 1;       //根据上述规定,SCL应为高电平
 _nop_();       //等待一个机器周期 
 _nop_();       //等待一个机器周期 
 _nop_();       //等待一个机器周期 
 _nop_();       //等待一个机器周期 
 ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
                //若送高电平,表示没有接收到,传送异常
 SCL = 0;       //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
 return  ack_bit; 
}

//应答
void ack()
{
 SDA=0;
 _nop_();
 _nop_();
 SCL = 1;
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 SCL = 0;
 _nop_();
 _nop_();
 SDA=1;
 _nop_();
 _nop_(); 
}

//非应答
void noack()
{
 SDA=1;
 _nop_();
 _nop_();
 SCL = 1;
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 SCL = 0;
 _nop_();
 _nop_();
 
}

//函数功能:从AT24Cxx读取一个字节
unsigned char ReadData()
{
 uchar i;
 uchar x;   //储存从AT24Cxx中读出的数据
 for(i = 0; i < 8; i++)
 {
  SCL = 1;                //SCL置为高电平
  x<<=1;                  //将x中的各二进位向左移一位
  x|=(unsigned char)SDA;  //将SDA上的数据通过按位“或“运算存入x中
  SCL = 0;                        //在SCL的下降沿读出数据
 }
 return(x);                //将读取的数据返回
}

 

//写入一个字节
void  WriteCurrent(unsigned char y)
{
 unsigned char i;
    for(i = 0; i < 8; i++)  // 循环移入8个位
 {
     SDA = (bit)(y&0x80);   //通过按位“与”运算将最高位数据送到S
                                    //因为传送时高位在前,低位在后
  _nop_();            //等待一个机器周期   
    SCL = 1;            //在SCL的上升沿将数据写入AT24Cxx      
    _nop_();            //等待一个机器周期 
   _nop_();             //等待一个机器周期       
  
    SCL = 0;            //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
  y <<= 1;           //将y中的各二进位向左移一位
 }
   
}

//在器件指定地址 写 n 个字节
//参数(数据地址,器件内存地址 ,写字节数)
void writeI2C(uchar device,uchar *wdata,uchar add,uchar bytes)
{
 uchar wdeviceadd=device;
 uchar rdeviceadd=device+1;

 start();               //开始数据传递
 WriteCurrent(wdeviceadd);  //选择要操作的AT24Cxx芯片,并告知要对其写入数据
 testack();
 WriteCurrent(add);       //写入指定地址0x36
 testack();
 
 //进入循环
 for(;bytes!=0;bytes--)
 {
  WriteCurrent(*wdata);       //向当前地址(上面指定的地址)写入数据 0x00 
  testack();  //应答检查
  wdata++;

 }
 stop();                //停止数据传递
 delaynms(4);

 
}

//在器件指定地址 读出 n 个字节
//参数(接收读出数据缓存地址,读数据器件内存地址 ,读出字节数)
void readI2C(uchar device,uchar *rdata,uchar add,uchar bytes)
{
 uchar wdeviceadd=device;
 uchar rdeviceadd=device+1;
 
 /*读出数据
 流程:
 启动-写芯片寻址-应答检查-写数据首址-应答检查- 进入读数据程序段 */
 start();                      
 WriteCurrent(wdeviceadd);       //选择要操作的AT24Cxx芯片,并告知要对其写入数据
 testack();
 WriteCurrent(add);       //读出数据地址
 testack();

 /*读数据程序段流程:
 启动-写芯片寻址-应答检查- 进入读数据程序段*/  
 start();              
 WriteCurrent(rdeviceadd);   //选择要操作的AT24Cxx芯片,并告知要读其数据
 testack();

 /*读数据程序段
 条件判断-读数据-应答-指针操作-循环,
 最后一个字节退出循环-读最后一个字节-非应答-停止  */ 
 while(bytes!=1)
 {
  *rdata=ReadData(); 
  ack();  //应答
  rdata++;
  bytes--;
 }
 *rdata=ReadData();    //读出最后一个字节    
 noack();      //最后一个数据  非应答  
 stop();                //停止数据传递


}

 


//main 程序
void main() 
{


    //将此字符串存入24C02,再读出。
 uchar str2[5]="12345" ;
 uchar str3[5]="67890";
 uchar *p;

 //读出缓存
 uchar readbuf2[10];
 uchar readbuf3[10];

 //U3 定义器件地址
 uchar U3add=0xa0; //写入器件,寻址地址


 //U2 定义器件地址
 uchar U2add=0xa2; //写入器件,寻址地址

 
 
 
 //U2 写入str2
 writeI2C(U2add,str2,0x00,5);
 //U3 写入str3
 writeI2C(U3add,str3,0x00,5);

 //
 

 //读出U2
 readI2C(U2add,readbuf2,0x00,5);


  //初始化LCD
 InitLCD();
 WriteAdd(0x00);           
 //写数据

 p=readbuf2;
 
 while(*p!='\0')
 {
  WriteData(*p);
  p++;
 }

 delaynms(1000);


 //读出U3
 readI2C(U3add,readbuf3,0x00,5);

 p=readbuf3;
 
 while(*p!='\0')
 {
  WriteData(*p);
  p++;
 }

 delaynms(1000);
 //

}

 

C51: 2块 24C02 的读写 - 沙粒 - 沙粒的博客
关键字:C51  24C02  读写 引用地址:C51: 2块 24C02 的读写

上一篇:keil c51 串口调试
下一篇:C51: 向24C02,写入n个数据,再读出n 个数据

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

Keil C51 Code Banking
1. 简介 MCS-51是8根数据线,16根地址线,所以MCS-51最大只能访问64KB(216)的地址。很多较复杂的C51代码,其整个代码生成Bin文件可能大小64KB。针对这种情况,Keil C51提出了Code Banking机制来解决这个问题。 2. 基本原理 MCS-51内核的代码执行机制已经固定死了,代码运行的地址范围只能在0-64KB之间。一般情况下,我们编译生成的Bin文件,其代码执行地址和代码存储地址是一致。MCU执行到哪个地址,直接去ROM上取相应地址的内容然后执行即可。 MCU要访问超过64KB的地址范围,肯定需要增加地址线。增加4根地址线,则能够访问到2MB的地址范围。由于MCS-51只能执行64K
[单片机]
Keil <font color='red'>C51</font> Code Banking
MSP430读写片内FLASH保存数据
FLASH型的MSP430单片机都带有信息存储器SegmengA及SegmentB,SegmengA及SegmentB各有128字,SegmentB的地址是:0x01000h到0x107F,SegmentA的地址是:0x01080h到0x010FFh。程序被写入MSP430之后,程序通过SegmengA及SegmentB就可以保存不掉电数据。注意:每次程序烧写到MSP430时,SegmengA及SegmentB都会被擦除! 接下来贴出本文的程序代码,以及程序写入信息存储器之后的FLASH数据: #include msp430xG43x.h void WriteSegment_256 (char index,char
[单片机]
MSP430<font color='red'>读写</font>片内FLASH保存数据
AT24C01/02/04/08/16/32系列EEPROM读写程序
/*------------------------------------------------------------------------------ 〖说明〗24Cxx I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接GND(24C65接VCC,具体看DataSheet)。 现缺页写、页读,和CRC校验程序。以下程序经过50台验证,批量的效果有待考察。 为了安全起见,程序中很多NOP是冗余的,希望读者能进一步精简,但必须经过验证。 Atmel 24C01 比较特殊,为简约型,为其单独编程. 51晶振为11.0592MHz 〖文件〗RW24CXX.c 2001/09/18 -----------------
[单片机]
PID调节C51程序(4)
typedef struct PID { double SetPoint; // Desired Value double Proportion; // Proportional Const double Integral; // Integral Const double Derivative; // Derivative Const double LastError; // Error double PrevError; // Error double SumError; // Sums of Errors
[单片机]
一种安全可靠的IC卡读写器系统
  人们日常生活中经常接触到磁卡和IC卡,它们是根据卡片上的信息载体的不同而划分的。卡片及其读写器都属于人机接口的输入输出设备。磁卡是在卡片上贴一条窄窄的磁带来记录信息的,它主要用于车船票 、信用卡、电话磁卡、旅馆门钥匙等。IC卡则为近几年才出现的新型卡片,在卡片上嵌有IC(E2PROM,有的还有CPU)。由于它保存的信息比较可靠安全、可以高达几万次的读写,所以大量应用于公交车票 、饭票 、保健卡、收费系统等。下面介绍一种以XICOR公司的X76F100为卡片的、用于存取款的IC卡读写器方案。    1 硬件组成   图1为IC卡及其读写器硬件电路图。其中读写器由单片机、键盘、显示、监控电路等部分组成。IC卡采用XICOR公司
[工业控制]
51单片机1602、18B20电子钟--C51源代码
#include REGx52.h #include RICHMCU.H sbit a0 = ACC^0; sbit a1 = ACC^1; sbit a2 = ACC^2; sbit a3 = ACC^3; sbit a4 = ACC^4; sbit a5 = ACC^5; sbit a6 = ACC^6; sbit a7 = ACC^7; sbit DQ = P3^3 ; //18B20接口 sbit speaker = P3^6 ; //蜂鸣器 sbit MODE = P1^4 ; //模式键 sbit INC = P1^5 ; //增加键 sbit DEC = P1^6 ; //减少键 sbit OK
[单片机]
基于MFRC523的非接触式读写13.56MHz通信设计方案
MFRC523是NXP公司的一个的高集成读/写器,用于13.56MHz频率的非接触式通信。MFRC523阅读器支持ISO/IEC 14443 A/MIFARE模式。MFRC523的内部发射器无需额外的激活电路就能够驱动读/写器天线和收发器,其中读/写器天线用于同ISO/IEC 14443 A/MIFARE卡进行通信。接收器模块为来自ISO/IEC 14443 A/MIFARE兼容卡和转发器的信号提供高效的解调和解码。该数字模块具有完全的ISO/IEC 14443A架构和误差检测(奇偶和CRC)功能。 MFRC523可用于MIFARE 1K、MIFARE Mini以及MIFARE 4K产品,支持非接触式通信,并利用MIFARE在双方
[单片机]
基于MFRC523的非接触式<font color='red'>读写</font>13.56MHz通信设计方案
基于单片机的I2C的读写操作实验
利用24C08断电以后存储的数据不消失的特点,可以做一个断电保护装置。首先利用单片机做一个0-99秒的自动计时器。然后随机关断电源,在 通电以后计时器接着断电前的状态继续计时。 首先简单的说明以下I2C总线,I2C总线是一种串行数据总线,只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。在 I2C总线上传送的一个数据字节由八位组成。总线对每次传送的字节数没有限制,但每个字节后必须跟一位应答位。数据传送首先传送最高位(MSB),数据传送按图1所示格式进行。首先由主机发出启动信号“S”(SDA在SCL高电平期间由高电平跳变为低电平),然后由主机发送一个字节的数据。启动信号后的第一个字节数据具有特殊含义:高七位
[单片机]
基于单片机的I2C的<font color='red'>读写</font>操作实验
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

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

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