📄 appi2c.c
字号:
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition received
if ( WriteI2C( addressh ) ){ // write word address for EEPROM
return ( -3 ); // set error for write collision
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition received
if ( WriteI2C( addressl ) ){ // write word address for EEPROM
return ( -3 ); // set error for write collision
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition received
if ( WriteI2C( data ) ){ // data byte for EEPROM
return ( -3 ); // set error for write collision
}
}
else{
return ( -2 ); // return with Not Ack error condition
}
}
else{
return ( -2 ); // return with Not Ack error condition
}
}
else{
return ( -2 ); // return with Not Ack error condition
}
}
IdleI2C(); // ensure module is idle
StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN ); // wait until stop condition is over
if ( PIR2bits.BCLIF ){ // test for bus collision
return ( -1 ); // return with Bus Collision error
}
return ( 0 ); // return with no error
}
*/
//2. Page write from external RAM
//When applying this function, attention should be paid to guarantee the low 5 bits of address to be 0b00000
INT8U EEPageWriteA(INT8U control, INT16U address, INT8U MEM_ROM *wrptr, INT16U length ){
INT8U addressl,addressh;
addressl = (INT8U)address;
addressh = (INT8U)(address>>8);
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
if ( PIR2bits.BCLIF ){ // test for bus collision
PIR2bits.BCLIF = 0;
return ( 1 ); // return with Bus Collision error
}
else{ // start condition successful
if ( WriteI2C( control )){ // write byte - R/W bit should be 0
return ( 2 ); //3 // set error for write collision
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition received
if ( WriteI2C( addressh ) ){ // write word address for EEPROM
return ( 3 ); // set error for write collision
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition received
if ( WriteI2C( addressl ) ){ // write word address for EEPROM
return ( 4 ); //3 // set error for write collision
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition received
if ( putsI2CA (wrptr,length ) ){
return( 5 ); //4 // bus device responded possible error
}
}
else{
return ( 6 ); //2 // return with Not Ack error condition
}
}
else{
return ( 7 ); //2 // return with Not Ack error condition
}
}
else{
return ( 8 ); //2 // return with Not Ack error condition
}
}
IdleI2C(); // ensure module is idle
StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN ); // wait until stop condition is over
if ( PIR2bits.BCLIF ){ // test for bus collision
return ( 9 ); //1 // return with Bus Collision error
}
return ( 0 ); // return with no error
}
//3. Random read to external RAM
INT8U EESequentialReadA(INT8U control,INT16U address,INT8U MEM_ROM *rdptr,INT8U length ){
INT8U addressl,addressh;
addressl = (INT8U)address;
addressh = (INT8U)(address>>8);
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
if ( PIR2bits.BCLIF ){ // test for bus collision
PIR2bits.BCLIF = 0;
StopI2C();
return ( -1 ); // return with Bus Collision error
}
else{
if ( WriteI2C( control ) ){ // write 1 byte
return ( -3 ); // set error for write collision
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition, if received
if ( WriteI2C( addressh ) ){ // WRITE word address to EEPROM
return ( -3 ); // return with write collision error
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition, if received
if ( WriteI2C( addressl ) ){ // WRITE word address to EEPROM
return ( -3 ); // return with write collision error
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){ // test for ACK condition received
RestartI2C(); // generate I2C bus restart condition
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
if ( WriteI2C( control +1 ) ){// WRITE 1 byte - R/W bit should be 1 for read
return ( -3 ); // set error for write collision
}
IdleI2C(); // ensure module is idle
if ( !SSPCON2bits.ACKSTAT ){// test for ACK condition received
if ( getsI2CA( rdptr, length ) ){// read in multiple bytes
return ( -1 ); // return with Bus Collision error
}
NotAckI2C(); // send not ACK condition
while ( SSPCON2bits.ACKEN );// wait until ACK sequence is over
StopI2C(); // send STOP condition
while ( SSPCON2bits.PEN );// wait until stop condition is over
if ( PIR2bits.BCLIF ){ // test for bus collision
return ( -1 ); // return with Bus Collision error
}
}
else{
return ( -2 ); // return with Not Ack error
}
}
else{
return ( -2 ); // return with Not Ack error
}
}
else{
return(-2);
}
}
else{
return ( -2 ); // return with Not Ack error
}
}
return ( 0 ); // return with no error
}
//
INT8U putsI2CA( INT8U MEM_ROM *wrptr, INT16U length )
{
while ( length ) //
{
if ( SSPCON1bits.SSPM3 ) // if Master transmitter then execute the following
{
if ( putcI2C ( *wrptr ) ) // write 1 byte
{
return ( -3 ); // return with write collision error
}
IdleI2C(); // test for idle condition
length--;
if ( SSPCON2bits.ACKSTAT ) // test received ack bit state
{
return ( -2 ); // bus device responded with NOT ACK
} // terminate putsI2C() function
}
else // else Slave transmitter
{
PIR1bits.SSPIF = 0; // reset SSPIF bit
SSPBUF = *wrptr; // load SSPBUF with new data
SSPCON1bits.CKP = 1; // release clock line
while ( !PIR1bits.SSPIF ); // wait until ninth clock pulse received
if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) )// if R/W=0 and BF=0, NOT ACK was received
{
return ( -2 ); // terminate PutsI2C() function
}
}
wrptr ++; // increment pointer
} // continue data writes until null character
return ( 0 );
}
INT8U getsI2CA( INT8U MEM_ROM *rdptr, INT8U length )
{
while ( length -- ) // perform getcI2C() for 'length' number of bytes
{
*rdptr++ = getcI2C(); // save byte received
while ( SSPCON2bits.RCEN ); // check that receive sequence is over
if ( PIR2bits.BCLIF ) // test for bus collision
{
return ( -1 ); // return with Bus Collision error
}
if ( length ) // test if 'length' bytes have been read
{
SSPCON2bits.ACKDT = 0; // set acknowledge bit state for ACK
SSPCON2bits.ACKEN = 1; // initiate bus acknowledge sequence
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
}
}
return ( 0 ); // last byte received so don't send ACK
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -