[51单片机]

c8051F120 模拟I2C进行操作AT24c02问题求助

[复制链接]
1540|18
手机看帖
扫描二维码
随时随地手机跟帖
逛逛看看学学|  楼主 | 2016-3-10 15:21 | 显示全部楼层 |阅读模式
端口设置:
sbit sda = P3^7;
sbit scl = P3^6;
端口配置:
void Port_IO_Init()                                                                               
{
    SFRPAGE   = CONFIG_PAGE;
    XBR0      = 0x14;                             //配置UART0 (TX0-P0^0,RX0-P0^1)        UART1 (TX1-P0^2,RX1-P0^3)
        XBR1      = 0X20;                                                          //PCA(CEX0-P0^4,CEX0-P0^5),定时器2(T2-P0^6),定时器4(T4-P0^7)
          XBR2      = 0x4C;                             //定时器4 (T4EX-P0^5),交叉开关使能
        P2MDOUT   = 0x7f;
        P3MDOUT   = 0X3f;
        P0MDOUT   = 0Xff;
        P6        = 0XFF;
    P5        = 0XFF;
        P4        = 0XFF;
I2C的相关操作:
void init()
{
        sda = 1;
        delay_nus(5);
        scl = 1;
        delay_nus(5);
}

void start()
{
        scl = 0;
        delay_1us();
        sda = 1;
        delay_1us();
        scl = 1;
        delay_nus(5);
        sda = 0;
        delay_nus(5);       
}

void stop()
{
        scl = 0;
        delay_1us();
        sda = 0;
        delay_nus(5);
        scl = 1;
        delay_nus(5);
        sda = 1;
        delay_nus(5);       
}

void respons()
{
        scl = 0;
        delay_nus(5);
        sda = 0;
        delay_nus(5);
        scl = 1;
        delay_nus(5);
        scl = 0;
        delay_nus(5);
        sda = 1;
}

void write_byte(unsigned char date)
{
        unsigned char i,temp;
        temp = date;
        for(i=0;i<8;i++)
        {
                temp = temp<<1;
                scl = 0;
                delay_nus(5);
                sda = CY;
                delay_nus(5);
                scl = 1;
                delay_nus(5);
        }
        scl = 0;
        delay_nus(5);
        sda = 1;
        scl = 1;
        delay_nus(5);
}

unsigned char read_byte()
{
        unsigned char i,k;

        for(i=0;i<8;i++)
        {
                scl = 0;
                delay_nus(5);
                k =(k<<1)|sda;
                scl = 1;
                delay_nus(5);
        }
        return k;
}

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

unsigned char read_add(unsigned char address)
{
        unsigned char date;
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);
        respons();
        start();
        write_byte(0xa1);
        respons();
        date = read_byte();
        stop();
        return date;
}
我在主程序运行开始  读取at24c02    page = read_add(2);  
在某一处往地址2里写数据:        write_add(2,page);                        //往AT24C02写数据现在   读取的值都是FF
这是怎么回事啊

相关帖子

ningling_21| | 2016-3-10 15:36 | 显示全部楼层
数据没写进去,读写程序有问题,重点查I2C时序

使用特权

评论回复
逛逛看看学学|  楼主 | 2016-3-10 15:40 | 显示全部楼层
ningling_21 发表于 2016-3-10 15:36
数据没写进去,读写程序有问题,重点查I2C时序

您说的查时序,是用示波器怎么看,我是在主程序中,while(1){start}   查启动程序,  然后又while(1){stop} 查停止时序,写的时候的时序,我业用类似方法,看到的是一串方波,不知道怎么判断对错

使用特权

评论回复
JY-DX-JY| | 2016-3-10 15:45 | 显示全部楼层
你这样不行吧。你在while循环里连续写或者连续读,用示波器把完整的波形捕捉下来,和数据手册上的时序图对照。

使用特权

评论回复
ningling_21| | 2016-3-10 16:02 | 显示全部楼层
逛逛看看学学 发表于 2016-3-10 15:40
您说的查时序,是用示波器怎么看,我是在主程序中,while(1){start}   查启动程序,  然后又while(1) ...

把你的程序输出的I2C时序和标准的I2C时序对比,就知道哪里不对了

使用特权

评论回复
dirtwillfly| | 2016-3-10 17:29 | 显示全部楼层
逛逛看看学学 发表于 2016-3-10 15:40
您说的查时序,是用示波器怎么看,我是在主程序中,while(1){start}   查启动程序,  然后又while(1) ...

用示波器或者逻辑分析仪观察时序,然后和手册对比

使用特权

评论回复
大秦正声| | 2016-3-10 19:38 | 显示全部楼层
可以用硬件的i2c

使用特权

评论回复
逛逛看看学学|  楼主 | 2016-3-11 08:14 | 显示全部楼层

现在硬件的口被其他器件占用了,就模拟了一个I2C。。。

使用特权

评论回复
ningling_21| | 2016-3-11 08:30 | 显示全部楼层
逛逛看看学学 发表于 2016-3-11 08:14
现在硬件的口被其他器件占用了,就模拟了一个I2C。。。

对比波形了?

使用特权

评论回复
逛逛看看学学|  楼主 | 2016-3-11 08:34 | 显示全部楼层

还在试,读的时序应该没有问题,应该是数据没有写进去

使用特权

评论回复
逛逛看看学学|  楼主 | 2016-3-11 09:31 | 显示全部楼层

请教个问题,写一个8位数据,比如说0xa0,sda上面的数据应该是 1 0 1 0 0 0 0 0吧,我现在检查写入都是1 1 1 1 1 1 1 1,这是不是PSW寄存器 CY位没有成功读取

使用特权

评论回复
逛逛看看学学|  楼主 | 2016-3-11 09:42 | 显示全部楼层
dirtwillfly 发表于 2016-3-10 17:29
用示波器或者逻辑分析仪观察时序,然后和手册对比

请教个问题,写一个8位数据,比如说0xa0,sda上面的数据应该是 1 0 1 0 0 0 0 0吧,我现在检查写入都是1 1 1 1 1 1 1 1,这是不是PSW寄存器 CY位没有成功读取

使用特权

评论回复
ningling_21| | 2016-3-11 11:41 | 显示全部楼层
逛逛看看学学 发表于 2016-3-11 09:42
请教个问题,写一个8位数据,比如说0xa0,sda上面的数据应该是 1 0 1 0 0 0 0 0吧,我现在检查写入都是1  ...

改一下
  if((temp &0x80)==0x80)
{
   sda =1;
}
else
{
    sda =0;
}

使用特权

评论回复
datouyuan| | 2016-3-11 16:13 | 显示全部楼层
怀疑PSW寄存器 CY位没有成功读取,请参考13楼.

使用特权

评论回复
逛逛看看学学|  楼主 | 2016-3-14 09:57 | 显示全部楼层
datouyuan 发表于 2016-3-11 16:13
怀疑PSW寄存器 CY位没有成功读取,请参考13楼.

谢谢

使用特权

评论回复
lrhsx33| | 2016-3-14 10:13 | 显示全部楼层
重点看ACK,读写是不同的,一个等一个发ACK

使用特权

评论回复
逛逛看看学学|  楼主 | 2016-3-15 13:25 | 显示全部楼层
lrhsx33 发表于 2016-3-14 10:13
重点看ACK,读写是不同的,一个等一个发ACK

是的,问题解决了,主要就是ACK信号,我在读的时候省了一个NOack  结果出问题了

使用特权

评论回复
评论
吃N少年 2019-1-7 19:21 回复TA
请问在哪里省了一个ACK?我也是这个情况 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

82

帖子

2

粉丝