📄 i2c.c
字号:
/**********************************************************************
* FileName: i2c.c
**********************************************************************/
#if defined(__dsPIC33F__)
#include "p33fxxxx.h"
#endif
#include "i2c.h"
void InitI2C(void)
{
// TRISAbits.TRISA2 = 0;//引脚配置
// PORTAbits.RA2 = 0;
ODCAbits.ODCA2 = 0;
ODCGbits.ODCG2 = 0;
ODCGbits.ODCG3 = 0;
OpenI2C1(35);//使能I2C模块
}
/******************************************************************************
* This function configures the I2C module for enable bit
*******************************************************************************/
void OpenI2C1(unsigned int brg)
{
I2C1BRG = brg;
I2C1CONbits.I2CEN = 1;
}
/*********************************************************************
* This routine generates acknowledge condition during master receive.
*********************************************************************/
void AckI2C1(void)
{
I2C1CONbits.ACKDT = 0;
I2C1CONbits.ACKEN = 1;
}
/*********************************************************************
* This routine generates Start condition during master mode.
*********************************************************************/
void StartI2C1(void)
{
IdleI2C1();
I2C1CONbits.SEN = 1; /* initiate Start on SDA and SCL pins */
}
/************************************************************************
* This routine provides the status whether the receive buffer is full by returning the RBF bit.
*************************************************************************/
char DataRdyI2C1(void)
{
return I2C1STATbits.RBF;
}
/************************************************************************
* This routine generates wait condition intil I2C bus is Idle.
*************************************************************************/
void IdleI2C1(void)
{
/* Wait until I2C Bus is Inactive */
while(I2C1CONbits.SEN || I2C1CONbits.PEN || I2C1CONbits.RCEN ||
I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT);
}
/************************************************************************
* This routine reads predetermined data string length from the I2C bus.
*************************************************************************/
unsigned char MastergetsI2C1(unsigned char * rdptr, unsigned int length)
{
while(length)/* Receive length bytes */
{
if(MasterReadI2C1(rdptr))return 1;/* save byte received */
rdptr++;
length--;
if(length == 0) /* If last char, generate NACK sequence */
{
I2C1CONbits.ACKDT = 1;
I2C1CONbits.ACKEN = 1;
}
else /* For other chars,generate ACK sequence */
{
I2C1CONbits.ACKDT = 0;
I2C1CONbits.ACKEN = 1;
}
while(I2C1CONbits.ACKEN == 1);/* Wait till ACK/NACK sequence is over */
}
/* return status that number of bytes specified by length was received */
return 0;
}
/***********************************************************************
* This routine is used to write out a string to the I2C bus.
* If write collision occurs,1 is sent.
* If string is written and null char reached, 0 is returned.
************************************************************************/
unsigned char MasterputsI2C1(unsigned char * wrptr, unsigned char length)
{
while(length)//transmit data until null char
{
if(MasterWriteI2C1(*wrptr) == 1)// write a byte
return 1;//return with write collison error
wrptr++;
length--;
}
return 0;
}
/******************************************************************************
* This routine reads a single byte from the I2C Bus.
* To enable master receive,RCEN bit is set.The RCEN bit is checked until it is cleared.
* When cleared,the receive register is full and it's contents are returned.
********************************************************************************/
unsigned char MasterReadI2C1(unsigned char *rdptr)
{
unsigned int wait=0;
IdleI2C1();
I2C1CONbits.RCEN = 1;
I2C1CONbits.ACKEN=0;//关应答使能
while(!DataRdyI2C1())
{
if(wait<10000) wait++ ;
else return 1;/* Time out, return number of byte/word to be read */
}
*rdptr=I2C1RCV;
I2C1STATbits.I2COV = 0;
return 0;
}
/************************************************************************
* This routine is used to write a byte to the I2C bus.
* The input parameter data is written to the I2CTRN register.
* If IWCOL bit is set,write collision has occured and 1 is returned, else 0 is returned.
*************************************************************************/
unsigned char MasterWriteI2C1(unsigned char data)
{
unsigned int wait;
IdleI2C1();//判I2C总线忙否
I2C1TRN = data;//寻址
wait=0;
while(I2C1STATbits.ACKSTAT)//数据发送,并等待从器件的应答,否就等待循环
{
wait++;
if(wait>5) return 1;
}
return 0;
}
/*********************************************************************
* This routine generates Restart condition during master mode.
*********************************************************************/
void RestartI2C1(void)
{
IdleI2C1();
I2C1CONbits.RSEN = 1; /* initiate restart on SDA and SCL pins */
while(I2C1CONbits.RSEN);
}
/*********************************************************************
* This routine generates Stop condition during master mode.
*********************************************************************/
void StopI2C1(void)
{
IdleI2C1();
I2C1CONbits.PEN = 1; /* initiate Stop on SDA and SCL pins */
}
/*********************************************************************
* This routine disables the I2C1 module by clearing the I2CEN bit in I2C1CON register.
* The MI2C1 and SI2C1 interrupts are disabled and the corresponding IF flags are cleared
*********************************************************************/
void CloseI2C1(void)
{
/* clear the I2CEN bit */
I2C1CONbits.I2CEN = 0;
/* clear the SI2C & MI2C Interrupt enable bits */
_SI2C1IE = 0;
_MI2C1IE = 0;
/* clear the SI2C & MI2C Interrupt flag bits */
_SI2C1IF = 0;
_MI2C1IF = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -