免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1430 | 回复: 0
打印 上一主题 下一主题

NEC I2C Driver [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-21 08:41 |只看该作者 |倒序浏览
/************************************************************************
*** 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<num-1)
   {
   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<num)
   {
   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;}
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP