打印
[51单片机]

AT24c02读写程序输出到串口的数据总是错误的。

[复制链接]
2321|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
主要是为了测试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 | 只看该作者
写操作完成前是不接受新的操作的,包括读也不接受

使用特权

评论回复
5
dirtwillfly| | 2015-4-26 23:00 | 只看该作者
调试时序最好用个逻辑分析仪看看,会很方便

使用特权

评论回复
6
ningling_21| | 2015-4-27 11:31 | 只看该作者
I2C的程序,应答处理有点问题

使用特权

评论回复
7
coolhongjie|  楼主 | 2015-4-28 10:43 | 只看该作者
ningling_21 发表于 2015-4-27 11:31
I2C的程序,应答处理有点问题

能帮我指出来吗??

使用特权

评论回复
8
ningling_21| | 2015-4-28 10:49 | 只看该作者
coolhongjie 发表于 2015-4-28 10:43
能帮我指出来吗??

你先自己判断一下AT24C02器件给应答信号没

使用特权

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

本版积分规则

2

主题

8

帖子

0

粉丝