[51单片机] AT24c02读写程序输出到串口的数据总是错误的。

[复制链接]
2682|7
 楼主| coolhongjie 发表于 2015-4-26 10:44 | 显示全部楼层 |阅读模式
主要是为了测试IIC总线方式的AT24c02基本读写测试,试了好几次,每次输出到串口的数据都是错误的,把数据输出到led灯也是一样,实在找不出错误。。
main.c的程序

#include "at24c02.h"

void Com_init(void)
{
        TMOD = 0x20;
        PCON = 0x00;
        TH1 = 0xfd;
        TL1 = 0xfd;
        SCON = 0x40;
        TR1 = 1;
}

void main(void)
{
        uchar dat;
        Com_init();
        SCL = 1;
        delay();
        SDA = 1;
        delay();
        send_byte(0x00,0xf0);
        dat = read_byte(0x00);
        while(1)
        {
                SBUF = dat;
                while(!TI);
                TI = 0;
                delay_1ms(1500);
        }
}


at24c02.c的程序

#include "at24c02.h"

bit ack_bit = 0;

//-------------------仿真得出延时约为6.51US------------------------
void delay(void)
{
        _nop_();
        _nop_();
}
//-------------------非应答信号------------------------
void nack(void)
{
        SCL = 0;
        delay();
        SDA = 1;
        delay();
        SCL = 1;
        delay();
}
//-------------------1ms*del延时------------------------
void delay_1ms(uint del)
{
        uint i,j;
        for(i = 0; i < del; i++)
                for(j = 0; j < 128; j++);
}

//---------------------start------------------------------
void start(void)
{
        SDA = 1;                        //SCL高电平期间,SDA由高变低为起始信号
        SCL = 1;
        delay();
        SDA = 0;
        delay();
        SCL = 0;
        delay();
}
//---------------------stop------------------------------
void stop(void)
{
        SDA = 0;                        //SCL高电平期间,SDA由低变高为停止信号
        SCL = 1;
        delay();
        SDA = 1;
        delay();
}
//---------------------send------------------------------
void send(uchar dat)
{
        uchar i,temp;
        temp = dat;
        SCL = 0;                //SCL拉底,数据可以改变
        delay();
        for(i = 0; i < 8; i++)
        {
                temp <<= 1;                        //temp左移一位
                SDA = CY;                        //CY进位标志的值赋给SDA
                delay();
                SCL = 1;
                delay();
                SCL = 0;
                delay();
        }
        SDA = 1;                        //释放SDA
        delay();
        SCL = 1;                        //高电平,等待应答信号
        delay();
        if(SDA == 1)
                ack_bit = 1;
        else
                ack_bit = 0;
        SDA = 1;
}
//---------------------read------------------------------
uchar read(void)
{
        uchar i,dat,j;
        SCL = 0;                        //拉底,为释放SDA做准备
        delay();
        SDA = 1;                        //释放SDA
        delay();
        for(i = 0; i < 8; i++)
        {
                SCL = 1;                //高电平数据稳定
                delay();
                if(SDA == 1)
                        j = 1;
                else
                        j = 0;
                dat = dat | j;
                delay();
                SCL = 0;                //拉底,为数据改变做准备
                delay();
                dat <<= 1;                //每次左移1位
        }
        SDA = 1;                        //释放总线,等待MCU发送非应答信号
        delay();
        SCL = 1;                        //拉高,数据稳定
        delay();
       
        return dat;                        //返回dat值
}
//---------------------send_byte------------------------------
bit send_byte(uchar waddr,uchar dat)        //waddr为子地址的首地址,dat为数据
{
        start();
        send(0xa0);                //写器件地址,已经说明写位
        if(ack_bit) return 0;
        send(waddr);        //写首地址
        if(ack_bit) return 0;
        send(dat);                //写数据
        if(ack_bit) return 0;
       
        stop();
        delay_1ms(10);
       
        return 1;
}
//-------------------read_byte------------------------
uchar read_byte(uchar waddr)
{
        uchar dat;
        start();
        send(0xa0);                //伪写,目的是写入地址
        if(ack_bit) return 0;
        send(waddr);        //写首地址
        if(ack_bit) return 0;
       
        start();
        send(0xa1);                //写器件地址,读
        if(ack_bit) return 0;
        dat = read();        //获取数据
        nack();
        stop();
        delay_1ms(10);
       
        return dat;
}

下面是串口输出的结果

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
ayb_ice 发表于 2015-4-26 11:05 | 显示全部楼层
写操作是需要时间的,一般在5~20MS,查具体的芯片手册
ayb_ice 发表于 2015-4-26 11:05 | 显示全部楼层
写操作是需要时间的,一般在5~20MS,查具体的芯片手册
ayb_ice 发表于 2015-4-26 11:06 | 显示全部楼层
写操作完成前是不接受新的操作的,包括读也不接受
dirtwillfly 发表于 2015-4-26 23:00 | 显示全部楼层
调试时序最好用个逻辑分析仪看看,会很方便
ningling_21 发表于 2015-4-27 11:31 | 显示全部楼层
I2C的程序,应答处理有点问题
 楼主| coolhongjie 发表于 2015-4-28 10:43 | 显示全部楼层
ningling_21 发表于 2015-4-27 11:31
I2C的程序,应答处理有点问题

能帮我指出来吗??
ningling_21 发表于 2015-4-28 10:49 | 显示全部楼层
coolhongjie 发表于 2015-4-28 10:43
能帮我指出来吗??

你先自己判断一下AT24C02器件给应答信号没
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

8

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部