EEPROM—_IIC总线编程,用按键控制IIC写入读取数据并由数码管显示

时间:2022-03-02 16:36:23

关于IIC串行总线的组成及工作原理
1.采用串行总线技术可以使系统的硬件设计大大简化,系统的体积减小,可靠性提高,同时,系统的更改和扩充极为容易。
2.常用的串行扩展总线有:IIC(Inter IC BUS)总线、单总线,SPI总线及Microwire、PLUS
3.IIC是一种串行总线,只有两根双向信号线:
一根是数据线SDA
一根是时钟线SCL
4.标准的IIC总线的数据传送有严格的时序要求
5.每个接到IIC总线上的器件都有唯一的地址

关于移位操作:
左移时最低位补0,最高位移入psw的cy位;
右移时最高位保持原数,最低位移除;

关于AT24Cxx系列的芯片
01、02、03、04、05芯片最大存储字节分别为128、256、512、1024、2048
A1、A2、A3为地址输入口;
SDA:串行地址和数据输入/输出口;
SCL:串行时钟输入,上升沿数据写入;
下降沿数据读出
wp:写保护 wp = 0,允许数据正常读写操作;
wp = 1,写保护,只读

k1保存数据
K2读取上次数据
K3数据加1
K4清零

i2c.h

#ifndef _I2C_H
#define _I2C_H

#include"reg52.h"

//typedef unsigned char uchar;

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

void At24c02Write(uchar addr,uchar dat);
uchar At24c02Read(uchar addr);

#endif


i2c.c

#include"i2c.h"

void Delay10us()
{
    uchar i,j;
    for(i=1;i>0;i--)
        for(j=2;j>0;j--);
}

void I2cStart()
{
    SDA = 1;
    Delay10us();
    SCL = 1;
    Delay10us();
    SDA =  0;
    Delay10us();
    SCL = 0;
    Delay10us();
}

void I2cStop()
{
    SDA = 0;
    Delay10us();
    SCL = 1;
    Delay10us();
    SDA = 1;
    Delay10us();
}

uchar I2cSendByte(uchar dat)
{
    uchar a = 0,b = 0;
    for(a=0;a<8;a++){
        SDA = dat>>7;
        dat = dat<<1;
        Delay10us();
        SCL = 1;
        Delay10us();
        SCL = 0;
        Delay10us();
    }
    SDA = 1;
    Delay10us();
    SCL = 1;
    Delay10us();
    while(SDA){
        b++;
        if(b == 300){
            SCL = 0;
            Delay10us();
            return 0;
        }
    }
    SCL = 0;
    Delay10us();
    return 1;
}

uchar I2cReadByte()
{
    uchar a=0,dat=0;
    SDA = 1;
    Delay10us();
    for(a=0;a<8;a++){
        SCL = 1;
        Delay10us();
        dat = dat << 1;
        dat |= SDA;
        Delay10us();
        SCL = 0;
        Delay10us();
    }
    return dat;
}

void At24c02Write(uchar addr,uchar dat)
{
    I2cStart();
    I2cSendByte(0xa0);
    I2cSendByte(addr);
    I2cSendByte(dat);
    T2cStop();
}

uchar At24c02Read(uchar addr)
{
    uchar num;
    I2cStart();
    I2cSendByte(0xa0);
    I2cSendByte(addr);
    I2cStart();
    I2cSendByte(0xa1);
    num = I2cReadByte();
    I2cStop();
    return num;
}

mian.c

#include "i2c.h"

typedef unsigned int u16;
typedef unsigned char u8;

sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;

sbit key1 = P3^0;
sbit key2 = P3^1;
sbit key3 = P3^2;
sbit key4 = P3^3;

u8 code sngduan[10]={ };
u8 num =0;
u8 spit[4] = {0};

void delay(u16 i)
{
    while(i--);
}

void keypors()
{
    if(key1 ==0){
        delay(1000);
        if(key1 == 0){
            IAt24c02Write(1,num);
        }
        while(!key1);
    }
    if(key2 ==0){
        delay(1000);
        if(key2 == 0){
            num = IAt24c02Read(1);
        }
        while(!key2);
    }
    if(key3 == 0){
        delay(1000);
        if(key3 == 0){
            num++;
            if(num>255){
                num = 0;
            }
        }
        while(!key3);
    }
    if(key4 ==0){
        delay(1000);
        if(key4 == 0){
            num = 0;
        }
        while(!key4);
    }
}

void datapors()
{
    spit[0] = sumduan[sum%10];
    spit[1] = sumduan[sum%100/10];
    spit[2] = sumduan[sum%1000/100];
    spit[3] = sumduan[sum/1000];
}

void display()
{
    u8 i;
    for(i=0;i<4;i++){
        switch(i){
            case 0:
                LSA = 0;LSB = 0;LSC = 0;break;
            case 1:
                LSA = 1;LSB = 0;LSC = 0;break;
            case 2:
                LSA = 0;LSB = 1;LSC = 0;break;
            case 3:
                LSA = 1;LSB = 1;LSC = 0;break;
        }
        P0 = spit[i];
        delay(100);
        P0 = 0x00;
    }
}

void main()
{
    while(1){
        kerpros();
        datapros();
        display();
    }
}
  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y