51单片机 与AT24C02通信

2019-07-16 04:25发布

用的是STC89C52RC单片机,买的LY-51S板子;A0,A1,A2接高电平,wp接地;能实现0-99s计时,就是不能实现记忆功能。
麻烦各位大虾帮帮忙,小弟不胜感激!先谢谢了!



/*************************************************
用定时器制作一个0--99s的秒表,并在数码管上显示,
把当前时间写入AT24C02;再次开机时能,从上次断电
时的时间开始计时!

*************************************************/

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit scl = P2^0;                   //串行时钟输入端
sbit sda = P2^1;                   //串行数据输入/输

出端

sbit dula = P2^2;                   //段锁存端
sbit wela = P2^3;                   //位锁存端

bit write = 0;             //写24c02的标志
uchar code table[]={                                 //0

-9数字
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
uchar sec,tcnt;
/***************5um延时**************/
void delay()         
{
        uchar tt;
        for(tt=5;tt>0;tt--);
}
/***************xms延时**************/
void delay_1ms(uchar x)                 
{
        uchar y;
        for(;x>0;x--)
        {
                for(y=110;y>0;y--);
        }               
}
/****************总线初始化***************/
void init()
{                          //将总线都拉高,以释放总线
        scl = 1;
        delay();
        sda = 1;
        delay();       
}
/****************启动信号****************/
void start()
{       
        sda = 1;               //在scl为高电平时,sda

一个下降沿启动信号
        delay();
        scl = 1;
        delay();
        sda = 0;
        delay();
}
/***************应答信号****************/
void  respons()
{                                        //scl高电平时

,sda被拉低,并且持续>4us
        uchar i;
        scl = 1;
        delay();
        while((1==sda)&&(i<255))  //如果如果从器件无

应答,
                i++;                          //延时一段

时间后,主器件默认已应答
        i = 0;   //再次应答时,i还从0开始计时,来延时
        scl = 0;
        delay();
}
/****************停止信号***************/
void stop()
{                                                //scl

高电平时,sda一个上升沿停止信号
        sda = 0;
        delay();
        scl = 1;
        delay();
        sda = 1;
        delay();       
}
/***************写一个字节*************/
void write_byte(uchar date)
{
        uchar i,temp;
        temp = date;
        for(i=0;i<8;i++)
        {
                temp = temp<<1;        //数据位一位一位的左

移到CY位
                scl = 0;                 //scl低电平

时,允许数据变化
                delay();
                sda = CY;                //从CY位一位

一位的把数据发出去
                delay();
                scl = 1;                //scl高电平时

,要求数据稳定
                delay();
        }
        scl = 0;                   //啥作用
        delay();                   //  啥作用
        sda = 1;                         //         啥作


        delay();                           // 啥作用
}
/**************读一个字节*************/
uchar read_byte()
{
        uchar i,k;
        scl = 0;
        delay();
        sda = 1;
        delay();
        for(i=0;i<8;i++)
        {
                scl = 1;
                delay();
                k = (k<<1)|sda;        //k左移一位后,与sda

与运算,一位一位的把数据读走
        scl = 0;
                delay();
        }
        delay();       
        return k;
}
/****向AT24C02指定地址写一个字节数据****/
void write_add(uchar address,uchar date)
{
        start();                           //启动
        write_byte(0xae);           //写控制字
        respons();                           //应答
        write_byte(address);   //送入一个字节的存储器

单元地址
        respons();
        write_byte(date);           //写入数据
        respons();
        stop();
}
/****从AT24C02指定地址读一个字节数据****/
uchar read_add(uchar address)
{
        uchar date;
        start();                           //启动
        write_byte(0xae);           //写入含片选单元的

写操作控制字
        respons();
        write_byte(address);   //送入一个字节的存储器

单元地址
        respons();

        start();                           //启动
        write_byte(0xaf);           //写入含片选单元的

读操作控制字
        respons();
        date = read_byte();           //
        stop();
        return date;
}
/*********数码管显示**********/
void display(uchar shi,uchar ge)
{
        dula = 0;
        P0 = table[shi];
        dula = 1;
        dula = 0;

        wela = 0;
        P0 = 0xfe;
        wela = 1;
        wela = 0;
        delay_1ms(5);

        dula = 0;
        P0 = table[ge];
        dula = 1;
        dula = 0;

        wela = 0;
        P0 = 0xfd;
        wela = 1;
        wela = 0;
        delay_1ms(5);
}
/*******************************************
                 主函数
*******************************************/
void main()
{
        init();
        sec = read_add(4);
        if(100>sec)
                sec = 0;
        TMOD = 0x01;
        TH0 = (65535-50000)/256;
        TL0 = (65535-50000)%256;
        EA = 1;
        ET0 = 1;
        TR0 = 1;
        while(1)
        {
                display(sec/10,sec%10);
                if(1==write)
                {
                        write = 0;
                        write_add(4,sec);
                }
        }
}
void timer0 () interrupt 1
{
        TH0 = (65535-50000)/256;
        TL0 = (65535-50000)%256;
        tcnt++;
        if(20==tcnt)
        {
                tcnt = 0;
                sec++;
                write = 1;
                if(100==sec)
                        sec = 0;       
        }       
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
lovezjf234
1楼-- · 2019-07-16 06:14
 精彩回答 2  元偷偷看……
yintianye
2楼-- · 2019-07-16 09:08
lovezjf234 发表于 2012-10-9 17:14
24c02是eeprom存储器,你没有写的对,那就业不能读的对,写不对有几个原因,一个是你写代码有错误,另一个 ...

我也是主要看了这两方面,可还是不对,可能是我思路有问题吧!这个是模仿郭天祥的程序,大致一样,只是把地址改了,其他地方,我再看看!谢谢!
lstcspring
3楼-- · 2019-07-16 14:07
单独调一下这个存储程序,看一时序对不
关于风的
4楼-- · 2019-07-16 16:42
感谢楼主!!!!!
255138
5楼-- · 2019-07-16 17:24
我是新人,我想问一下,at24c02在学习板上的用途是什么?
朱枫
6楼-- · 2019-07-16 21:26
 精彩回答 2  元偷偷看……

一周热门 更多>