/************************************************************************
*** 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;}
}
阅读(1270) | 评论(0) | 转发(0) |