搜索
bottom↓
回复: 6

关于AT24c02多字节的读写,求解决?

[复制链接]

出0入0汤圆

发表于 2011-11-19 16:11:50 | 显示全部楼层 |阅读模式
IIC总线协议写的两个字节读写,用数码管显示,但不知道为什么一直读不出第二个数据,求解决。程序如下:
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P1^2;//根据板的原理图,定义相应管脚,数据线
sbit scl=P1^1;//时钟线
sbit wp=P1^0;//写保护,高电平则只能读,为低电平时,读写正常
uchar x,y;
void delay()//少少的延时
{
        _nop_();        _nop_();
        _nop_();         _nop_();
        _nop_();         _nop_();
        _nop_();        _nop_();
}
void delay1()
{
        uint a=60000;
        while(a--);               
}

void start()  //开始信号
{       
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}

void stop()   //停止
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}

void ack()  //应答,判断是否要终止发送
{
        uchar i;
        scl=1;
        delay();
        while((sda==1)&&(i<200))i++;//当sda为1且小于这个时间,表示从机向主机发出了应答信号,不用终止
        scl=0;
        delay();
}

void noack()
{
        sda=1;
        delay();
        scl=1;
        delay();
        scl=0;
        delay();
}


void iicwr_byte(uchar dat)//写入地址、数据函数
{
        uchar i;
        scl=0;
        for(i=0;i<8;i++)
                {
                        if(dat&0x80)
                                {
                                        sda=1;
                                }
                        else
                                {
                                        sda=0;
                                }
                        dat=dat<<1;
                        delay();
                        scl=1;
                        delay();
                        scl=0;
                        delay();
                }
        sda=1;//养成释放总线的习惯
        delay();
}

uchar iicre_byte()//读出数据和地址函数
{
        uchar i,dat;
        scl=0;
        delay();
        sda=1;//释放总线
        delay();
        for(i=0;i<8;i++)//每次将sda的k或一次,就将sda的数据或地址存在k中
                {
                        scl=1;//要在稳定的情况下读出数据
                        delay();
                        dat=dat<<1;       
                        if(sda)
                                {
                                        dat++;       
                                }
                        scl=0;
                        delay();
                               
                }
        return dat;
}

void init()//函数初始化
{
        wp=0;
        sda=1;//把数据总线全部释放
        delay();
        scl=1;
        delay();
}

void write_add(uchar add,uchar dat1,uchar dat2)
{
        init();
        start();
        iicwr_byte(0xae);
        ack();
        iicwr_byte(add);
        ack();
        iicwr_byte(dat1);
        ack();
        iicwr_byte(dat2);
        ack();
        stop();
}
void read_add(uchar add)
{
        init();
        start();
        iicwr_byte(0xae);
        ack();
        iicwr_byte(add);
        ack();
        start();
        iicwr_byte(0xaf);
        ack();
        x=iicre_byte();
        ack();
        y=iicre_byte();
        noack();
        stop();
}
void main()
{
        write_add(3,0x3f,0x06);
        delay1();
        read_add(3);
        delay1();
        while(1)
        {
                P0=x;
                P2=0XF7;
                delay();
                P0=y;
                P2=0xf6;
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2011-11-19 16:12:33 | 显示全部楼层
坐等解决,急急急呀。

出0入0汤圆

发表于 2011-11-23 13:47:52 | 显示全部楼层
#include<reg52.h>
#include<delay.h>
#include<intrins.h>
#include"iic.h"
#include"delay.h"
#define _Nop() _nop_()
bit ack;
void start_I2c();
void stop_I2c();
void sendbyte(uchar c);
uchar rcvbyte();
void ack_I2c(bit a);

/*启动总线函数*/
void start_I2c()
{SDA=1;
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;
_Nop();
_Nop();
}
/*结束总线函数*/

void stop_I2c()
{SDA=0;
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1;
_Nop();
_Nop();
_Nop();
_Nop();
}
/*字节数据传送函数*/
void sendbyte(uchar c)
{uchar bitcnt;
  for (bitcnt=0;bitcnt<8;bitcnt++)
  {if ((c<<bitcnt)&0x80)
    SDA=1;
   else SDA=0;
    _Nop();
        SCL=1;
    _Nop();
    _Nop();
    _Nop();
    _Nop();
        _Nop();
        SCL=0;
  }
  _Nop();
  _Nop();
  SDA=1;
  _Nop();
  _Nop();
  SCL=1;
  _Nop();
  _Nop();
  _Nop();
  if (SDA==1)
           ack=0;
  else
           ack=1;
  SCL=0;
  _Nop();
  _Nop();

}

/*字节数据接受函数*/
uchar rcvbyte()
{uchar retc;
  uchar bitcnt;
  retc=0;
  SDA=1;
  for (bitcnt=0;bitcnt<8;bitcnt++)
  {_Nop();
   SCL=0;
   _Nop();
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SCL=1;
  _Nop();
  _Nop();
  retc=retc<<1;
  if (SDA==1)  retc=retc+1;
  _Nop();
  _Nop();
  }
  SCL=0;
  _Nop();
  _Nop();
  return (retc);
}

/* 应答函数*/
void ack_I2c(bit a)
{if (a==0)
   SDA=0;
  else SDA=1;
  _Nop();
  _Nop();
  _Nop();
  SCL=1;
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SCL=0;
  _Nop();
  _Nop();
}

/*写N个字节数据
  入口地址参数:从地址sla,子地址suba,发送no字节数据是S指向的内容
   出口参数:返回1,操作成功,否则有误*/
bit nsend (uchar sla,uchar suba,uchar *s,uchar no)
{ uchar i;
  start_I2c();
  sendbyte(sla);
  if (ack==0)return(0);
    sendbyte(suba);
  if (ack==0)return(0);
  for (i=0;i<no;i++)
    {
          sendbyte(*s);
          if (ack==0)return(0);
          s++;
         }
   stop_I2c();
   return(1);
}

/*读N个字节数据
  入口地址参数:从地址sla,子地址suba,读出的内容存放到S指向的内容单元
   出口参数:返回1,操作成功,否则有误*/
bit nread(uchar sla,uchar suba,uchar *s,uchar no)
{ uchar i;
start_I2c();
  sendbyte(sla);
  if (ack==0)return(0);
    sendbyte(suba);
  if (ack==0)return(0);
   start_I2c();
   sendbyte(sla+1);
  if (ack==0) return (0);
  for (i=0;i<no-1;i++)
    {*s=rcvbyte();
      ack_I2c(0);
      s++;
     }
*s=rcvbyte();
ack_I2c(1);
stop_I2c();
return (1);
}

出0入0汤圆

发表于 2011-11-23 13:48:28 | 显示全部楼层
我写的函数  修改下直接用吧

出0入42汤圆

发表于 2011-11-23 18:09:42 | 显示全部楼层
一般都是时序的问题,你再仔细检查下就知道了,呵呵

出0入0汤圆

发表于 2013-1-7 12:29:03 | 显示全部楼层
rocky-zou 发表于 2011-11-23 13:48
我写的函数  修改下直接用吧

你好,你这个函数可以向24C02里边写入多少字节的数据,是256字节吗?有点不太懂,希望你能帮帮忙,谢过了

出0入0汤圆

发表于 2013-1-7 12:46:40 | 显示全部楼层
24C02一次只能写8个字节吧,写完后还得延迟个5ms左右等待写完成
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-18 08:05

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表