找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2956|回复: 7
收起左侧

C51单片机通过I2C对EEPROM进行页读取的问题求助

[复制链接]
ID:424091 发表于 2018-11-13 07:58 | 显示全部楼层 |阅读模式
25黑币
我在尝试移植教材上的程序时,发现在页读取EEPROM时,第9位应答位假如直接置1或置0,就可以顺利读取,但由形参传递1或0给应答位时,就只能读到一串0,这是什么原因?

应答位直接置0

应答位直接置0

应答位直接置1

应答位直接置1

应答位由形参置0或1

应答位由形参置0或1

EEPROM读取函数

EEPROM读取函数

直接置位时可以正常读取

直接置位时可以正常读取

由形参置位时读到一串0

由形参置位时读到一串0


回复

使用道具 举报

ID:411940 发表于 2018-11-13 11:02 | 显示全部楼层
你可以在论坛里面搜集一下,有很多现成的程序可以参考学习。要善用论坛的搜索功能。
回复

使用道具 举报

ID:424091 发表于 2018-11-13 12:16 | 显示全部楼层
浮念 发表于 2018-11-13 11:02
你可以在论坛里面搜集一下,有很多现成的程序可以参考学习。要善用论坛的搜索功能。

程序上我没有太大的问题,这部分程序我也是移植后再自己重新编写了的,主要就是想不明白为啥直接置位可以,用形参置位就出问题了,形参置位和直接置位有啥区别吗?
回复

使用道具 举报

ID:7485 发表于 2018-11-13 15:53 | 显示全部楼层
怎么用图形贴出来,而不用文本格式呢?别人想试一试程序还要照图抄一遍?
回复

使用道具 举报

ID:424091 发表于 2018-11-13 17:35 | 显示全部楼层
ahshmj 发表于 2018-11-13 15:53
怎么用图形贴出来,而不用文本格式呢?别人想试一试程序还要照图抄一遍?

额,好吧,我把程序列出来
回复

使用道具 举报

ID:424091 发表于 2018-11-13 17:39 | 显示全部楼层
----------------------------------------------------------------主函数
#include <reg52.h>
#define u8 unsigned char
#define u16 unsigned int

extern void Int_Lcd();
extern void Lcd_Show(u8 x,u8 y,u8 *set);
extern void EE_Read(u8 *buf,u8 addr,u8 len);
extern void EE_Write(u8 *buf,u8 addr,u8 len);

void Str_Convert(u8 *str,u8 *src,u8 len);

void main()
{
        u8 buf[5]={5,2,8,6,1};
        u8 str[20];
       
        Int_Lcd();
//        EE_Write(buf,0x00,sizeof(buf));              //EEPROM写入
        EE_Read(buf,0x00,sizeof(buf));          //EEPROM读取
        Str_Convert(str,buf,sizeof(buf));       //字符串转化函数
        Lcd_Show(0,0,str);                      //1cd1602显示
        while(1);
}

void Str_Convert(u8 *str,u8 *src,u8 len)
{
        u8 tem;
        while(len--)
        {
                tem=*src>>4;
                if(tem<=9)
                        *str++=tem+'0';
                else
                        *str++=tem-10+'a';
                tem=*src&0x0f;
                if(tem<=9)
                        *str++=tem+'0';
                else
                        *str++=tem-10+'a';
                *str++=' ';
                src++;
        }
}
----------------------------------------------------------------LCD1602
#include <reg52.h>
#define u8 unsigned char
#define u16 unsigned int
#define LCD_DB P0

sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
       
void LCD_Wait_Ready()
{
        u8 sta;

        LCD_DB=0xff;
        LCD_RS=0;
        LCD_RW=1;
        do
        {
                LCD_E=1;
                sta=LCD_DB;
                LCD_E=0;
        }
        while(sta & 0x80);
}

void LCD_Write_Cmd(u8 cmd)
{
        LCD_Wait_Ready();
        LCD_RS=0;
        LCD_RW=0;
        LCD_DB=cmd;
        LCD_E=1;
        LCD_E=0;
}

void LCD_Write_Dat(u8 dat)
{
        LCD_Wait_Ready();
        LCD_RS=1;
        LCD_RW=0;
        LCD_DB=dat;
        LCD_E=1;
        LCD_E=0;
}

void Lcd_Set_Cursor(u8 x,u8 y)
{
        u8 addr;
        if(y==0)
                addr=0x00+x;
        else
                addr=0x40+x;
        LCD_Write_Cmd(addr | 0x80);
}

void Lcd_Show(u8 x,u8 y,u8 *str)
{
        Lcd_Set_Cursor(x,y);
        while(*str!='\0')
        {
                LCD_Write_Dat(*str++);
        }
}

void Int_Lcd()
{
        LCD_Write_Cmd(0x38);
        LCD_Write_Cmd(0x0c);
        LCD_Write_Cmd(0x06);
        LCD_Write_Cmd(0x01);
}
----------------------------------------------------------------I2C
#include <reg52.h>
#include <intrins.h>
#define u8 unsigned char
#define u16 unsigned int

sbit SCL=P2^1;
sbit SDA=P2^0;
sbit LED1=P0^0;
sbit LED2=P0^1;

void Dealy()
{
        u8 i;
       
        for(i=0;i<10;i++)
                _nop_();
}

void I2C_Start()
{
        SDA=1;
        SCL=1;
        Dealy();
        SDA=0;
        Dealy();
        SCL=0;
        Dealy();
}

void I2C_Stop()
{
        SCL=0;
        SDA=0;
        Dealy();
        SCL=1;
        Dealy();
        SDA=1;
        Dealy();
}

bit I2C_Write(u8 dat)         //I2C写入
{
        bit ack;
        u8 mask;
       
        for(mask=0x80;mask>0;mask>>=1)
        {
                if((mask & dat)==0)
                        SDA=0;
                else
                        SDA=1;
                Dealy();
                SCL=1;
                Dealy();
                SCL=0;
                Dealy();
        }
        SDA=1;
        Dealy();
        SCL=1;
        ack=SDA;
        Dealy();
        SCL=0;
        Dealy();
        return (~ack);
}

u8 I2C_Read(bit ack)         //I2C读取
{
        u8 dat,i;
       
        SDA=1;
        Dealy();             //延时10us
        for(i=0;i<8;i++)
        {
                SCL=1;
                Dealy();
                dat<<=1;
                dat |= SDA;
                Dealy();
                SCL=0;
                Dealy();
        }
        SDA=ack;     //SDA由形参ack控制
        Dealy();
        SCL=1;
        Dealy();
        SCL=0;
        Dealy();
        return dat;
}

u8 I2C_ReadACK()
{
        u8 dat,i;
       
        SDA=1;
        Dealy();         //延时10us
        for(i=0;i<8;i++)
        {
                SCL=1;
                Dealy();
                dat<<=1;
                dat |= SDA;
                Dealy();
                SCL=0;
                Dealy();
        }
        SDA=0;      //SDA直接置0
        Dealy();
        SCL=1;
        Dealy();
        SCL=0;
        Dealy();
        return dat;
}

u8 I2C_ReadNAK()
{
        u8 dat,i;
       
        SDA=1;
        Dealy();
        for(i=0;i<8;i++)
        {
                SCL=1;
                Dealy();
                dat<<=1;
                dat |= SDA;
                Dealy();
                SCL=0;
                Dealy();
        }
        SDA=1;       //SDA直接置1
        Dealy();
        SCL=1;
        Dealy();
        SCL=0;
        Dealy();
        return dat;
}
----------------------------------------------------------------EEPROM
#include <reg52.h>
#define u8 unsigned char
#define u16 unsigned int

extern void I2C_Start();
extern void I2C_Stop();
extern bit I2C_Write(u8 dat);
extern bit I2C_Read(bit ack);
extern u8 I2C_ReadACK();
extern u8 I2C_ReadNAK();

void EE_Read(u8 *buf,u8 addr,u8 len)       //EEPROM读取,len读取长度
{
        do
        {
                I2C_Start();
                if(I2C_Write(0x50<<1))
                        break;
                I2C_Stop();
        }
        while(1);
        I2C_Write(addr);            //写入读取的起始地址
        I2C_Start();
        I2C_Write((0x50<<1)|0x01);
        while(len>1)
        {
                *buf++=I2C_Read(0);       //应答位置0
//                *buf++=I2C_ReadACK();
                len--;
        }
        *buf=I2C_Read(1);           //应答位置1
//        *buf=I2C_ReadNAK();
        I2C_Stop();
}

void EE_Write(u8 *buf,u8 addr,u8 len)       //EEPROM写入
{
        while(len>0)
        {
                do
                {
                        I2C_Start();
                        if(I2C_Write(0x50<<1))
                                break;
                        I2C_Stop();
                }
                while(1);
                I2C_Write(addr);
                while(len>0)
                {
                        I2C_Write(*buf++);
                        len--;
                        addr++;
                        if((addr&0x07)==0)
                                break;
                }
                I2C_Stop();       
        }
}
回复

使用道具 举报

ID:424091 发表于 2018-11-13 22:11 | 显示全部楼层
ahshmj 发表于 2018-11-13 15:53
怎么用图形贴出来,而不用文本格式呢?别人想试一试程序还要照图抄一遍?

大佬求帮忙看看
回复

使用道具 举报

ID:111634 发表于 2018-11-14 08:23 | 显示全部楼层
实例49  读写AT24C02
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表