打印

一个EEPROM的程序,呼叫大神~~~~~~~

[复制链接]
1999|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ygdmx|  楼主 | 2014-7-31 13:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#define uchar unsigned char
sbit sda=P2^1;
sbit scl=P2^0;
uchar a;
void delay()
{ ;; }
void start()  //开始信号
{       
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}

void stop()   //停止
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}

void respons()  //应答
{
        uchar i;
        scl=1;
        delay();
        while((sda==1)&&(i<250))i++;
        scl=0;
        delay();
}

void init()
{
        sda=1;
        delay();
        scl=1;
        delay();
}

void write_byte(uchar date)
{
        uchar i,temp;
        temp=date;


        for(i=0;i<8;i++)
        {
               
                scl=0;
                delay();
              temp=temp<<i;
               if(temp&0x80=1) sda=1;
               else  sda=0;
                scl=1;
                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;
                scl=0;
                delay();       
        }
        return k;
}

void delay1(uchar x)
{
        uchar a,b;
        for(a=x;a>0;a--)
         for(b=100;b>0;b--);
}

void write_add(uchar address,uchar date)
{
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);
        respons();
        write_byte(date);
        respons();
        stop();
}

uchar read_add(uchar address)
{
        uchar date;
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);
        respons();
        start();
        write_byte(0xa1);
        respons();
        date=read_byte();
        stop();
        return date;
}

void main()
{
        init();
        write_add(23,0xaa);
        delay1(100);
        P1=read_add(23);
        while(1);
}
这是一个写和读AT24C02的程序,把aa写到AT24C02,再读回来在P1口接的8个LED显示出来,但是调了好就,LED死活不亮,好郁闷~~~~~,会不会是我在时序的的一些延时没调好,都不知怎么调了,求大神指教~~~

相关帖子

沙发
peter_wjp| | 2014-7-31 14:38 | 只看该作者
1. 不知道LZ用的什么MCU,时序里延时太短了,建议增大。
2. 这段程序里temp每次都会重新赋值,而且左移的并非是1而是变量i,这样肯定是有问题的。

               temp=temp<<i;
               if(temp&0x80=1) sda=1;
               else  sda=0;
                scl=1;
                delay();
   比如我现在传递的是10011001,那么
   第一次循环: temp=10011001,左移0位
   第二次循环: temp=00110010,左移1位,然后发送最高位
   第三次循环: temp=11001000 (00110010<<2) 然后发送最高位,这个时候就出问题了。 因为此时实际上应该为01100100  
   
所以 如果使用重新赋值移位,建议使用sda=CY方式。固定移位为1.
如果使用变量i移位,那么就不应该重新赋值。

3. 时序里最好每次结束都要将scl=0,保证不会影响到下一次通讯。

使用特权

评论回复
板凳
peter_wjp| | 2014-7-31 14:44 | 只看该作者
还有就是
if(temp&0x80=1) sda=1;
这样keil也不报错?
应该是if((temp&0x80)==1)  sda=1;
=是赋值 ==是判断

使用特权

评论回复
地板
ygdmx|  楼主 | 2014-7-31 14:50 | 只看该作者
peter_wjp 发表于 2014-7-31 14:44
还有就是
if(temp&0x80=1) sda=1;
这样keil也不报错?

噢噢~~谢谢提醒,我又粗心大意犯错了

使用特权

评论回复
5
ningling_21| | 2014-7-31 15:30 | 只看该作者
ygdmx 发表于 2014-7-31 14:50
噢噢~~谢谢提醒,我又粗心大意犯错了

程序的问题太多了,可以改一个别人写好的程序先试试....

使用特权

评论回复
6
ygdmx|  楼主 | 2014-7-31 15:35 | 只看该作者
peter_wjp 发表于 2014-7-31 14:38
1. 不知道LZ用的什么MCU,时序里延时太短了,建议增大。
2. 这段程序里temp每次都会重新赋值,而且左移的并 ...

谢谢指点,我使用的是51单片机,你指出来的问题我看懂了,关于在时序里的延时,我晚上下班回去调大一点试试:loveliness:

使用特权

评论回复
7
ayb_ice| | 2014-7-31 15:52 | 只看该作者
发送要先执行
if(temp&0x80=1) sda=1;

temp=temp<<i;


使用特权

评论回复
8
ayb_ice| | 2014-7-31 15:54 | 只看该作者
本帖最后由 ayb_ice 于 2014-7-31 15:57 编辑
peter_wjp 发表于 2014-7-31 14:44
还有就是
if(temp&0x80=1) sda=1;
这样keil也不报错?

“应该是if((temp&0x80)==1)  sda=1;”
这样也是错的

应该
f(temp & 0x80)  sda=1;”


f((temp & 0x80)  == 0x80) sda=1;”


f((temp & 0x80)  != 0x00) sda=1;”

使用特权

评论回复
9
peter_wjp| | 2014-7-31 16:04 | 只看该作者
ayb_ice 发表于 2014-7-31 15:54
“应该是if((temp&0x80)==1)  sda=1;”
这样也是错的

谢谢指点 顺着错误写下来了

使用特权

评论回复
10
ygdmx|  楼主 | 2014-7-31 16:11 | 只看该作者
ayb_ice 发表于 2014-7-31 15:54
“应该是if((temp&0x80)==1)  sda=1;”
这样也是错的

嗯嗯~~明白了,temp&0x01得出来的是一个16进制的数,所以不能用=1来表示是吗,还有个问题,关于时序里的延时,我是不是应该一点一点来加大或者减少来调啊:)

使用特权

评论回复
11
ayb_ice| | 2014-7-31 16:13 | 只看该作者
ygdmx 发表于 2014-7-31 16:11
嗯嗯~~明白了,temp&0x01得出来的是一个16进制的数,所以不能用=1来表示是吗,还有个问题,关于时序里的 ...

调试的时候可以延时大一点,通过了再降下去

使用特权

评论回复
12
ygdmx|  楼主 | 2014-7-31 16:17 | 只看该作者
ayb_ice 发表于 2014-7-31 16:13
调试的时候可以延时大一点,通过了再降下去

好的,谢谢:)

使用特权

评论回复
13
ygdmx|  楼主 | 2014-7-31 16:23 | 只看该作者
ningling_21 发表于 2014-7-31 15:30
程序的问题太多了,可以改一个别人写好的程序先试试....

好的,努力学习中~~~~~

使用特权

评论回复
14
ycbx| | 2014-7-31 17:50 | 只看该作者
楼主 有示波器吗 ?
可以用示波器对照 官方文档 调程序即可

使用特权

评论回复
15
NWPU_CHEN| | 2014-7-31 21:52 | 只看该作者
ygdmx 发表于 2014-7-31 16:11
嗯嗯~~明白了,temp&0x01得出来的是一个16进制的数,所以不能用=1来表示是吗,还有个问题,关于时序里的 ...

你temp&0x80,取的是第八位,当然不能用1来判断了,temp&0x01就可以用1来判断,因为它取得temp的第一位,C语言基础知识有待加强,位操作是最基本的东西,基础不牢固,自己永远也看不出错误,加油

使用特权

评论回复
16
ygdmx|  楼主 | 2014-7-31 22:39 | 只看该作者
NWPU_CHEN 发表于 2014-7-31 21:52
你temp&0x80,取的是第八位,当然不能用1来判断了,temp&0x01就可以用1来判断,因为它取得temp的第一位, ...

共勉!加油!

使用特权

评论回复
17
pwdzsj| | 2014-8-1 12:31 | 只看该作者
可以先单步调试,看看读出来的数据对不对。

使用特权

评论回复
18
ygdmx|  楼主 | 2014-8-1 13:22 | 只看该作者
pwdzsj 发表于 2014-8-1 12:31
可以先单步调试,看看读出来的数据对不对。

你说的单步调试是通过什么来调试,可以读出数据来?:)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

15

帖子

0

粉丝