Chinaunix首页 | 论坛 | 博客
  • 博客访问: 69266
  • 博文数量: 7
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 97
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-16 18:52
文章分类

全部博文(7)

文章存档

2011年(5)

2010年(1)

2009年(1)

我的朋友

分类: 嵌入式

2011-05-13 13:30:32

/************************************************************************
*** Copyright(c) 2009,by XH Du ***
*** All right reserved. 引用请注明出处***
*** 文件名:NEC_78K0_i2c.c
*** 当前版本:1.2
*** 完成日期:2009-12-08
*** 作 者:XH Du
*** 功能描述:NEC的硬件I2C 操作
************************************************************************/
#include "macrodriver.h"
#include "NEC_78K0_system_clk.h"
#include "NEC_78K0_i2c.h"
 
static UCHAR I2CWaitDelay;
 
// **头文件中的部分内容**************************************
typedef unsigned char bool;
 
#define IICCL0_INITIALVALUE   0x00
#define IIC0_CLOCK2           0x02
#define IIC0_EXPENSION0       0x00
#define  I2C_ERR     0
#define  I2C_CRR     1
#define  I2CStart()      {STT0 = 1;}
#define  I2CStop()       {SPT0 = 1;}
#define  I2CSendByte(x)  {IIC0 = x;}
#define  I2CEightIsr()   {WTIM0 = 0;}
#define  I2CNinthIsr()   {WTIM0 = 1;}
#define  I2CRcvNoAck()   {ACKE0 = 0;}
#define  I2CRcvAck()     {ACKE0 = 1;}
#define  I2CWait()       {WREL0 = 0;}
#define  I2CCanWait()    {WREL0 = 1;}
//********************************************************
 
 
/*******************************************************************************
** Abstract:
**  This function initializes IIC0.
**
** Parameters:
**  None
**
** Returns:
**  None
**
*******************************************************************************/
void IIC0_Init(void)
{
 IICE0 = 0;  /* IIC0 disable */
 IICMK0 = 1; /* INTIIC0 disable */
 IICIF0 = 0; /* clear INTIIC0 interrupt flag */
 /* Set INTIIC0 low priority */
 IICPR0 = 1;
 /* Set clock pin for IIC0 */
 PM6 &= ~0x1;
 P6 &= ~0x1;
 /* Set data transfer I/O pin for IIC0 */
 PM6 &= ~0x2;
 P6 &= ~0x2;
 /*Set IIC0 clock*/
 IICCL0 = IICCL0_INITIALVALUE | IIC0_CLOCK2;
 IICX0 = IIC0_EXPENSION0;
 STCEN = 1; //After operation is enabled (IICE0 = 1), enable generation of a start condition without detecting a stop condition.
 IICRSV = 1;  //Disable communication reservation
 SPIE0 = 0;  //Disable generation of interrupt request when stop condition is detected 
   WTIM0 = 1;  //Interrupt request is generated at the ninth clock's falling edge.
 ACKE0 = 1;   //No auto acknowledge   
 WREL0 = 1;
 IICE0 = 1; /* IIC0 ensable */
 LREL0 = 1;  /*normal operation*/
 STT0  = 0;      //Generate no start condition   
 SPT0 = 1;
 //IICMK0 = 0;
}
/*********************************************************************
******************* I2C 等待时间处理 *********************************
*******************(定时器中调用时间比较准确)*************************
*********************************************************************/
void I2CWaitDelayProcess(void)
{
 if((I2CWaitDelay>0) && (I2CWaitDelay<=250))
  {
  I2CWaitDelay--;
  }
}
/************************************************************
*******************检测I2C总线是否忙状态 **********************
************************************************************/
bool SysI2CCheckBusy(void)
{
 I2CWaitDelay = 100;  //Wait 1S
 while((IICBSY==1) && (I2CWaitDelay>0))
  {
  NOP();
  }
 if(I2CWaitDelay<=0)  //overtime
  {
  SPT0 = 1;
  return I2C_ERR;
  }
 else
  {
  I2CWaitDelay = 100;  //Wait 1S  
  while((SPT0==1 || STT0==1) && (I2CWaitDelay>0))
   {
   NOP();
   }
  
  if(I2CWaitDelay<=0)
   {
   SPT0 = 1;
   return I2C_ERR;
   }
  else
   {
   return I2C_CRR;
   }
  }
}
/*******************************************************
********************Start I2C*****************************
*******************************************************/
bool SysI2C_Start(void)    
{
 I2CStart();   /*Generate a start condition */
 I2CWaitDelay = 100;  //Wait 1S
 while((!STD0) && (I2CWaitDelay>0))
  {
  NOP();
  }
 
 if(I2CWaitDelay<=0)  //overtime
  {
  SPT0 = 1;
  return I2C_ERR;
  }
 else
  {
  return I2C_CRR;
  }
}
/*******************************************************
********************Stop I2C*****************************
*******************************************************/
bool SysI2C_Stop(void)
{
 I2CStop();
 I2CWaitDelay = 100;  //Wait 1S
 while((!SPD0) && (I2CWaitDelay>0))
  {
  NOP();
  }
 
 if(I2CWaitDelay<=0)  //overtime
  {
  return I2C_ERR;
  }
 else
  {
  return I2C_CRR;
  }
}
/*******************************************************
**************** Wait ack and judge overtime ***************
*******************************************************/
bool SysI2CWaitAck(void)

 I2CWaitDelay = 100;  //Wait 1S
 while((!IICIF0) && (I2CWaitDelay>0))  //
  {
  NOP();
  }
 if(I2CWaitDelay<=0)  //overtime
  {
  SPT0 = 1;
  return I2C_ERR;
  }
 else
  {
  if(!ACKD0)  //not ACK
   {
   SPT0 = 1;
   return I2C_ERR;
   }
  else
   {
   IICIF0 = 0;
   return I2C_CRR;
   }
  }
}
/*******************************************************
********************Send data****************************
*******************************************************/
bool SysI2C_SendDat(UCHAR configDat)
{
 bool I2CSTATE;
 I2CSendByte(configDat);  /*Send data*/
 I2CSTATE = SysI2CWaitAck();
 return I2CSTATE;
}

/*******************************************************
**************I2C(TWI)I2C(TWI)receive data ****************
*******************************************************/
bool SysI2C_RcvDat(UCHAR *pRdDat)
{
 I2CWaitDelay = 100;  //Wait 1S
 while((!IICIF0) && (I2CWaitDelay>0))
  {
  NOP();
  }
 if(I2CWaitDelay<=0)
  {
  SPT0 = 1;
  return I2C_ERR;
  }
 else
  {
  IICIF0 = 0;
  *pRdDat = IIC0;
  return I2C_CRR;
  }
}
/*******************************************************
**********************读N个数据**************************
**** wrDAdr: write device-address 器件地址??
**** wordAdr: word address 读数据的寄存器地址??
**** pRdDat: p->read data 存放数据的指针
**** num: number 读数据的个数
*******************************************************/
bool SysI2C_Read(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pRdDat,USHORT num)
{
 UCHAR rdDAdr;
 USHORT i=0;
 rdDAdr = wrDAdr+1; //读器器件地址为写地址加1
 
 if(SysI2CCheckBusy()==I2C_ERR)
  {return I2C_ERR;}
 if(SysI2C_Start()==I2C_ERR)       /*启动I2C*/
  {return I2C_ERR;}
 if(SysI2C_SendDat(wrDAdr)==I2C_ERR)/*发写器件地址*/
  {return I2C_ERR;}
 if(SysI2C_SendDat(wordAdr)==I2C_ERR)/*发要读的寄存器地址*/
  {return I2C_ERR;}
 if(SysI2C_Start()==I2C_ERR)/*重启I2C*/
  {return I2C_ERR;}
 if(SysI2C_SendDat(rdDAdr)==I2C_ERR)/*发读器器件地址*/
  {return I2C_ERR;}
 if(TRC0 == 0)  //读
  {
  I2CRcvAck();
  while(i   {
   I2CCanWait(); 
   if(SysI2C_RcvDat(pRdDat+i))
    {i++;}
   else
    {return I2C_ERR;}
   }
  I2CRcvNoAck();
  I2CCanWait();
  i=num-1;
  if(SysI2C_RcvDat(pRdDat+i))
   {
   I2CRcvAck();
   if(SysI2C_Stop())
    {
    _delay_us(10);
    return I2C_CRR;
    }
   else
    {return I2C_ERR;}
   }
  else
   {return I2C_ERR;}
  }
 else
  {return I2C_ERR;}
}
/*******************************************************
**********************写N个数据**************************
**** wrDAdr: write device-address 器件地址??
**** wordAdr: word address 写数据的寄存器地址??
**** pRdDat: p->read data 写数据的指针
**** num: number 写数据的个数
*******************************************************/
bool SysI2C_Write(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pWrDat,UCHAR num)
{
 unsigned char i=0;
 if(SysI2CCheckBusy()==I2C_ERR)
  {return I2C_ERR;}
 if(SysI2C_Start()==I2C_ERR)       /*启动I2C*/
  {return I2C_ERR;}
 if(SysI2C_SendDat(wrDAdr)==I2C_ERR)/*发写器件地址*/
  {return I2C_ERR;}
 if(SysI2C_SendDat(wordAdr)==I2C_ERR)/*发要写的寄存器地址*/
  {return I2C_ERR;}
 if(TRC0 == 1)  //写
  {
  while(i   {
   if(SysI2C_SendDat(*(pWrDat+i)))
    {i++;}
   else
    {return I2C_ERR;}
   }
  if(SysI2C_Stop())
   {
   _delay_us(10);
   return I2C_CRR;
   }
  else
   {
   return I2C_ERR;
   }
  }
 else
  {return I2C_ERR;}
}
阅读(1227) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~