打印

求肋,为什么读不出I2C器件数据,麻烦各位帮忙看一看程序

[复制链接]
2803|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Tohg|  楼主 | 2009-5-21 23:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules

#define uchar unsigned char
#define clearbit( MSKN_REG, MASK )   (MSKN_REG &= ~MASK)        // Clear Bit Mask(s) 
#define setbit( MSKN_REG, MASK )    (MSKN_REG |= MASK)           // Set Bit Mask(s) 
#define AddRd 0x81 //Read Address
#define sda 0x20
#define scl 0x80

unsigned char Reg_dat[2]={0,0};
unsigned char E2P_dat[2]={0,0};
unsigned char txbuf[2]={0,0};
BYTE F_ACK=0;

/**/
void uDelay()
{;;;}
 void mDelay(unsigned int j)//A normal delay
 {
  unsigned int i;
  for(;j>0;j--)
     {
      for(i=0;i<63;i++)
         {;}
      }
  }

void Start(void)
  {
   setbit(PRT1DR,sda);           //置Sda为高
   setbit(PRT1DR,scl);           //置scl为高
   uDelay();uDelay();
   clearbit(PRT1DR,sda);         //sda为低 
   uDelay();
   clearbit(PRT1DR,scl);
  }
  
    //stop IIC
void Stop(void)
  {
   clearbit(PRT1DR,sda);          //sda为低 
   uDelay();      
   setbit(PRT1DR,scl);           //置scl为高
   uDelay();uDelay();
   setbit(PRT1DR,sda);           //sda为高
   uDelay();uDelay();
   clearbit(PRT1DR,scl);         
   uDelay();
   setbit(PRT1DR,scl);

   }
  /* void reposion()
   {
           unsigned int i;
           clearbit(PRT1DR,scl);
        uDelay();
        setbit(PRT1DR,sda);           //准备接收应答
        uDelay();
        setbit(PRT1DR,scl);
        uDelay();uDelay();
        if(((PRT1DR&sda))&&i<2500){i++; F_ACK=0;}         //判断I2C设备有应答则置ACK为1;
        else F_ACK=1;
        clearbit(PRT1DR,scl);
        uDelay();
   }*/
 //ack IIC
   void Ack(void)
   {
    clearbit(PRT1DR,sda);       //sda为低 
    uDelay();
    setbit(PRT1DR,scl);        //置scl为高
    uDelay();uDelay();
    clearbit(PRT1DR,scl);      //scl为低 
    uDelay();
    }
//unack IIC
    void NoAck(void)
    {
     setbit(PRT1DR,sda);        //sda为高 
     uDelay();
     setbit(PRT1DR,scl);         //置scl为高
     uDelay();uDelay();
     clearbit(PRT1DR,scl);       //scl为低
     uDelay();
     }
 void i2c_init()
 {
    setbit(PRT1DR,sda);
    uDelay();uDelay();
    setbit(PRT1DR,scl);
    uDelay();uDelay();
 }
/**/ 
void Send(unsigned char Data,unsigned char n)

    unsigned int i;
    unsigned char BitCounter;
    unsigned char temp;
    BitCounter=n;
do
{
    temp=Data;
    clearbit(PRT1DR,scl);
    uDelay();uDelay();
    if((temp&0x80)==0x80) setbit(PRT1DR,sda);
        
    else           clearbit(PRT1DR,sda);  
        
        setbit(PRT1DR,scl);  //保持数据
        temp=Data<<1;
        Data=temp;
        BitCounter--;
}
while(BitCounter);
          uDelay();
        clearbit(PRT1DR,scl);
        uDelay();
        setbit(PRT1DR,sda);          //准备接收应答
        uDelay();
        setbit(PRT1DR,scl);
        uDelay();uDelay();
        if((PRT1DR&sda)&&(i<250)){i++; F_ACK=0;}         //判断I2C设备有应答则置ACK为1;
        else F_ACK=1;
        clearbit(PRT1DR,scl);
        uDelay();
        setbit(PRT1DR,sda);
        uDelay();
      }
unsigned char Read(void)
  {
   unsigned char temp=0;
   unsigned char temp1=0;
   unsigned char BitCounter=8;
   setbit(PRT1DR,sda);
   do
     {
      clearbit(PRT1DR,scl);
      uDelay();uDelay();
      setbit(PRT1DR,scl);               //准备接收数据
      uDelay();uDelay();
      if(PRT1DR&sda)   temp=temp|0x01;      //接收1
         
      else             temp=temp&0xfe;      //接收0
      if(BitCounter-1)
         {
          temp1=temp<<1;
          temp=temp1;
          }
          BitCounter--;
         }
    while(BitCounter);
    return(temp);
  }
  /**/
  void Sensor_reset()          //器件重置
  {
      Start();
    Send(0x40,8);
    Send(0xfe,8);
    uDelay();
    clearbit(PRT1DR,scl); 
  }
  /**/
  BYTE WrToSensor(unsigned char AddWr,unsigned char com)
      {
       unsigned char i;
     //  unsigned char *PData;
           Start();
           Send(AddWr,8);   //Write Address
           Send(com,8);    //Write Data
           Stop();
           mDelay(20); 
           if(F_ACK) return 1;
           else         return 0;
       }
       /**/
  int  RdFromSensor()
      {
       int temp;
       int temp1,temp2;//,*PData;
           Start(); 
           Send(0x40,8);     //写器件地址
           uDelay();
           Send(0xf1,8);     //写入命令
           uDelay();
           Start();
           Send(0x41,8);             //发送命读写命令
           mDelay(80);
           temp1=Read();           // Read  two Data
           Ack();
          // uDelay();
           temp2=Read();
           mDelay(5);
           clearbit(PRT1DR,scl);      //钳住总线
           NoAck();
           Stop();
           temp=(temp1<<8)|(temp2&0x00ff);
           //temp=temp1+temp2;
           return temp;
         //  }
      }
/**/
    /*BYTE ReadRegistor(unsigned char Reg_dat[])
    {
        unsigned char i;
        unsigned char *PData;
        PData=Reg_dat;
        for(i=0;i<2;i++)
        {
            Start();
            Send(0x80,8);//Ack();
            Send(0xE3,8);//Ack();
            mDelay(5);
            Start();
            Send(0x81,8);
            *(PData+i)=Read();
            clearbit(PRT1DR,scl);
            NoAck();
            Stop();
            if(F_ACK) return 1;
            else      return 0;
        }
    }*/
    /**/
/* int ReadE2prom(unsigned char addr,unsigned char add)
    {
         int temp;
         int temp1,temp2;
        unsigned char i;
        //unsigned char *PData;
        //PData=E2P_dat;
    //    for(i=0;i<2;i++)
    //    {
            Start();
            Send(0x40,8);
            uDelay();
            Send(0xfa,8);
            uDelay();
            Send(addr,8);
            Send(add,8);
            mDelay(10);
            Start();
            Send(0x41,8);
            temp1=Read(); Ack();
            temp1=Read(); 
            mDelay(5);
            clearbit(PRT1DR,scl);
            NoAck();
            Stop();
            temp=temp1+temp1;
            return temp;
    //    }
    }*/
      
void main()
{
    BYTE  f_ack,r_ack,E_ack;
    uchar temp,E_dat,E_temp,rx_dat;//,tx_temp;
    unsigned int Result=0,tx_temp;
    DAC8_1_Start(DAC8_1_FULLPOWER);
    DAC8_1_WriteStall(254);
    i2c_init();
    Sensor_reset();    
    mDelay(500);
    DAC8_1_WriteStall(0);
    mDelay(100);
    while(1)
    {
    F_ACK=0;
    DAC8_1_WriteStall(0);
    //WrToSensor(0x40,0xf1); 
    //Stop();
    mDelay(50);
    Result=RdFromSensor();
    //if(F_ACK) ;DAC8_1_WriteStall(254);
    if((Result-tx_temp)!=0) 
    DAC8_1_WriteStall(Result);
    //else DAC8_1_WriteStall(254);
    tx_temp=Result;
    mDelay(5);
    }
}
沙发
ni_labview| | 2009-5-22 10:39 | 只看该作者

楼主我看到这样一点问题

1.你用I/O模拟I2C总线要注意SDA线要有读写两个方向,对于PSOC来说读写某个I/O要改变其口寄存器DM0,DM1,DM2数值才能实现I/O口输入输出切换,我在程序中没见到。
2.既然你用P1.5,P1.7作为I2C总线,为何不用I2CHW或I2CM模块,版内也有例子,更简单可靠,不用自己写那么麻烦的函数。

使用特权

评论回复
板凳
Tohg|  楼主 | 2009-5-22 15:42 | 只看该作者

我是将P1.5,P1.7设置为PULL UP

我是将P1.5,P1.7设置为PULL UP,再请教怎样才能读写I/O寄存器DM0、DM1、DM2的数值进行I/O切换呢

使用特权

评论回复
地板
ni_labview| | 2009-5-22 22:05 | 只看该作者

参照此贴即可明白,楼主请看

在主题查找中查找如下即可看到你想要的:

比如对P1_1,在不同时刻进行输入输出切换

使用特权

评论回复
5
ni_labview| | 2009-5-22 22:13 | 只看该作者

在这个地方查找

使用特权

评论回复
6
Tohg|  楼主 | 2009-5-22 23:06 | 只看该作者

非常感谢

非常感谢

使用特权

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

本版积分规则

14

主题

28

帖子

0

粉丝