打印

help:I2C总线程序

[复制链接]
2016|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 perhapsa 于 2011-7-24 10:40 编辑

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA=P1^2;
sbit SCL=P1^1;
uchar a;
void delay()   //短延时
{
        ; ;
}
void delay1(uchar x)  //长延时
{
        uchar y,z;
        for(y=x;y>0;y--)
                for(z=100;z>0;z--) ;
}
void start()  //  开始
{
        SDA=1;
        delay();
        SCL=1;
        delay();
        SDA=0;
        delay();
        SCL=0;//
}
void stop()  //结束
{
        SDA=0;
        delay();
        SCL=1;         //
        delay();
        SDA=1;
        delay();
        SCL=0;
}
void response()     //应答
{
        SDA=0;
        delay();
        SCL=1;
        delay();
        SCL=0;
        delay();
        SDA=1;
        delay();
}
void init()  //初始化
{
        SDA=1;
        delay();
        SCL=1;
        delay();
}
void write_byte(uchar dat)  // 写数据
{
        uchar i,temp;
        temp=dat;

        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                SCL=0;
                delay();
                SDA=CY;
                delay();
                SCL=1;
                delay();
//                SCL=0;
//                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 main()
{
        init();
        start();
        write_byte(0xa0);
        response();
        write_byte(3);//数据存在第3个地址单元
        response();
        write_byte(0x55);  //写数据0x55
        response();
        stop();
        delay1(100);//         大延时

        start();
        write_byte(0xa0);
        response();
        write_byte(3);
        response();
        start();
        write_byte(0xa1);//读
        response();
        a=read_byte();  //a得不到预期的0x55这个值,调试结果都是0xFF
        stop();
        while(1);
               
}

各位前辈,我按照郭天祥的51单片机视频写的总线读写程序,自己又调试了很久,但是不如人意,本来想先放下一段时间的,但是觉得有问题还是找解答的好,知道看程序比较麻烦,就先放上来,有时间的麻烦帮我看看程序有什么问题,感激不尽!:D
(我这个帖子原本是希望那些跟我一样看过郭天祥这节视频的人给我分析一下,因为没有看过的大致看这个程序确实很费劲,好吧,我就说一下大概,就是用24C02芯片实现存储和读,我先写一个字节0x55到第3个存储单元,然后再把值通过总线读回来赋给变量a,不过调试结果a都是0xff,不是0x55,上面的位声明可以忽略不看)

相关帖子

沙发
NE5532| | 2011-7-24 09:54 | 只看该作者
谁有时间帮你这样看呢?你连啥问题都懒得说,还有人看?

使用特权

评论回复
板凳
cqcqcq0| | 2011-7-24 10:26 | 只看该作者
我也刚刚学习单片机,一起研究一下吧!你这是什么问题啊,说清楚

使用特权

评论回复
地板
perhapsa|  楼主 | 2011-7-24 10:45 | 只看该作者
你没有仔细看吧,我上面都写了注释了,只是简短了些,再说我也没说一定有人帮我看,如果真想帮忙,这个程序读懂找出问题对高手来说不过是小菜一碟,如果没涉猎过I2C总线的,那我说再多也是枉然,原谅我说话过了 2# NE5532

使用特权

评论回复
5
NE5532| | 2011-7-24 11:41 | 只看该作者
我不看程序,因为一般没时间。你注释里确实写了的。你能不能先说说调I2C的第一步是什么?

高手不代表看一眼就知道你程序错在哪里,不要把高手当神,他们经常因为一个低级错误找上几个小时。高手和新手的区别在于遇到问题的时候他们知道怎么去找。

使用特权

评论回复
6
老鱼探戈| | 2011-7-24 20:25 | 只看该作者
路过,碰到一个跟NE5532抬杠的。
“高手和新手的区别在于遇到问题的时候他们知道怎么去找。”这句话说的比较中肯

使用特权

评论回复
7
相信哥咯| | 2011-7-24 22:40 | 只看该作者
本帖最后由 相信哥咯 于 2011-7-24 22:42 编辑

我以前写的一个51的读写24c02,51读引脚前要先置1,貌似你没


org 0000h
ajmp main

main:
scl equ p2.0;
sda equ p2.1;


fs:
lcall start;
mov a,#0a0h;
lcall send;
lcall check;
jb f0,fs;
mov a,#00h;
lcall send;
lcall check;
jb f0,fs;
mov a,#03fh;
lcall send;
lcall check;
jb f0,fs;
lcall stop;
lcall delay;



fs2:
lcall start;
mov a,#0a0h;
lcall send;
lcall check;
jb f0,fs2;
mov a,#00h;
lcall send;
lcall check;
jb f0,fs2;
lcall start;
mov a,#0a1h;
lcall send;
lcall check;
jb f0,fs2;
lcall rev;
lcall nack;
lcall stop;

last:
clr p2.7;
mov p3,r2;

ajmp $;




start:
setb scl;
nop;
setb sda;
nop;
nop;
nop;
nop;
nop;
clr sda;
nop;
nop;
nop;
nop;
nop;
clr scl;
nop;
ret;


stop:
clr sda;
nop;
nop;
setb scl;
nop;
nop;
nop;
nop;
nop;
setb sda;
nop;
nop;
nop;
nop;
nop;
ret;


nack:
setb sda;
setb scl;
nop;
nop;
nop;
nop;
nop;
clr scl;
clr sda;
nop;
ret;



send:
mov r0,#08h;
wlp:rlc a
jc wr1;
sjmp wr00;
wlp1:
djnz r0,wlp;
nop;
ret;
wr1:
setb sda;
nop;
setb scl;
nop;
nop;
nop;
nop;
nop;
clr scl;
sjmp wlp1;
wr00:
clr sda;
nop;
setb scl;
nop;
nop;
nop;
nop;
nop;
clr scl;
sjmp wlp1;


rev:
mov r0,#08h;
rlp:
setb sda
setb scl;
mov c,sda;
mov a,r2;
rlc a;
mov r2,a;
clr scl;
djnz r0,rlp;
ret;

check:
setb sda;
setb scl;
clr f0;
mov c,sda;
jnc cend;
setb f0;
cend:
clr scl;
ret;

delay:mov r6,#0ffh;
d1:mov r7,#0ffh;
d2:djnz r7,d2;
djnz r6,d1;
ret;


end;

使用特权

评论回复
8
linqing171| | 2011-7-24 23:26 | 只看该作者
1 你的短延时时间是多少
2 stop后,scl为1. 建议而已。
3  response的注释为 发送应答,
4 你写完A0什么的,应该是读应答。而不应该是发送应答
5 写了0x55后,应是读应答
6 read_byte(); 之后,应该有发送 非应答。

另外,你的这个主要原因,应该是你的delay1那个大延时时间不够,或者你的小延时不够。

使用特权

评论回复
9
perhapsa|  楼主 | 2011-7-25 00:17 | 只看该作者
都谢谢各位了,花宝贵的时间帮我看程序

使用特权

评论回复
10
perhapsa|  楼主 | 2011-7-25 00:18 | 只看该作者
非常感谢,我会试一下您的思路的:handshake 8# linqing171

使用特权

评论回复
11
NE5532| | 2011-7-25 20:29 | 只看该作者
看来你还是没抓到缰啊。调I2C的第一步是调通器件ID应答。

使用特权

评论回复
12
Bonnieeast| | 2011-7-25 22:07 | 只看该作者
我也刚学习调节I2C,请各位为前辈多指点。:)

使用特权

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

本版积分规则

个人签名:当我蓦然回首,才发现生命的价值在于奉献和自我价值的统一

0

主题

9

帖子

1

粉丝