51单片机——IIC、EEPROM数据存储 C语言入门编程

目录

IIC:

起始和停止信号:

应答响应:

AT24C02:

 1.IIC—EEPROM:码管右3位显示0, 按K1键将数据写入到EEPROM内保存,按K2键读取EEPROM内保存的数据,按K3键显示数据加1,按K4键显示数据清零,最大能写入的数据是255


IIC:

        I2C(Inter-Integrated Circuit)总线是由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单, 器件封装形式小,通信速率较高等优点。I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。由于其管脚少,硬件实现简单,可扩展性强等特点,因此被广泛的使用在各大集成芯片内。       

        (1)它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在 一个I2C通讯总线中,可连接多个I2C通讯设备,支持多个通讯主机及多个通 讯从机。 (2)一个I2C总线只使用两条总线线路,一条双向串行数据线(SDA),一 条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。 (3)每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址 进行不同设备之间的访问。 (4)总线通过上拉电阻接到电源。当I2C设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。 (5)多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定 由哪个设备占用总线。具有三种传输模式:标准模式传输速率为100kbit/s,快速模式为400kbit/s,高速模式下可达3.4Mbit/s,但目前大多I2C设备尚不支持高速模式。 (7)连接到相同总线的IC数量受到总线的最大电容400pF限制。

        数据有效性规定:I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。每次数据传输都以字节为单位,每次传输的字节数不受限制。

起始和停止信号:

        SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。(接收数据和接收应答时应先释放SDA置1)起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。

应答响应:

        每当发送器件传输完一个字节的数据后,后面必须紧跟一个校验位,这个校验位是接收端通过控制SDA(数据线)来实现的,以提醒发送端数据我这边已经接收完成,数据传送可以继续进行。这个校验位其实就是数据或地址传输过程中的响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。

作为数据接收端时,当设备(无论主从机)接收到I2C传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号即特定的低电平脉冲,发送方会继续发送下一个数据;若接收端希望结束数据传输,则向对方发送“非 应答(NACK)”信号即特定的高电平脉冲,发送方接收到该信号后会产生一个停止信号,结束信号传输。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有 9 位)。

AT24C02:

        AT24C01/02/04/08/16...是一个 1K/2K/4K/8K/16K位串行CMOS,内部含有 128/256/512/1024/2048个8位字节,AT24C01有一个8字节页写缓冲器, AT24C02/04/08/16 有一个16字节页写缓冲器。该器件通过I2C总线接口进行 操作,它有一个专门的写保护功能。

        AT24C02 器件地址为7位,高4位固定为1010,低3位由A0/A1/A2信号线的电平决定。 因为传输地址或数据是以字节为单位传送的,当传送地址时, 器件地址占7位,还有最后一位(最低位 R/W)用来选择读写方向,它与地址无关。(每次写入数据都需要5ms)

 1.IIC—EEPROM:码管右3位显示0, 按K1键将数据写入到EEPROM内保存,按K2键读取EEPROM内保存的数据,按K3键显示数据加1,按K4键显示数据清零,最大能写入的数据是255

        IIC函数

#include <REGX52.H>

sbit SCL=P2^1;
sbit SDA=P2^0;

void IIC_Start(void)//IIC开始
{
    SDA=1;
    SCL=1;
    SDA=0;
    SCL=0;
}

void IIC_Stop(void)//IIC停止
{
    SCL=0;
    SDA=0;
    SCL=1;
    SDA=1;
}

void IIC_SendAck(unsigned char Ack)//IIC发送应答0为应答1为非应答
{
    Ack=SDA;
    SCL=1;
    SCL=0;
    SDA=0;
}

unsigned char IIC_ReceiveAck(void)//IIC接收应答
{
    unsigned char Ack;
    SDA=1;//接收时先释放SDA置1
    SCL=1;
    SDA=Ack;
    SCL=0;
    SDA=0;
    return Ack;
}

void IIC_SendByte(unsigned char Byte)//IIC发送一个字节,先发高位
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        SDA=Byte&(0x80>>i);
        SCL=1;
        SCL=0;
    }
}
unsigned char IIC_ReceiveByte(void)//IIC接收一个字节
{
    unsigned char Byte=0,i;
    SDA=1;//接收时先释放SDA置1
    for(i=0;i<8;i++)
    {
        SCL=1;
        if(SDA)
            Byte|=(0x80>>i);
        SCL=0;
    }
    return Byte;
}

        AT24C02函数

#include <REGX52.H>
#include "IIC.h"

void AT24C02_WriteByte(unsigned char Address,Data)//AT24C02写入一个字节 地址,数据 需5ms
{
    IIC_Start();
    IIC_SendByte(0xa0);//写入
    IIC_ReceiveAck();
    IIC_SendByte(Address);
    IIC_ReceiveAck();
    IIC_SendByte(Data);
    IIC_ReceiveAck();
    IIC_Stop();
}

unsigned char AT24C02_ReceiveByte(unsigned char Address)//AT24C02读取一个字节 地址
{
    unsigned char Data;
    IIC_Start();
    IIC_SendByte(0xa0);//写入
    IIC_ReceiveAck();
    IIC_SendByte(Address);
    IIC_ReceiveAck();
    IIC_Start();
    IIC_SendByte(0xa1);//读取
    IIC_ReceiveAck();
    Data=IIC_ReceiveByte();
    IIC_SendAck(1);
    IIC_Stop();
    return Data;
}

        主函数

#include <REGX52.H>
#include "AT24C02.h"
#include "shumaguan.h"
#include "anjian.h"

void main()
{
    unsigned char i=199,key;
    while(1)
    {
        key=anjian();
        if(key)
        {
            if(key==1)
            {
                AT24C02_WriteByte(0,i);//写入当前数据
            }
            if(key==2)
            {
                i=AT24C02_ReceiveByte(0);//读取写入的数据
            }
            if(key==3)
            {
                i++;//当前数据+1
            }
            if(key==4)
            {
                i=0;//当前数据清零
            }
        }
        shumaguan(6,i/100);//显示数据
        shumaguan(7,(i/10)%10);
        shumaguan(8,i%10);
    }
}

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
51单片机基础应用设计C语言实例源码仿真300个合集: 100000秒以内的计时程序 10秒的秒表 12864LCD图形滚动演示 128X64LED 160128LCD图文演示 1602字符液晶滚动演示程序 1602液晶显示的DS1302实时时钟 16×16点阵(滚动显示) 16×16点阵2(滚动显示) 2io5键盘模拟音量数码管显示 2×20串行字符液晶演示 32x16汉字 44行列键盘 485全双工通信 4×4键盘矩阵控制条形LED显示 4个独立式按键控制LED开关 4个独立式按键控制LED移位 4只数码管滚动显示0~3 555可调PWM发生器 555的应用 6264扩展内存 6个16×16点阵 74HC154译码器应用 74HC595 74HC595串入并出芯片应用 74LS138译码器应用 74LS148扩展中断 8051双机通信简例 8255并行口扩展实例 89C51PWM 8x8LED汉字显示 8x8点阵做的贪吃蛇游戏 8×8LED点阵屏显示数字 8只数码管同时显示不同字符 8只数码管显示多个不同字符 8只数码管滚动显示8~F 8只数码管滚动显示单个数字 8只数码管滚动显示数字串 8只数码管闪烁显示 8通道自动温度检测系统仿真(含原程序) ADC0808 PWM实验 ADC0809模数转换与显示 ADC0832模数转换与显示 AT89C51对直流电动机的驱动 AVR_Uart BCD译码数码管显示数字 c51 可预设电压的数控电源(功能强大) clock Conter CPU控制的独立式键盘扫描实验 da、ad。液晶,传递函数模型综合应用的实例 DIY51式数控电源 DS1621温度传感器实验 ds18b20 DS18B20温度传感器实验 DS18B20温度检测及其液晶显示 HorseLight I2C IIC-24C04与数码管 IIC-24C04与蜂鸣器 INT0与INT1中断计数 INT0中断3位计数 INT0及INT1中断计数 INT0和INT1控制条形LED INT1中断5位计数 IO并行口直接驱动单个数码管 K1-K4 分组控制LED K1-K4 控制LED移位 K1-K4 控制数码管加减演示 K1-K4 控制数码管移位显示 K1-K4 键状态显示 key_lcd ks0108 液晶12864 LCD频率计仿真 LED代码查询V1[1].1 LED模拟交通灯 LED闪烁 M16_AN_Compare M16_EEPROM M16_Horse MAX7221控制数码管动态显示 my16key_c NT0中断控制LED NT0中断计数 NumberDisplay P3口流水灯 PCF8574 PCF8583+LCD1602 PCF8591模数与数模转换实验 proteus ADDC的练习程序 PWM PWMLED PWM控制LED的亮度仿真程序 PWM控制马达的方法 PWM波输出(可调) PWM电机正反转 pwm程序实例 PWM调温 RAM扩展练习 sscom32串口调试 TIMER0与TIMER1控制条形LED TIMER0控制LED二进制计数 TIMER0控制单只LED闪烁 TIMER0控制四只LED滚动闪烁 TIMER0控制流水灯 ULN2803 usart_t 《lcd1602仿真实例》 一个数控直流稳压电源 一个步进电机的仿真 一步一步教你51_PC串口通信 万能逻辑电路实验 三机通讯 串口仿真mcu_pc 串口方式1 串行数据转换为并行数据 交通灯 从左到右的流水灯 光藕隔离驱动电机 内部函数intrins.h应用举例 净水控制器仿真电路 刚做好的十个字的led屏模拟有程序 包含单片机寄存器的头文件 单只按键控制单只数码管滚动显示 单只数码管循环显示0-9 单只数码管循环显示0~F 单片机与PC机串口通讯仿真 单片机之间双向通信 单片机向PC发送数据 单片机向主机发送字符串 单片机接收PC发出的数据 单片机控制的电动自行车驱动系统 单片机数据发送程序 发一个用定时器做的PWM 基于1602+ds12b80+ds1302+音乐+电子书+流水灯的多功能电子表 基于ADC0832的数字电压表 基于AT24C02的多机通信 基于AT89C51+MAX7219的频率计 附带proteus仿真电路图 实际硬件电路测试通过 基于DS1302的日历时钟 基于yjwpm测试过的DS18B20仿真实例 多功能电子钟 多点温度测量 多路开关状态指示 大屏幕仿真 子电路做的一个H型电机驱动电路 字符串函数string.h应用举例 字符函数ctype.h应用举例 宏定义应用举例 定时器中断控制的独立式键盘扫描实验 定时器控制交通指示灯 定时器控制数码动态显示 定时器控制数码管动管显示 对I2C总线上挂接多个AT24C02
以下是51单片机完整的IIC读取和发送C语言程序的示例代码: ```c #include <reg52.h> sbit SDA = P2^0; //定义SDA数据线引脚 sbit SCL = P2^1; //定义SCL时钟线引脚 void delay() { int i = 1000; while(i--); } void IIC_Start() { SDA = 1; SCL = 1; delay(); SDA = 0; delay(); SCL = 0; } void IIC_Stop() { SDA = 0; SCL = 1; delay(); SDA = 1; delay(); } void IIC_Ack() { SDA = 0; delay(); SCL = 1; delay(); SCL = 0; delay(); SDA = 1; } void IIC_NAck() { SDA = 1; delay(); SCL = 1; delay(); SCL = 0; delay(); } unsigned char IIC_WriteByte(unsigned char dat) { unsigned char i; for(i=0; i<8; i++) { SDA = dat & 0x80; delay(); SCL = 1; delay(); SCL = 0; dat <<= 1; } delay(); SDA = 1; delay(); SCL = 1; delay(); i = SDA; SCL = 0; return i; } unsigned char IIC_ReadByte() { unsigned char i; unsigned char dat = 0; SDA = 1; for(i=0; i<8; i++) { SCL = 1; delay(); dat <<= 1; dat |= SDA; SCL = 0; delay(); } return dat; } void IIC_Init() { SDA = 1; SCL = 1; delay(); } void main() { unsigned char dat; IIC_Init(); IIC_Start(); IIC_WriteByte(0xA0); IIC_Ack(); IIC_WriteByte(0x00); IIC_Ack(); IIC_Stop(); IIC_Start(); IIC_WriteByte(0xA1); IIC_Ack(); dat = IIC_ReadByte(); IIC_NAck(); IIC_Stop(); while(1); } ``` 这段代码实现了51单片机通过IIC总线读取和发送数据的功能。其中,IIC_Start()函数用于产生起始信号,IIC_Stop()函数用于产生停止信号,IIC_Ack()和IIC_NAck()函数分别用于产生应答和非应答信号,IIC_WriteByte()和IIC_ReadByte()函数分别用于发送和接收一个字节的数据。在main函数中,我们首先初始化IIC总线,然后发送一个命令,接着发送一个要入的地址,再停止总线,接着再发送一个读命令,最后接收一个字节的数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值