单片机
返回首页

C51: 2块 24C02 的读写

2016-10-14 来源:eefocus

/*/函数功能,

向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 的读写 - 沙粒 - 沙粒的博客
进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

    相关电子头条文章