Juxey 2021-10-06 16:28 采纳率: 0%
浏览 47

C51单片机I2C总线与E2PROM实现简易数码管计数断电保护功能问题,求指点QAQ

可以正常按键计数,通过P0,P2计数,但数据进不去24c01c中,或者进去了但读取错误,调试了好多天,人都麻了,有没有大兄弟能指点一下,不胜感激。。
仿真图如下图:

img


总程序如下:

#include "reg51.h" 

typedef unsigned int uint;      //对数据类型进行声明定义
typedef unsigned char uchar;

sbit BUT=P1^7;
sbit SCK=P3^3;
sbit SDA=P3^4;
sbit BUT1=P1^0;
sbit BUT2=P1^1;


uchar code num[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极段码
uchar  g;
uchar  s;


void Delay()
{
    uchar a,b;
    for(b=1;b>0;b--)
        for(a=2;a>0;a--);
}
    
void display()
{
    if(BUT==0)
    {
        g++;
        while(BUT==0);
    }
    if(g==10)
    {
        g=0;
        s++;
    }
    P2=num[g];
    if(s==10)
        s=0;
    P0=num[s];    
}

void I2cStart()
{
    SDA=1;
    SCK=1;
    Delay();
    SDA=0;
    Delay();
    SCK=0;                    
}

void I2cStop()
{    
    SCK=0;
    SDA=0;
    Delay();
    SCK=1;
    Delay();
    SDA=1;
    Delay();        
}


bit I2cSendByte(uchar dat)
{
    uchar a=0,b=0;
    bit ack;        
    for(a=0;a<8;a++)//要发送8位,从最高位开始
    {
        SDA=dat>>7;     //起始信号之后SCL=0,所以可以直接改变SDA信号
        dat=dat<<1;
        Delay();
        SCK=1;
        Delay();
        SCK=0;        
    }
    SDA=1;
    Delay();
    SCK=1;

    ack=SDA;
    Delay();
    SCK=0;
    return(~ack);

//    while(SDA)//等待应答,也就是等待从设备把SDA拉低
//    {
//        b++;
//        if(b>200)     //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
//        {
//            SCK=0;
//            Delay();
//            return 0;
//        }
//    }
//    SCK=0;
//    Delay();
//     return 1;        
}


uchar I2cReadByte()
{
    uchar a,dat;
    SDA=1;            //确保主机释放sda    
    for(a=0;a<8;a++)//接收8个字节
    {
        Delay();
        SCK=1;
        dat<<=1;
        dat|=SDA;
        Delay();
        SCK=0;
    }
    SDA=1;
    Delay();
    SCK=1;
    Delay();
    SCK=0;
    return dat;        
}


void At24c02Write(uchar addr,uchar dat)
{
    I2cStart();
    I2cSendByte(0xa0);//发送写器件地址
    I2cSendByte(addr);//发送要写入内存地址
    I2cSendByte(dat);    //发送数据
    I2cStop();
}


uchar At24c02Read(uchar addr)
{
    uchar n;
    I2cStart();
    I2cSendByte(0xa0); //发送写器件地址
    I2cSendByte(addr); //发送要读取的地址
    I2cStart();
    I2cSendByte(0xa1); //发送读器件地址
    n=I2cReadByte(); //读取数据
    I2cStop();
    return n;    
}


void main()
{                
    uchar r=51;
    r=At24c02Read(0x01);
    P2=num[r%10];
    P0=num[r/10];
    while(1)
    {
         display();
        Delay();
        r=10*s+g;
        At24c02Write(0x01,r);                    
    }
}    


  • 写回答

1条回答 默认 最新

  • 老皮芽子 2021-10-07 19:34
    关注

    可能是ack信号处理的不对,仔细看看iic 读写中ack部分怎么处理

    评论

报告相同问题?

问题事件

  • 创建了问题 10月6日

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境