切换到宽版
  • 8869阅读
  • 9回复

[MSP]【请教:已解决】关于IIC协议读操作中的应答问题 [复制链接]

上一主题 下一主题
离线younges
 
发帖
2119
M币
2164
专家
7
粉丝
62
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2011-10-26
    以前在大学时候研究过iic,参照的是郭天祥的视频教程,把at24c02里面的数据读写完成之后就没深入研究了,而是作为一个子程序封装来用了。
最近研究rda5802时候参考挪用了一个论坛一坛友的代码,后来据说是伟纳的工程师放出来的代码,呵呵偏题了。
   我发现用如下的代码读at24c02时候总是出错,比如我的某个但愿存的是bcd码01,但是读出来就是03,我参考at24c02的官方pdf,然后参考如下代码段,就产生疑问了,望坛友们不吝赐教,谢谢


代码



#include <intrins.h>
#define  I2C_ACK     1
#define  I2C_NACK    0
#define uchar unsigned char
#define uint  unsigned int
//#define AT24c02
extern unsigned char  RDA_reg_data[8];
sbit SDA = P3^6;
sbit SCL = P3^7;
void I2C_start()
{
   SDA = 1;
   SCL = 1;
   _nop_();_nop_();_nop_();
   SDA = 0;
   _nop_();_nop_();_nop_();
   SCL = 0;
}
void I2C_stop()
{
   SDA = 0;
   SCL = 1;
   _nop_();_nop_();_nop_();
   SDA = 1;
   _nop_();_nop_();_nop_();
}
// 发送一个字节子程序
unsigned char I2C_write_byte(unsigned char indata)
{
    unsigned char i, ack;
    // I2C 发送8 位数据
    for (i=0; i<8; i++)
    {
        // 高在前低在后
        if (indata & 0x80)
            SDA = 1;
        else
            SDA = 0;
        // 发送左移一位
        indata <<= 1;
        _nop_();_nop_();_nop_();
        SCL = 1;
        _nop_();_nop_();_nop_();
        SCL = 0;
    }
    // 设置SDA为输入
    SDA =1;
    _nop_();_nop_();_nop_();

    // 读取从机应答状态
    SCL = 1;
    _nop_();_nop_();_nop_();

    if(SDA)       //为什么?一个是uchar一个是bit,返回一个ack值有什么意义呢???
        ack = I2C_NACK;
    else
        ack = I2C_ACK;
    SCL = 0;
    return ack;
}
//  读一个字节子程序
unsigned char I2C_read_byte(unsigned char ack)
{
    unsigned char i, out_data = 0;
    SDA = 1;  // SDA 设置输入方向


    // I2C 接收8位数据
    for(i = 8; i > 0; i--)
    {
        out_data <<= 1;
        SCL = 1;
        _nop_();_nop_();_nop_();

        // 高在前低在后
        if (SDA)
            out_data++;


        SCL = 0;
        _nop_();_nop_();_nop_();
    }


    // 主机发送应答状态
    if(ack == I2C_ACK)                       //pdf所示的时序中没有对sda进行操作啊,为什么这儿进行了,并且时序还不一致
          SDA = 0;
    else
    SDA = 1;


    _nop_();_nop_();_nop_();
    SCL = 1;
    _nop_();_nop_();_nop_();
    SCL = 0;


    return out_data;
}

问题结症是我在读多字节读操作中读完最后一个字节后主机没有向从机发送无应答信号NACK,导致错误。发送应答信号后一切正常。但是此处还有个小疑问:最后一个自己结束后我就发了stop()信号,按道理我已经读到正确值了,上述问题到底怎么得来的。

void IIC_ser_read(uchar chip_add,uchar firstadd ,uchar length ,uchar getadd,uchar *aim)
{
    I2C_start();                            //启动总线
    I2C_write_byte(chip_add & 0xfe);        //发送器件地址
    I2C_write_byte(firstadd);                //发送器件子地址
    I2C_start();                            //启动总线
    I2C_write_byte(chip_add | 0x01);        //发送器件读地址


    length -= 1;
    while(length)
    {
        aim[getadd] = I2C_read_byte(I2C_ACK);
        getadd      += 1;
        length      -= 1;
    }
   aim[getadd] = I2C_read_byte(I2C_NACK);//原来就是这个非应答信号没有,所以失败
    I2C_stop();
}


[ 此帖被younges在2011-10-30 14:05重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
离线cmheia

发帖
11646
M币
6479
专家
9
粉丝
117
只看该作者 1楼 发表于: 2011-10-26
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+4
离线ayumi7

发帖
12342
M币
2148
专家
25
粉丝
5725
只看该作者 2楼 发表于: 2011-10-27
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+4
离线younges
发帖
2119
M币
2164
专家
7
粉丝
62
只看该作者 3楼 发表于: 2011-10-27
请登录后查看
离线younges
发帖
2119
M币
2164
专家
7
粉丝
62
只看该作者 4楼 发表于: 2011-10-27
请登录后查看
离线racede

发帖
80
M币
842
专家
5
粉丝
30
只看该作者 5楼 发表于: 2011-10-27
标题
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+4
离线geniuskim
发帖
475
M币
702
专家
2
粉丝
5
只看该作者 6楼 发表于: 2011-10-27
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+4
离线jiexiao

发帖
500
M币
114
专家
11
粉丝
101
只看该作者 7楼 发表于: 2011-10-28
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+4
离线黑暗深处

发帖
349
M币
614
专家
3
粉丝
11
只看该作者 8楼 发表于: 2011-10-28
请登录后查看
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共1条打赏 ,M币+4
离线jiexiao

发帖
500
M币
114
专家
11
粉丝
101
只看该作者 9楼 发表于: 2011-10-28
请登录后查看
快速回复
限80 字节
温馨提示:欢迎交流讨论,请勿发布纯表情、纯引用等灌水帖子;以免被删除
 
上一个 下一个