51单片机读取EEPROOM(AT24C512)程序

    选择打赏方式

main.c文件



#include<reg52.h>

extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
extern void I2CStart();
extern void I2CStop();
extern bit I2CWrite(unsigned char dat);
extern unsigned char  I2CRead(bit ack);
void E2WriteByte(unsigned int addr,unsigned char dat);
unsigned char E2ReadByte(unsigned int addr);

void main()
{
    unsigned char dat;
    unsigned char str[10];

    InitLcd1602();
    dat = E2ReadByte(0x0000);

    str[0] = (dat/100) + '0';
    str[1] = (dat/10%10) + '0';
    str[2] = (dat%10) + '0';
    str[3] = '\0';

    LcdShowStr(0,0,str);

    dat++;
    E2WriteByte(0x00000,dat);

    while(1);
}
/*读取EEPROOM中一个字节*/
unsigned char E2ReadByte(unsigned int addr)
{
    unsigned char dat;

    I2CStart();
    I2CWrite(0x50 << 1);

    I2CWrite(addr / 256);
    I2CWrite(addr % 256);
    I2CStart();
    I2CWrite((0x50 << 1) | 0x01);
    dat = I2CRead(0);
    I2CStop();

    return dat;
}
/*向EEPROOM中写入一个字节*/
void E2WriteByte(unsigned int addr,unsigned char dat)
{
    I2CStart();
    I2CWrite(0x50 << 1);
    I2CWrite(addr / 256);
    I2CWrite(addr % 256);
    I2CWrite(dat);
    I2CStop();
}

I2C.c文件

#include<reg52.h>
#include<intrins.h>

#define I2CDelay() {_nop_();_nop_();_nop_();_nop_();}
sbit I2C_SCL = P3^7;
sbit I2C_SDA = P3^6;

/*产生总线起始信号*/
void I2CStart()
{
    I2C_SDA = 1;                            //首先确保SDA,SCL都是高电平
    I2C_SCL = 1;
    I2CDelay();
    I2C_SDA = 0;                            //首先拉低SDA
    I2CDelay();
    I2C_SCL = 0;                            //再拉低SCL
}

/*产生总线停止信号*/
void I2CStop()
{
    I2C_SCL = 0;                            //首先确保SDA,SCL都是低电平
    I2C_SDA = 0;
    I2CDelay();
    I2C_SCL = 1;                            //首先拉高SCL
    I2CDelay();
    I2C_SDA = 1;                            //再拉高SDA
    I2CDelay();
}
/*I2C总线写操作,dat为待写入字节,返回值为从机应答位的值*/
bit I2CWrite(unsigned char dat)
{
    bit ack;                                //用于暂存应答位的值
    unsigned char mask;                     //用于探测字节内某一位值得掩码变量

    for(mask = 0x80; mask != 0; mask >>= 1)   //从高位到低位一次进行
    {
        if((mask & dat) == 0)               //该位的值输出到SDA上
            I2C_SDA = 0;
        else
            I2C_SDA = 1;
        I2CDelay();
        I2C_SCL = 1;                        //拉高SCL
        I2CDelay();
        I2C_SCL = 0;                        //再拉低SCL,完成一个位周期
    }

    I2C_SDA = 1;                            //8位数据发送完成后,主机释放SDA,以检测从机应答
    I2CDelay();
    I2C_SCL = 1;                            //拉高SCL
    ack = I2C_SDA;                          //读取此时的SDA值,既为从机的应答位
    I2CDelay();
    I2C_SCL = 0;                            //再次拉低SCL完成应答位,并保持住总线

    return ack;                             //返回从机应答值
}
/*I2C总线读操作*/
unsigned char  I2CRead(bit ack)
{
    unsigned char mask;
    unsigned char dat;

    I2C_SDA = 1;
    for(mask = 0x80; mask != 0; mask >>= 1)
    {
        I2CDelay();
        I2C_SCL = 1;
        if(I2C_SDA == 0)
            dat &= ~mask;
        else
            dat |= mask;
        I2CDelay();
        I2C_SCL = 0;
    }
    I2C_SDA = ~ ack;
    I2CDelay();
    I2C_SCL = 1;
    I2CDelay();
    I2C_SCL = 0;

    return dat;
}
Lcd1602.c文件 

#include<reg52.h>

#define LCD1602_DB P0
sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_E = P2^7;

/*等待液晶准备好*/
void LcdWaitReady()
{
    unsigned char sta;

    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do
    {
        LCD1602_E = 1;
        sta = LCD1602_DB;           //读取状态字
        LCD1602_E = 0;
    }
    while(sta & 0x80);              //bit7等于1表示液晶正忙,重复检测直到其等于0为止
}

/*想LCD1602液晶写入一个字节命令,cmd为待写入命令值*/
void LcdWriteCmd(unsigned char cmd)
{
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E = 1;
    LCD1602_E = 0;
}

/*向LCD1602液晶写入一字节数据,dat为待写入数据值*/
void LcdWriteDat(unsigned char dat)
{
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_E = 1;
    LCD1602_E = 0;
}

/*设置显示RAM启始地址,亦即光标位置,(x,y)为对应屏幕上的字符坐标*/
void LcdSetCursor(unsigned char x, unsigned char y)
{
    unsigned char addr;

    if(y == 0)                      //由输入的屏幕坐标计算RAM的地址
        addr = 0x00 + x;            //第一行字符地址从0x00起始
    else
        addr = 0x40 + x;            //第二行字符地址从0x40起始
    LcdWriteCmd(addr | 0x80);       //设置RAM地址
}

/*在液晶上显示字符串,(x,y)为对应屏幕上的起始坐标,str为字符串指针*/
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
    LcdSetCursor(x,y);              //设置起始地址
    while(*str != '\0')             //连续输入字符串数据,直到检测到结束符
    {
        LcdWriteDat(*str++);
    }
}

/*初始化1602液晶*/
void InitLcd1602()
{
    LcdWriteCmd(0x38);              //1602*2显示,5*7点整,8位数据接口
    LcdWriteCmd(0x0C);              //显示器开,光标关闭 
    LcdWriteCmd(0x06);              //文字不动,地址自动+1
    LcdWriteCmd(0x01);              //清屏
}




版权声明:若无特殊注明,本文为《海盗船长》原创,转载请保留文章出处。
本文链接:https://www.progr.cn/post-7.html
正文到此结束

热门推荐

发表吐槽

你肿么看?

你还可以输入 250 / 250 个字

嘻嘻 大笑 可怜 吃惊 害羞 调皮 鄙视 示爱 大哭 开心 偷笑 嘘 奸笑 委屈 抱抱 愤怒 思考 日了狗 胜利 不高兴 阴险 乖 酷 滑稽

评论信息框
可使用QQ号实时获取昵称+头像

私密评论

吃奶的力气提交吐槽中...


既然没有吐槽,那就赶紧抢沙发吧!