51通过IO口模拟IIC实现AT24C02的读写

发布者:meilidaowl最新更新时间:2019-01-14 来源: eefocus关键字:IO口  模拟IIC  AT24C02的读写 手机看文章 扫描二维码
随时随地手机看文章

1.硬件连接


这里写图片描述


AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。在单片机上的应用广泛, 可以实现掉电数据不丢失功能。


2.AT24C02读写时序说明:


(1)写数据描述:


通过IIC几种信号的组合,可以向AT24C02指定单元地址写一字节的数据。


这里写图片描述


可以看出,写顺序为:起始,写器件地址,应答,写单元地址,应答,写数据,应答,终止。


(2)读数据描述


这里写图片描述


从AT24C02任意单元地址读取数据,可以看出读写顺序为:起始,写器件地址(下一个字节为写),应答,写单元地址,应答,起始,写器件地址(下一个字节为读取),读取数据,终止。


3.例程实现


(1)延时

delay.h:


#ifndef _DELAY_H

#define _DELAY_H


#include "stc51.h"


void delay_us(uchar t);

void delay_ms(uint t);



#endif


#include "delay.h"

#include "stc51.h"

//Function:延时1us

//Input:延时的微秒数

//Output:无

//Return:无

//Others:无

void delay_us(uchar t)

{

    while(t--);

}


//Function:延时1us

//Input:延时的毫秒数

//Output:无

//Return:无

//Others:无

void delay_ms(uint t)

{

    uint x,y;

    for(x=t;x>0;x--)

        for(y=110;y>0;y--);

}



(2)IIC模拟

iic.h:


#ifndef _IIC_H

#define _IIC_H


#include "stc51.h"


/*IIC管脚定义*/

sbit IIC_SDA = P3^0;

sbit IIC_SCL = P3^1;


void IO_Init();

void IIC_Start();

void IIC_Stop();

void IIC_Ack();

void IIC_NAck();

void IIC_Write_Byte(uchar txd);

uchar IIC_Read_Byte();


#endif


iic.c:


#include "delay.h"

#include "iic.h"

#include "stc51.h"


//Function:初始化IO口

//Description:GPIO初始化为高,通知器件总线空闲

//Input:无

//Output:无

//Return:无

//Others:无

void IO_Init()

{

    IIC_SCL = 1;

    delay_us(5);

    IIC_SDA = 1;

    delay_us(5);

}


//Function:启动IIC传输

//Description:IIC_SCL为高时,IIC_SDA由高到低

//Input:无

//Output:无

//Return:无

//Others:无

void IIC_Start()

{

    IIC_SDA = 1;

    IIC_SCL = 1;

    delay_us(5);

    IIC_SDA = 0;

    delay_us(5);

    IIC_SCL = 0;

}


//Function:停止IIC传输

//Description:IIC_SCL为高时,IIC_SDA由低到高

//Input:无

//Output:无

//Return:无

//Others:无

void IIC_Stop()

{

    IIC_SCL = 0;

    IIC_SDA = 0;

    delay_us(5);

    IIC_SCL = 1;

    IIC_SDA = 1;

    delay_us(5);

}


//Function:产生应答信号

//Description:IIC_SCL为高时,IIC_SDA被拉低并保持一定时间的低电平

//Input:无

//Output:无

//Return:无

//Others:无

void IIC_Ack()

{

    uchar i;


    IIC_SCL = 1;//在scl为高电平期间等待应答

    delay_ms(2);

    while((IIC_SDA == 1) && i < 250)//若为应答0即退出,从机向主机发送应答信号

        i++;//通过i自增等待一段时间   

    IIC_SCL = 0;//得到应答,拉低时钟

    delay_ms(2);

}


//Function:产生非应答信号

//Description:IIC_SCL为高时,IIC_SDA为高

//Input:无

//Output:无

//Return:无

//Others:无

void IIC_NAck()

{

    IIC_SCL = 1;

    delay_ms(2);

    IIC_SDA = 1;

    IIC_SCL = 0;

    delay_ms(2);

}


//Function:I2C写一个字节数据,返回ACK或者NACK

//Description:从高位开始依次传输

//Input:写的字节

//Output:无

//Return:无

//Others:无

void IIC_Write_Byte(uchar txd)

{

    uchar len;


    for (len=0;len<8;len++)

    {

        IIC_SCL = 0;//只有在IIC_SCL为低电平时,才允许IIC_SDA上的数据变化

        delay_us(5); 

        if(txd & 0x80)

            IIC_SDA = 1;

        else

            IIC_SDA = 0;  

        delay_us(5);   

        IIC_SCL = 1;//在IIC_SCL为高电平时,不允许IIC_SDA上的数据变化,使数据稳定

        txd <<= 1;

        delay_us(10); 

        IIC_SCL = 0;    

        delay_us(5);

    }

    IIC_SDA = 1;//释放总线

    IIC_SCL = 1;

    delay_us(5);

}


//Function:I2C读一个字节数据,返回ACK或者NACK

//Description:从高到低,依次接收

//Input:是否应答

//Output:无

//Return:接收的数据

//Others:无

uchar IIC_Read_Byte(/*uchar ack*/)

{

    uchar len,dat = 0;


    IIC_SDA = 1;//准备读取数据

    for(len=0;len<8;len++) 

    {


        IIC_SCL = 0; 

        delay_us(5);

        IIC_SCL = 1;//不允许IIC_SDA变化

        delay_us(5); 

        dat <<= 1;

        dat |= IIC_SDA; //读数据 

        delay_us(5); 

        IIC_SCL = 0;//允许IIC_SDA变化等待下一位数据的到来

        delay_us(5); 

    }   


    return dat;

}


(3)AT24C02实现:


at24c02.h:


#ifndef _AT24C02_H

#define _AT24C02_H


#include "stc51.h"


#define IIC_WADDR   0XA0

#define IIC_RADDR   0XA1


void AT24C02_Init(void);


void At24c02_Write_Byte(uchar addr,uchar dat);

uchar At24c02_Read_Byte(uchar addr);


void At24c02_Serial_Write(uchar Writeaddr,uchar *Str,uchar Len);

void At24c02_Serial_Read(uchar Readaddr,uchar *Str,uchar Len);


#endif


at24c02.c:


#include "iic.h" 

#include "delay.h"

#include "at24c02.h"

#include "stc51.h"



//Function:初始化AT24C02

//Description:IO口属于空闲,准备开始通信

//Input:无

//Output:无

//Return:无

//Others:无

void AT24C02_Init(void)

{

    IO_Init();

}


//Function:写一个字节

//Description:向AT24C02的任意地址写入一个字节数据

//Input:写入的地址和数据

//Output:无

//Return:无

//Others:无

void At24c02_Write_Byte(uchar addr,uchar dat)

{

    IIC_Start();    //启动

    IIC_Write_Byte(IIC_WADDR);  //发送从设备地址

    IIC_Ack();  //等待从设备的响应

    IIC_Write_Byte(addr);   //发出芯片内地址

    IIC_Ack();  //等待从设备的响应

    IIC_Write_Byte(dat);    //发送数据

    IIC_Ack();  //等待从设备的响应

    IIC_Stop(); //停止

    delay_ms(10);    // 写入周期

}


//Function:指定地址读一个字节

//Description:向AT24C02的指定地址读出一个字节数据

//Input:读地址

//Output:无

//Return:读到的数据

//Others:无

uchar At24c02_Read_Byte(uchar addr)

{

    uchar dat;


    IIC_Start();

    IIC_Write_Byte(IIC_WADDR);//发送发送从设备地址 写操作

    IIC_Ack();

    IIC_Write_Byte(addr);//发送芯片内地址

    IIC_Ack();

    IIC_Start();

    IIC_Write_Byte(IIC_RADDR);//发送发送从设备地址 读操作

    IIC_Ack();

    dat = IIC_Read_Byte();//获取数据

    IIC_Stop();


    return dat;

}


//Function:任意地址写入一串数据

//Description:向AT24C02写入一串数据

//Input:写地址,写数据,数据长度

//Output:无

//Return:无

//Others:无

void At24c02_Serial_Write(uchar Writeaddr,uchar *Str,uchar Len)

{

    while(Len--)

    {

        At24c02_Write_Byte(Writeaddr,*Str);

        Writeaddr++;

        Str++;

    }

}


//Function:指定地址读出一串数据

//Description:向AT24C02读出一串数据

//Input:读地址,读数据,数据长度

//Output:无

//Return:无

//Others:无

void At24c02_Serial_Read(uchar Readaddr,uchar *Str,uchar Len)

{

    while(Len)

    {

        *Str++ = At24c02_Read_Byte(Readaddr++);

        Len--;

    }

}



stc51.h:


#ifndef _STC51_H

#define _STC51_H


#include


typedef unsigned char   uchar;

typedef unsigned int    uint;


#endif


主函数main.c:


#include "iic.h"

#include "at24c02.h"

#include "stc51.h"

#include "Lcd_4line.h"

#include "key.h"

#include "delay.h"


//要写入到24c02的字符串数组

const uchar TEXT_Buffer[]={"STC51"};

uchar TEXT_Buffer1[]={"00000"};//数组一定初始化


#define SIZE sizeof(TEXT_Buffer)


void main()

{

    uchar dat = 8;

    uchar Text = 6 + '0';

    uchar val;


    Lcd_1602_init();

    AT24C02_Init();

    while(1)

    {

        lcd_onestring(0,0,Text);

        At24c02_Write_Byte(10,dat);

        val = At24c02_Read_Byte(10);

        val = val + '0';

        lcd_onestring(1,0,val);


    lcd_string(0,7,5,TEXT_Buffer);

    At24c02_Serial_Write(10,TEXT_Buffer,5);

    At24c02_Serial_Read(10,TEXT_Buffer1,5);

    lcd_string(1,7,5,TEXT_Buffer1);

    }

}


4.实验现象

通过LCD1602显示写入和读出的数据,分别测试单字节和字符串

这里写图片描述

关键字:IO口  模拟IIC  AT24C02的读写 引用地址:51通过IO口模拟IIC实现AT24C02的读写

上一篇:51 软件模拟SPI驱动OLED
下一篇:C51/C52的定时器计数器与中断

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

LabVIEW编程实时控制KEITHLEY 6517A静电计
基于GPIB接口总线,采用6517A中最简单的按钮命令,在LabVIEW5.1平台上实现了对6517A面板操作的实时控制和信息的同步显示。   关键词:LabVIEW编程;计算机模拟;6517A静电计 Hefei 230029, China)   LabVIEW提供了任意一个程序调用另一个LabVIEW程序的办法,即将后者作为一个子程序(即subVI)。因此在实验站的数据采集主程序中,将模拟的6517A作为主程序调用的subVI嵌入其中(当然这个子程序完全可以不依赖于主程序而能够独立运行)。根据主程序的要求,6517A的subVI具备以下特点:   代码简洁,执行效率高;完全能实现真实面板上各个按键的功能,并可以基本同步显
[测试测量]
LabVIEW编程实时控制KEITHLEY 6<font color='red'>51</font>7A静电计
51单片机模拟IIC通信
在 之前的MCS-51系列单片机中内部没有IIC通信资源,所如果要想用51单片机实现IIC通信,就只能通过软件模拟其时序,这样也能实现IIC通信的功 能。如下程序是我用Protues仿真IIC通信的结果,希望对大家有用,非常希望有共同爱好的朋友,多给我提出些宝贵的意见,至诚感谢! 这个是IIC的头文件,便于使用调用: #ifndef _IIC_H_ #define _IIC_H_ /***ucahr和uint 的宏定义很重要,否则下面的函数无法正常运行******/ #define uchar unsigned char //定义uchar型数据为无符号型 #define uint unsigned int //定义uint
[单片机]
基于TDK5110与TDA5220无线温度采集系统
介绍一种基于英飞凌公司TDK5110与TDA5220芯片的无线温度采集系统。对该系统的无线数据传输部分进行了深入分析,重点分析了无线发射芯片TDK5110及无线接收芯片TDA5220的参数设计与硬件电路设计。该系统具有极强的抗干扰性,可以应用在恶劣的温度环境下,实现了对温度状况的实时监控,有效地降低了发射系统功耗,提高了系统的可靠性。   随着科学技术的发展,简单、方便、实用的东西越来越受到人们的喜爱。无线通信技术的发展为人们的生活、生产带来了极大的改变,节省了大量的人力、物力资源。现在,无线通信技术已经应用到生活的方方面面。在一些不利于有线通信的场所,无线通信技术更是起到了不可替代的作用。小到对讲机,大到移动通信网络,它们无疑在改
[模拟电子]
基于TDK<font color='red'>51</font>10与TDA5220<font color='red'>的</font>无线温度采集系统
51单片机心形灯实现从右到左顺时针流水编程
心形灯原理图 编译软件:Keil uVision5 (如有需要可点此链接下载:https://download.csdn.net/download/qq_36931762/11343174) 单片机程序下载软件:STC-ISP (如有需要可点此链接下载:https://download.csdn.net/download/qq_36931762/11343157) 程序代码: #include reg51.h #include intrins.h unsigned char code table ={0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; unsigned c
[单片机]
<font color='red'>51</font>单片机心形灯实现从右到左顺时针流水编程
51通讯协议—奇偶校验
代码 #include "at89x52.h" /*************************************************** * 类型定义,方便代码移植 ***************************************************/ typedef unsigned char UINT8; typedef unsigned int UINT16; typedef unsigned long UINT32; typedef char INT8; typedef int INT16; typedef long
[单片机]
51单片机——SPI
UART、 I2C 和 SPI 是单片机系统中最常用的三种通信协议。 1、初步介绍 SPI 是一种高速的、全双工、同步通信总线,标准的 SPI 也仅仅使用 4 个引脚,常用于单片机和 EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。 SPI 通信原理比 I2C要简单,它主要是主从方式通信,这种模式通常只有一个主机和一个或者多个从机,标准的 SPI 是 4 根线,分别是 SSEL( 片选,也写作 SCS)、 SCLK( 时钟,也写作 SCK)、 MOSI( 主机输出从机输入Master Output/Slave Input) 和 MISO( 主机输入从机输出 Master Input/Slave Output)。
[单片机]
基于AT89C51SND1C单片机MP3播放器设计
引言 MP3作为高质量音乐压缩标准,正在进入越来越多人的生活,给数字音频工业带来了强劲的冲击。MP3使用此技术可以获得较大的音乐压缩比,还可以得到较高的音乐回放质量,比如将CD格式的音乐数据压缩成MP3格式,音效相差无几,文件大小至少可以压缩12倍。 正是由于MP3音乐的较小数据量和近似完美的播放效果,使得以MP3为后缀的音乐文件在网络上的传输得以实现。当前MP3播放器正朝着功能强大、外观丰富、价格便宜的方向发展,这里提出一种基于AT89C51SND1C单片机的MP3播放器设计方案。 1 MP3编码简介 MP3是MPEG Layer III(第3层音频编码标准)的缩写,图1为MP3编码器内部原理框图。它是一种超级声音文件的压缩
[单片机]
基于AT89C<font color='red'>51</font>SND1C单片机<font color='red'>的</font>MP3播放器设计
S3C2510A设计嵌入式数字硬盘录像机技术
  数字硬盘录像机,英文名称为Digital Video Recorder,简称DVR,它是视频监控系统中重要的设备,用于替代早期的长延时录像机或者磁带录像机。目前硬盘录像机从硬件架构上分主要分为工控式硬盘录像机(或者工控硬盘录像机或者PC式硬盘录像机)、嵌入式硬盘录像机,从压缩算法来分有小波压缩、MJPEG、MPEG4、H.264等。目前工控式硬盘录像机和嵌入式硬盘录像机所占市场比重差不多,由于嵌入式硬盘录像机的稳定性及易维护性,选择嵌入式硬盘录像机的用户会越来越多,市场前景非常大。基于这种应用背景,本文提出了嵌入式硬盘录像机的设计思路和实现方案。   系统总体方案   1 技术指标   本系统的主要技术指标如下。   ●
[单片机]
S3C2<font color='red'>51</font>0A设计<font color='red'>的</font>嵌入式数字硬盘录像机技术
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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