51单片机 I2C AT24C02

发布者:吾道明亮最新更新时间:2015-10-30 来源: eefocus关键字:51单片机  I2C  AT24C02 手机看文章 扫描二维码
随时随地手机看文章
    I2C协议在项目开发中使用很常见,很多存储芯片使用I2C接口。由于51单片机没有I2C接口,这里使用IO口模拟I2C通讯协议,来完成I2C芯片驱动。使用的I2C芯片为AT24C02。

    原理图如下:

51单片机 <wbr>I2C <wbr>AT24C02

    代码如下:

  //程序功能:计时器每一秒向AT24C02保持数据,同时数码管显示,重启之后读取出数据接着计时,100S循环
//程序问题:无法写入
#include
#define uint unsigned int
#define uchar unsigned char
//变量定义
uint timer_flag;                      //用于判断定时器T0方式一是否计满1s
uchar shiwei,gewei;                   //数码管显示的十位与个位
uint number;
uchar time_date;                      //当前时间数据
//控制端口声明
sbit duanxuan=P2^6;                   //数码管段选端
sbit weixuan=P2^7;                    //数码管位选端
sbit AT24C02_SDA=P2^0;                //AT24C02串行数据输入输出端口
sbit AT24C02_SCLK=P2^1;               //时钟信号端口
//数码管显示数字段码定义
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
//相关函数声明
void delay_minute();                  //延时us级函数声明
void delay_xs(uint);                  //延时s级函数声明
void timer_init();                    //定时器T0方式一初始化函数声明
void AT24C02_init();                  //I^2C通讯总线初始化函数声明
void star();                          //I^2C通讯启动函数声明
void stop();                          //I^2C通讯停止函数声明
void response();                      //应答函数声明
void write_in_byte(uchar);            //写入一个字节函数声明
uchar read_out_byte();                //读出一个字节函数声明,函数放回到读出的值
     //注意写入一个字节与写入数据的区别,前者是后者的一个子过程,读取同
void saveing(uchar,uchar);            //向AT24C02保存数据函数声明
uchar load(uchar);                    //从AT24C02载入掉电之前的数据,函数放回到读出的值
void quwei(uchar);                    //显示数字取出各位与十位
void display(uchar);                  //数码管显示函数声明
//主函数
void main()
{
  AT24C02_init();                     //AT24C02初始化
  time_date=load(3);                  //开机首先载入AT24C02中的数据,这里读取的是第三位址的数据
  if(time_date>100)                   //防止上一次保存的数据是100,这里计时是100循环的
  {
    time_date=1;
  }
  timer_init();                       //计时器T0方式一初始化
  while(1)
  {
    display(time_date);               //显示时间
    if(timer_flag==1)                 //如果计满一秒,就保存时间数据
    {
      timer_flag=0;
      saveing(3,time_date);           //保存时间数据
    }
  }
}
//延时us级函数主体
void delay_minute()
{;;}
//延时s级函数主体
void delay_xs(uint s)
{
  uint i,j;
  for(i=s;i>0;i--)
  {
    for(j=110;j>0;j--)
 {
 }
  }
}
//定时器T0方式一初始化函数主体
void timer_init()
{
  //方式选择
  TMOD=0x01;
  //预装初值
  TH0=(65536-46080)/256;
  TL0=(65536-46080)%6;
  //开中断
  EA=1;
  ET0=1;
  //启动定时器
  TR0=1;
}
//I^2C通讯总线初始化函数主体
void AT24C02_init()           //两线均写1  AT24C02数据有效规则,sclk为高电平且sda数据稳定,当sda发生有效数据变化时,sclk必须要是0
{
  AT24C02_SDA=1;
  delay_minute();
  AT24C02_SCLK=1;
  delay_minute();
}
//I^2C通讯启动函数主体
void star()                  //启动规则:SCLK-1,SDA下降沿
{
  AT24C02_SDA=1;             //一定要SDA首先为1,再是SCLK为1,否则会出现一个停止信号
  delay_minute();
  AT24C02_SCLK=1;
  delay_minute();
  AT24C02_SDA=0;
  delay_minute();
}
//I^2C通讯停止函数主体
void stop()                 //停止规则:SCLK-1,SDA上升沿
{
  AT24C02_SDA=0;            //一定要SDA首先为0,再是SCLK为1,否则会出现一个启动信号
  delay_minute();
  AT24C02_SCLK=1;
  delay_minute();
  AT24C02_SDA=1;
  delay_minute();
}
//应答函数主体
void response()             //应答规则:SCLK-1,等待从机把SDA拉低
{
  uint i;
  AT24C02_SCLK=1;
  delay_minute();
  while(AT24C02_SDA==1&&i<255)//等待从机把SDA拉低,且超过一定时间没有应答,默认已经应答
  {
    i++;
  }
  AT24C02_SCLK=0;             //应答之后,SCLK-0.防止数据误操作,因为SCLK-1,数据就是有效地
  delay_minute();
}
//写入一个字节函数主体
void write_in_byte(uchar date)
{
  uint i,buffer;             //i用于循环发送每一位,buffer缓冲数据
  buffer=date;
  for(i=0;i<8;i++)
  {
    buffer=buffer<<1;        //buffer左旋,高位就放入CY
 AT24C02_SCLK=0;          //有效发送规则:sclk-0变化数据,sclk-1数据稳定后有效
 delay_minute();
 AT24C02_SDA=CY;
 delay_minute();
 AT24C02_SCLK=1;
 delay_minute();
  }
  AT24C02_SCLK=0;           //不发送,一定是SCLK-0,SDA-1
  delay_minute();
  AT24C02_SDA=1;
  delay_minute();
}
//读出一个字节函数主体
uchar read_out_byte()       //读出规则:启动-控制字片选+写(为了写入要读取的地址)-应答-写入存储地址-应答-读取数据-应答-停止
{
  uchar i,buffer_writting;
  //--------------------------------------------------
  //不能少的
  AT24C02_SCLK=0;           //方便SDA数据发生有效变化
  delay_minute();
  AT24C02_SDA=1;
  delay_minute();
  //--------------------------------------------------
  for(i=0;i<8;i++)
  {
    AT24C02_SCLK=1;
 delay_minute();
 buffer_writting=(buffer_writting<<1)|AT24C02_SDA;//buffer_writting左旋之后与AT24C02_SDA的数据线与
 delay_minute();
    AT24C02_SCLK=0;
 delay_minute();

  }
  return buffer_writting;
}
//向AT24C02保存数据函数主体
void saveing(uchar address,uchar time_date0)         //写入字节规则:启动-控制字片选+写-应答-写入存储地址-应答-写入数据-应答-停止
{
  star();                                            //启动信号
  write_in_byte(0xa0);
  response();
  write_in_byte(address);
  response();
  write_in_byte(time_date0);
  response();
  stop();
}
//从AT24C02载入掉电之前的数据函数主体
uchar load(uchar address)                            //读出规则:启动-控制字片选+写(为了写入要读取的地址)-应答-写入存储地址-应答-读取数据-应答-停止
{
  uchar time_date_former;
  star();
  write_in_byte(0xa0);
  response();
  write_in_byte(address);
  response();
  time_date_former=read_out_byte();
  stop();
  return time_date_former;
}
//显示数字取出各位与十位函数主体
void quwei(uchar quwei_date)
{
  shiwei=quwei_date/10;
  gewei=quwei_date;
}
//数码管显示函数函数主体
void display(uchar display_date)
{
  quwei(display_date);
  //显示第一个数码管
  duanxuan=1;
  P0=table[shiwei];
  duanxuan=0;
  P0=0xff;
  weixuan=1;
  P0=0xfe;
  weixuan=0;
  delay_xs(2);
  //显示第二的数码管
  duanxuan=1;
  P0=table[gewei];
  duanxuan=0;
  P0=0xff;
  weixuan=1;
  P0=0xfd;
  weixuan=0;
  delay_xs(2);
}
//T0定时器方式一中断服务程序
void T0_timer_no1() interrupt 1
{
  //预装初值
  TH0=(65536-46080)/256;
  TL0=(65536-46080)%6;
  number++;
  if(number==20)                         //20次计满就是1s
  {
    number=0;
    time_date++;                         //时间累加
    timer_flag=1;                        //计满一次就保存数据
 if(time_date==100)                   //100s循环计时
 {
   time_date=0;
 }
  }
}
 以上,结束。

关键字:51单片机  I2C  AT24C02 引用地址:51单片机 I2C AT24C02

上一篇:51单片机 LCD12864
下一篇:51单片机 LCD1602

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

51单片机LED流星雨拖尾灯程序
流星雨就是几个亮度不同的灯一起滚动,亮度依次更暗,像流星雨拖着尾巴。 控制全彩(三色)led也可以用同样的概念编程。 用的是51的单片机pwm实现的拖尾效果 程序的解说以及视频演示请打开http://www.51hei.com/bbs/dpj-22524-1.html 里面有详细的说明. 程序源码: #include reg52.h #define uint unsigned int #define uchar unsigned char uchar abit=16; //流到哪位 uchar atimer0_n; uchar code abit8 ={1,2,4,8,16,32,64,128,0}; uchar nn; c
[单片机]
<font color='red'>51单片机</font>LED流星雨拖尾灯程序
51单片机的延时子程序
延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者 我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如 在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何实现的呢?下面让我们先来了解一些相关的概念。 一、机器周期和指令周期 1.机器周期是指单片机完成一个基本操作所花费的时间,一般使用微秒来计量单片机的运行速度,51 单片机的一个机器周期包
[单片机]
基于51单片机自动售货机设计
一.硬件方案 本设计由STC系列单片机+12864显示+电源模块+按键模块+蜂鸣器报警模块等元件组成。 使用STC89C52(STC89C52数据手册)单片机设计,设有8个按键,3个按键模拟硬币(5元、1元、5角),另外5个按键模拟货物选择,一块12864显示屏;如图: 二.设计功能 (1)开机启动显示货物价格列表,自动切换列表。 (2)可以选择①—⑤种货物(或更多)。 (3)按对应按键可选择该货物。 (4)选择后,提示要投进的金额,并显示投币有效时间30秒(可修改)。 (5)按键模拟投币,有5元、1元、5角。 (6)投币金额等于或大于所选货物的金额则购物成功。 (7)若投币不足,则30秒后自动退回。 三.设计原理图 (1
[单片机]
基于<font color='red'>51单片机</font>自动售货机设计
用定时器做的流水灯
简介:在51单片机开发板上,用定时器做了一个流水灯程序,调整非常灵活,很实用拿出来和朋友们一起分享 #include reg52.h unsigned char sz ={ 0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f, 0xbf,0xdf,0xef,0xf7, 0xfb,0xfd, }; void main() { unsigned char cnt = 0; //声明定时器并赋值 unsigned char sec = 0; //声明计数器并赋值 TMOD = 0x01; //设置定时器模式为1 TH0 = 0xb8; //高位定时器并赋初值 TL0 = 0x00; //低位定时
[单片机]
51单片机实验13:温度传感器模块应用
开发板温度模块电路图如下: 目的:利用开发板温度传感器测量温度,并在数码管显示。 开发板温度传感器模块相关内容:https://blog.csdn.net/cax1165/article/details/86763991 开发板数码管模块的相关内容:https://blog.csdn.net/cax1165/article/details/86557551 主函数: #include reg52.h #include temp.h #define uc unsigned char #define ui unsigned int sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC
[单片机]
<font color='red'>51单片机</font>实验13:温度传感器模块应用
51单片机扩充串行口的方法
基本的 51 单片机有四个并行口,其中还包含了一个串行口。 当接口不够用的时候,大家就会想到,使用什么外接芯片来扩充。 但是,各种教材、参考书、网络文章,介绍扩充并行口的花样不少,扩充串行口的方法,几乎无人问津。 偶尔见到一个,也是使用 8250、8251 等“巨型”芯片来扩充的 使用这些芯片,就要占用单片机很多的更为紧缺的并行口,基本上就是得不偿失。更别说还要设置复杂的控制字了。 使用简单的三态门,即可为单片机扩充串行口,仅仅占用单片机的一、二个引脚作为控制引线而已。 实际上是很简单的,就像使用 74LS373、74LS244 扩充并行口一样,为串行口,配上合适三态门就行了。 选用 74LS125(低电平
[单片机]
<font color='red'>51单片机</font>扩充串行口的方法
51单片机的中断基本知识介绍
1、中断的概念 对于单片机中断的概念,我们可以这样理解:单片机处理某一事件A时,发生了另一事件B请求(中断请求);单片机暂时中断当前工作,转去处理事件B(中断响应和中断服务);待单片机将事件B处理完毕,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断。 引起单片机中断的根源或原因: 中断源向单片机提出中断请求。 2、中断优先级 单片机的中断系统一般允许多个中断源,当几个中断源同时向单片机请求中断,要求为它服务的时候,这就存在单片机优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。单片机总是先响应优先级别最高的中断请
[单片机]
<font color='red'>51单片机</font>的中断基本知识介绍
51单片机烧写程序的方法
STC89C51是应用广泛的51单片机,很多人都是通过该单片机入门学习的,单片机的学习需要勤动手。单片机需要烧写程序,要用到相关的软件和硬件。下面介绍一下51单片机烧写程序的方法。 1 所用到的硬件工具 51单片机烧写程序需要用到单片机的UART串口,所用到的工具为USB/TTL,具有四个引脚分别为5V、GND、TXD、RXD,需要和单片机的UART口连接,在连接的时候需要注意的是,串口要交叉连接,即USB/TTL的TXD和单片机的RXD连接;USB/TTL的RXD和单片机的TXD连接。 2 所用到的软件以及设置 STC的51单片机需要用到STC-ISP软件,该软件可以在STC的官网上下载到 烧写过程为:1)选择具体的单片机型
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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