找回密码
 注册
搜索
查看: 937|回复: 5

[讨论] 跪求大侠指点

[复制链接]
发表于 2007-5-10 16:36:09 | 显示全部楼层 |阅读模式
一下是一个IIC通信协议程序,通过单片机P20,P21管脚模拟SDL,SCL;
从器件的地址为7位,0001100,第八位是读写位;器件只有一个寄存器是16位的。程序的目的是通过单片机的模拟端口写人内容到器件中去,但是现在出现的问题是写不进去内容。请各位大侠指点迷津,如调通会讲程序源代码和硬件电路图公布网上,供大家共享!
代码部分:
#define _I2C2_C_
#include "reg51.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "intrins.h"
#include "stdarg.h"
#include "i2c2.h"

#define  uchar unsigned char /*宏定义*/
#define  _Nop()  _nop_()
#define md118b1 0x18
#define md118b2 0x19       /*定义空指令*/

/* 常,变量定义区 */

                                                
sbit SDA=P2^0;            /*模拟I2C数据传送位*/
sbit SCL=P2^1;            /*模拟I2C时钟控制位*/
sbit PD=P2^2;
bit ack;                  /*应答标志位*/
void Start_I2c();
void Stop_I2c();
void  SendByte(uchar c);
uchar  RcvByte();
void Ack_I2c(bit a);
bit IRcvByte(uchar sla,uchar *c);

//*******************************************************
//主函数部分,程序最可能存在的问题是在初始化的过程中
//*******************************************************

main()
{   
   uchar *c;
   Start_I2c();               /*启动总线*/
   SendByte(0x18);            /*发送器件地址*/
     if(ack==1)               /*等待应答信号变成1*/
       {
              SendByte(0x3f);
              if(ack==1)            /*等待应答信号变成1*/
              {
                     SendByte(0xf0);
                     if(ack==1)         /*等待应答信号变成1*/
                     {
                     Stop_I2c();
                     }
              }
       }

       IRcvByte(0x19,c);
      
}

/*******************************************************************
                     起动总线函数               
函数原型: void  Start_I2c();  
功能:       启动I2C总线,即发送I2C起始条件.
  
********************************************************************/
void Start_I2c()
{
  SDA=1;   /*发送起始条件的数据信号*/
  _Nop();
  SCL=1;
  _Nop();    /*起始条件建立时间大于4.7us,延时*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();   
  SDA=0;   /*发送起始信号*/
  _Nop();    /* 起始条件锁定时间大于4μs*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();      
  SCL=0;   /*钳住I2C总线,准备发送或接收数据 */
  _Nop();
  _Nop();
}

/*******************************************************************
                      结束总线函数               
函数原型: void  Stop_I2c();  
功能:       结束I2C总线,即发送I2C结束条件.
  
********************************************************************/
void Stop_I2c()
{
  SDA=0;  /*发送结束条件的数据信号*/
  _Nop();   /*发送结束条件的时钟信号*/
  SCL=1;  /*结束条件建立时间大于4μs*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SDA=1;  /*发送I2C总线结束信号*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();
}

/*******************************************************************
                 字节数据传送函数               
函数原型: void  SendByte(uchar c);
功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
     此状态位进行操作.(不应答或非应答都使ack=0 假)     
     发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void  SendByte(uchar c)
{
uchar BitCnt;

for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
    {
     if((c<<BitCnt)&0x80) SDA=1;   /*判断发送位*/
       else  SDA=0;               
     _Nop();
     SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
      _Nop();
      _Nop();               /*保证时钟高电平周期大于4μs*/
      _Nop();
      _Nop();
      _Nop();         
     SCL=0;
    }
   
    _Nop();
    _Nop();
    SDA=1;               /*8位发送完后释放数据线,准备接收应答位*/
    _Nop();
    _Nop();   
    SCL=1;
    _Nop();
    _Nop();
    _Nop();
    if(SDA==1) ack=0;     
       else ack=1;        /*判断是否接收到应答信号*/
    SCL=0;
    _Nop();
    _Nop();
}

/*******************************************************************
                 字节数据传送函数               
函数原型: uchar  RcvByte();
功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
     发完后请用应答函数。  
********************************************************************/
uchar  RcvByte()
{
  uchar retc;
  uchar BitCnt;
  
  retc=0;
  SDA=1;             /*置数据线为输入方式*/
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        _Nop();           
        SCL=0;       /*置时钟线为低,准备接收数据位*/
        _Nop();
        _Nop();         /*时钟低电平周期大于4.7μs*/
        _Nop();
        _Nop();
        _Nop();
        SCL=1;       /*置时钟线为高使数据线上数据有效*/
        _Nop();
        _Nop();
        retc=retc<<1;
        if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
        _Nop();
        _Nop();
      }
  SCL=0;   
  _Nop();
  _Nop();
  return(retc);
}

/********************************************************************
                     应答子函数
原型:  void Ack_I2c(bit a);

功能:主控器进行应答信号,(可以是应答或非应答信号)
********************************************************************/
void Ack_I2c(bit a)
{
  
  if(a==0) SDA=0;     /*在此发出应答或非应答信号 */
        else SDA=1;
  _Nop();
  _Nop();
  _Nop();      
  SCL=1;
    _Nop();
    _Nop();              /*时钟低电平周期大于4μs*/
    _Nop();
    _Nop();
    _Nop();  
SCL=0;                /*清时钟线,钳住I2C总线以便继续接收*/
    _Nop();
    _Nop();   
}

/*******************************************************************
                    向无子地址器件读字节数据函数               
函数原型: bit  IRcvByte(uchar sla,ucahr *c);  
功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地
          址sla,返回值在c.
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{
   Start_I2c();                /*启动总线*/
   SendByte(sla+1);
   //SendByte(sla);          /*发送器件地址*/
     if(ack==0) return(0);
   *c=RcvByte();               /*读取数据*/
     Ack_I2c(1);               /*发送非就答位*/
  Stop_I2c();                  /*结束总线*/
  return(1);
}

[em14][em14]
【文件名】:07510@52RD_改进后的程序.doc
【格 式】:doc
【大 小】:34K
【简 介】:
【目 录】:

本帖子中包含更多资源

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

×
发表于 2007-5-14 11:54:27 | 显示全部楼层
没做过这东西,我看你最好还是仔细研究一下IIC总线协议.[em12]
点评回复

使用道具 举报

发表于 2007-5-19 21:15:30 | 显示全部楼层
鄙视没有尊严的,跪求?
点评回复

使用道具 举报

发表于 2007-8-23 17:18:49 | 显示全部楼层
是什么从器件?仔细看下它的资料  

main()
{  
   uchar *c;
   Start_I2c();               
   SendByte(0x18);         
     if(ack==1)              
       {
              SendByte(0x3f);     //这个地址是对的吗?
              if(ack==1)         
              {
                     SendByte(0xf0);
                     if(ack==1)      
                     {
                     Stop_I2c();
                     }
              }
       }
点评回复

使用道具 举报

发表于 2007-8-24 17:12:53 | 显示全部楼层
你用的是什么型号的I2C器件啊?这种通过I2C写入寄存器的器件基本上是每一次写操作完成之后都要等待一定的时间,因为器件会有一个内部写操作的时间,否则会出错的,还有写的时候要注意翻页的情况。[br]<p align=right><font color=red>+3 RD币</font></p>
点评回复

使用道具 举报

发表于 2007-8-25 16:49:17 | 显示全部楼层
是什么器件?
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2025-2-25 14:08 , Processed in 0.048520 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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