Hi Tim Pieper,
bitte gib codes immer in spezielle tags {(php) oder (code)} denn so ist es etwas umständlich zum lesen.
zb so:
[php:1:1f76094f1d]// Credit where its due : seeprom routines i have converted Peter Daneegers software bit bang routines to hard I2C with minor changes.
/* I2C Status Message Codes (Master mode) */
#define START_TXD 0x08 /* Start condition for bus transmited */
#define REPEAT_START_TXD 0x10 /* Repeated Start condition for bus transmited */
#define ADDRESS_TXD_ACK 0x18 /* Address plus write sent, ack received */
#define ADDRESS_TXD_NOACK 0x20 /* Address plus write sent, NO ack received! */
#define DATA_TXD_ACK 0x28 /* Data sent, ack received */
#define DATA_TXD_NOACK 0x30 /* Data sent, NO ack received! */
#define ARB_LOST 0x38 /* I2C Master Arbitration Lost */
#define ADDRESS_RXD_ACK 0x40 /* Address plus read sent, ack received */
#define ADDRESS_RXD_NOACK 0x48 /* Address plus read sent, NO ack received! */
#define DATA_RXD_ACK 0x50 /* Data received, ack sent */
#define DATA_RXD_NOACK 0x58 /* Data received, NO ack sent! */
// I2CON Register bit values for bit masking operations.
#define I2B_I2EN 0x40
#define I2B_STA 0x20
#define I2B_STO 0x10
#define I2B_SI 0x08
#define I2B_AA 0x04
#define I2BX_I2EN 0xBF
#define I2BX_STA 0xDF
#define I2BX_STO 0xEF
#define I2BX_SI 0xF7
#define I2BX_AA 0xFB
// Page size of eeprom 2^n here 2^3=8
#define WRITEPAGE 3
// Function protypes.
bit hi2c_in(bit, uchar *);
bit hi2c_out(uchar);
bit hi2c_stop(void);
bit hi2c_start(void);
bit read_pcf8591(uchar *, uchar);
bit Seepromwrite( uint adr, uchar *s, uchar n );
bit Seepromread( uint adr, uchar *s, uchar n );
// Generates start condition on I2C bus returns 1 if error else returns 0.
bit hi2c_start(void)
{
I2CON=0x00; // I2C speed set using I2SCL & I2SCH
I2CON|=I2B_I2EN; // Enable I2C Bus.
I2CON|=I2B_STA; // Send Start condition.
while (!(I2CON & I2B_SI) ); // Wait for si.
if ( (I2STA!= START_TXD) && (I2STA!=REPEAT_START_TXD)) // If Status not as expected.
{
I2CON&=I2BX_STA; // Clear start bit;
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 1; // return error.
}
I2CON&=I2BX_STA; // Clear start bit;
return 0;
}
// Generates stop condition returns 1 if error else 0.
bit hi2c_stop(void)
{
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 0;
}
// Reads byte from I2C bus parameters ack to send pointer to uchar to store data.
// Returns 1 if error in operation.
bit hi2c_in(bit ack, uchar *i2rxdata)
{
if ( ack ) // set auto acknowledge flag if ack is to be sent.
I2CON|= I2B_AA;
else
I2CON&= I2BX_AA;
I2CON&=I2BX_SI; // Clear SI.
while (!( I2CON & I2B_SI ) ); // Wait for SI.
if ((I2STA!= DATA_RXD_ACK) && (I2STA!= DATA_RXD_NOACK)) // If status not as expected.
{
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 1; // Return error.
}
*i2rxdata=I2DAT; // Store received data.
return 0; // Return no error.
}
// Transmits a byte on I2C bus parameter byte to send.
// Returns 1 if error occured.
bit hi2c_out(uchar i2txdata)
{
I2DAT=i2txdata; // Put data to transmit in register.
I2CON&=I2BX_SI; // Clear SI.
while ( ! ( I2CON & I2B_SI ) ); // Wait for SI.
if ((I2STA!=DATA_TXD_ACK) && (I2STA!=ADDRESS_TXD_ACK) && (I2STA!=ADDRESS_RXD_ACK)) // If status not as expected.
{
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 1; // Return error.
}
return 0; // Return no error.
}
// Reads a value from ADC PCF8591 Parameters pointer to uchar to store result and channel no to read.
// Returns 1 if error occured in operation.
bit read_pcf8591( uchar *adrdbuff, uchar adch)
{
if(hi2c_start()) // Send start condition.
return 1;
if(hi2c_out(0x90)) // Send device address + write.
return 1;
if(hi2c_out(adch)) // send channel number to read.
return 1;
hi2c_stop(); // Send stop condition.
if(hi2c_start()) // send start condition.
return 1;
if(hi2c_out(0x91)) // Send device address + Read.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(0, adrdbuff)) // Final Read data from ADC send nack.
return 1;
hi2c_stop(); // Send stop condition.
return 0; // Return no error.
}
// Sends address of memory location in seeprom to read or write.
// Returns 1 if error occured else returns 0.
// Parameters address high and low bytes rd/wr bit.
bit Seepromadr( uchar adrh, uchar adrl, bit rd )
{
uchar devadr=0xa2; //I2C Bus Address 0.
devadr |= rd; //Or the RD/WR bit.
hi2c_start(); //Send a start codition.
if( hi2c_out( devadr )) //Send the device address.
return 1;
if(!rd) //If Write Operation.
{
if( hi2c_out( adrh )) //Send the address high byte.
return 1;
return hi2c_out( adrl ); //Send the address low byte.
}
return 0; // Return no error.
}
// Writes specified no. of bytes to seeprom.
// Parameters starting address location, pointer to data buffer, no. of bytes to write.
// Returns 1 if error occured else returns 0.
bit Seepromwrite( uint adr, uchar *s, uchar n )
{
uchar i;
do
{
// Acknowledge pooling for eeprom since seeproms dont respond when busy writing.
for( i = 255;; )
{
if( 0 == Seepromadr( adr>>8, adr, 0) )
break; // receive ACK = write finished
hi2c_stop();
if( 0 == --i ) // try it 25.5msec
return 1; // Timeout
}
if( 0 == n )
return hi2c_stop(); // all bytes written
i = adr & ((1 << WRITEPAGE) - 1); // prepare write boundary check
do
{
if( hi2c_out( *s ))
{
hi2c_stop();
return 1; // Write error
}
s++;
adr++;
}while( --n && ++i < (1 << WRITEPAGE));
hi2c_stop();
}while(1);
}
// Reads specified no. of bytes from seeprom.
// Parameters starting address location, pointer to data buffer, no. of bytes to read
// Returns 1 if error occured else returns 0.
bit Seepromread( uint adr, uchar *s, uchar n )
{
if( Seepromadr( adr>>8, adr, 0))
return 1; // EEPROM not connected
do
{
if( Seepromadr( adr>>8, 0, 1)) // repeat start for read
return 1;
for(;Zwinkern
{
bit ack = --n && ++adr & 0xff; // last byte or last in page
if( hi2c_in(ack, s) )
return 1;
s++;
if( !ack )
break;
}
}while( n );
hi2c_stop(); // send stop condition.
return 0; // return no error.
}
//************************************************** *************** [/php:1:1f76094f1d]
oder
Code:
// Credit where its due : seeprom routines i have converted Peter Daneegers software bit bang routines to hard I2C with minor changes.
/* I2C Status Message Codes (Master mode) */
#define START_TXD 0x08 /* Start condition for bus transmited */
#define REPEAT_START_TXD 0x10 /* Repeated Start condition for bus transmited */
#define ADDRESS_TXD_ACK 0x18 /* Address plus write sent, ack received */
#define ADDRESS_TXD_NOACK 0x20 /* Address plus write sent, NO ack received! */
#define DATA_TXD_ACK 0x28 /* Data sent, ack received */
#define DATA_TXD_NOACK 0x30 /* Data sent, NO ack received! */
#define ARB_LOST 0x38 /* I2C Master Arbitration Lost */
#define ADDRESS_RXD_ACK 0x40 /* Address plus read sent, ack received */
#define ADDRESS_RXD_NOACK 0x48 /* Address plus read sent, NO ack received! */
#define DATA_RXD_ACK 0x50 /* Data received, ack sent */
#define DATA_RXD_NOACK 0x58 /* Data received, NO ack sent! */
// I2CON Register bit values for bit masking operations.
#define I2B_I2EN 0x40
#define I2B_STA 0x20
#define I2B_STO 0x10
#define I2B_SI 0x08
#define I2B_AA 0x04
#define I2BX_I2EN 0xBF
#define I2BX_STA 0xDF
#define I2BX_STO 0xEF
#define I2BX_SI 0xF7
#define I2BX_AA 0xFB
// Page size of eeprom 2^n here 2^3=8
#define WRITEPAGE 3
// Function protypes.
bit hi2c_in(bit, uchar *);
bit hi2c_out(uchar);
bit hi2c_stop(void);
bit hi2c_start(void);
bit read_pcf8591(uchar *, uchar);
bit Seepromwrite( uint adr, uchar *s, uchar n );
bit Seepromread( uint adr, uchar *s, uchar n );
// Generates start condition on I2C bus returns 1 if error else returns 0.
bit hi2c_start(void)
{
I2CON=0x00; // I2C speed set using I2SCL & I2SCH
I2CON|=I2B_I2EN; // Enable I2C Bus.
I2CON|=I2B_STA; // Send Start condition.
while (!(I2CON & I2B_SI) ); // Wait for si.
if ( (I2STA!= START_TXD) && (I2STA!=REPEAT_START_TXD)) // If Status not as expected.
{
I2CON&=I2BX_STA; // Clear start bit;
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 1; // return error.
}
I2CON&=I2BX_STA; // Clear start bit;
return 0;
}
// Generates stop condition returns 1 if error else 0.
bit hi2c_stop(void)
{
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 0;
}
// Reads byte from I2C bus parameters ack to send pointer to uchar to store data.
// Returns 1 if error in operation.
bit hi2c_in(bit ack, uchar *i2rxdata)
{
if ( ack ) // set auto acknowledge flag if ack is to be sent.
I2CON|= I2B_AA;
else
I2CON&= I2BX_AA;
I2CON&=I2BX_SI; // Clear SI.
while (!( I2CON & I2B_SI ) ); // Wait for SI.
if ((I2STA!= DATA_RXD_ACK) && (I2STA!= DATA_RXD_NOACK)) // If status not as expected.
{
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 1; // Return error.
}
*i2rxdata=I2DAT; // Store received data.
return 0; // Return no error.
}
// Transmits a byte on I2C bus parameter byte to send.
// Returns 1 if error occured.
bit hi2c_out(uchar i2txdata)
{
I2DAT=i2txdata; // Put data to transmit in register.
I2CON&=I2BX_SI; // Clear SI.
while ( ! ( I2CON & I2B_SI ) ); // Wait for SI.
if ((I2STA!=DATA_TXD_ACK) && (I2STA!=ADDRESS_TXD_ACK) && (I2STA!=ADDRESS_RXD_ACK)) // If status not as expected.
{
I2CON|=I2B_STO; // Send stop stop condition.
I2CON&=I2BX_SI; // Clear SI.
while ( I2CON & I2B_STO ); // Wait till hardware clears stop bit.
I2CON&=I2BX_I2EN; // Disable I2C Bus.
return 1; // Return error.
}
return 0; // Return no error.
}
// Reads a value from ADC PCF8591 Parameters pointer to uchar to store result and channel no to read.
// Returns 1 if error occured in operation.
bit read_pcf8591( uchar *adrdbuff, uchar adch)
{
if(hi2c_start()) // Send start condition.
return 1;
if(hi2c_out(0x90)) // Send device address + write.
return 1;
if(hi2c_out(adch)) // send channel number to read.
return 1;
hi2c_stop(); // Send stop condition.
if(hi2c_start()) // send start condition.
return 1;
if(hi2c_out(0x91)) // Send device address + Read.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(1, adrdbuff)) // Dummy read data from ADC send ack.
return 1;
if(hi2c_in(0, adrdbuff)) // Final Read data from ADC send nack.
return 1;
hi2c_stop(); // Send stop condition.
return 0; // Return no error.
}
// Sends address of memory location in seeprom to read or write.
// Returns 1 if error occured else returns 0.
// Parameters address high and low bytes rd/wr bit.
bit Seepromadr( uchar adrh, uchar adrl, bit rd )
{
uchar devadr=0xa2; //I2C Bus Address 0.
devadr |= rd; //Or the RD/WR bit.
hi2c_start(); //Send a start codition.
if( hi2c_out( devadr )) //Send the device address.
return 1;
if(!rd) //If Write Operation.
{
if( hi2c_out( adrh )) //Send the address high byte.
return 1;
return hi2c_out( adrl ); //Send the address low byte.
}
return 0; // Return no error.
}
// Writes specified no. of bytes to seeprom.
// Parameters starting address location, pointer to data buffer, no. of bytes to write.
// Returns 1 if error occured else returns 0.
bit Seepromwrite( uint adr, uchar *s, uchar n )
{
uchar i;
do
{
// Acknowledge pooling for eeprom since seeproms dont respond when busy writing.
for( i = 255;; )
{
if( 0 == Seepromadr( adr>>8, adr, 0) )
break; // receive ACK = write finished
hi2c_stop();
if( 0 == --i ) // try it 25.5msec
return 1; // Timeout
}
if( 0 == n )
return hi2c_stop(); // all bytes written
i = adr & ((1 << WRITEPAGE) - 1); // prepare write boundary check
do
{
if( hi2c_out( *s ))
{
hi2c_stop();
return 1; // Write error
}
s++;
adr++;
}while( --n && ++i < (1 << WRITEPAGE));
hi2c_stop();
}while(1);
}
// Reads specified no. of bytes from seeprom.
// Parameters starting address location, pointer to data buffer, no. of bytes to read
// Returns 1 if error occured else returns 0.
bit Seepromread( uint adr, uchar *s, uchar n )
{
if( Seepromadr( adr>>8, adr, 0))
return 1; // EEPROM not connected
do
{
if( Seepromadr( adr>>8, 0, 1)) // repeat start for read
return 1;
for(;Zwinkern
{
bit ack = --n && ++adr & 0xff; // last byte or last in page
if( hi2c_in(ack, s) )
return 1;
s++;
if( !ack )
break;
}
}while( n );
hi2c_stop(); // send stop condition.
return 0; // return no error.
}
//*****************************************************************
Lesezeichen