我给一个例子程序吧,从MOT的汇编改过来的。调试好了的。
希望能对各位有些帮助。
#include "68hc08jl3.h"
//===========================================================
//定义SCL 及SDA 和 I2CPORT 及 DIRECTION
#ifndef SIMI2C
#define SCL 0x08
#define SDA 0x04
#define I2CPORT PTD
#define I2CDIR DDRD
#endif
void I2CSetupDelay (void);
void I2CBitDelay (void);
void I2CTxByte (unsigned char ucByte);
unsigned char I2CRxByte (void);
void I2CStartBit (void);
void I2CStopBit (void);
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// I2CTxByte
// Transmit the byte in Acc to the SDA pin
// (Acc will not be restored on return)
// Must be careful to change SDA values only while SCL is low,
// otherwise a STOP or START could be implied
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void I2CTxByte(unsigned char ch)
{
unsigned char i;
for(i = 8;i >0;i--)
{
if((ch & 0x80)!=0)
I2CPORT |= SDA; //Set the data bit value
else
I2CPORT &= ~SDA;
I2CSetupDelay();
I2CPORT |= SCL;
I2CBitDelay();
I2CPORT &= ~SCL;
ch <<= 1;
}
I2CPORT |= SDA;
I2CDIR &= ~SDA; //Set SDA as input
I2CSetupDelay();
I2CPORT |= SCL; //Clock the line to get ACK
I2CBitDelay();//
if((I2CPORT & SDA)==0)
{ //Look for ACK from slave device
I2CPORT &= ~SCL; //Restore clock line
I2CDIR |= SDA; //SDA back as output
}
else
{
//No acknowledgment received from slave device
//Some error action can be performed here
//For now, just restore the bus
I2CPORT &= ~SCL;
I2CDIR |= SDA;
}
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// I2CRxByte
// Recieve the byte to Acc from the SDA pin
// (Acc will not be restored on return)
// Must be careful to change SDA values only while SCL is low,
// otherwise a STOP or START could be implied
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
unsigned char I2CRxByte()
{
unsigned char i,ch=0;
I2CDIR &= ~SDA; //Set the SDA as input
for(i = 8;i > 0;i--)
{
ch <<= 1;
// I2CSetupDelay(); //Wait a bit
I2CPORT |= SCL; //Clock it in
I2CSetupDelay(); //Wait a bit
if((I2CPORT & SDA)!=0)
ch++;
I2CPORT &= ~SCL; //Restore clock to low state
I2CBitDelay();
}//
I2CPORT &= ~SDA; //SDA set low
I2CDIR |= SDA; //Set SDA as output
I2CSetupDelay();
I2CPORT |= SCL; //Clock the line to give ACK
I2CBitDelay();//
I2CPORT &= ~SCL;
return ch;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// A START condition is defined as a falling edge
// on SDA while SCL is high
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-
void I2CStartBit()
{ I2CPORT |= SCL;
I2CPORT |= SDA;
I2CDIR |= SDA;
I2CDIR |= SCL;
I2CPORT &= ~SDA;
I2CBitDelay();//
I2CPORT &= ~SCL;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// A STOP condition is defined as a rising edge
// on SDA while SCL is high
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void I2CStopBit()
{
I2CPORT &= ~SDA;
I2CPORT |= SCL;
I2CPORT |= SDA;
I2CBitDelay();//
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Provide some data setup time to allow
// SDA to stabilize in slave device
// Completely arbitrary delay (10 cycles)
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void I2CSetupDelay()
{
asm NOP;
asm NOP;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Bit delay to provide (approximately) the desired
// SCL frequency
// Again, this is arbitrary (16 cycles)
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void I2CBitDelay()
{
asm NOP;
asm NOP;
asm NOP;
asm NOP;
asm NOP;
}作者: mc9s08aw60 时间: 2007-2-9 14:54
程序如下:
void IIC_writebyte(unsigned char record)
{
IBCR_MS_SL = 1; // Set transmit and master mode
IBCR_TX_RX = 1; // And generate start condition
IBDR = slavewrite; // Adress the slave and set up for master transmit
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag
IBDR = slave_RD_address_LSB; // Send word adress
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag
while(IBSR_RXAK); // check for RXAK
IBDR = record;
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag
IBCR_MS_SL = 0; // generate stop signal
}
void IIC_readbyte()
{
unsigned char dummy;
IBCR_MS_SL = 1; // Set transmit and master mode
IBCR_TX_RX = 1; // And generate start condition
IBDR = slavewrite; // Adress the slave and set up for master transmit
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag
while(IBSR_RXAK); // check for RXAK
IBDR = slave_RD_address_LSB; // Send word adress
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag
while(IBSR_RXAK); // check for RXAK
IBCR_RSTA = 1; // set up repeated start
IBDR = SLAVEREAD;
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag
while (IBSR_RXAK); // check for RXAK
IBCR_TX_RX = 0; // set up to receive
RD_data = IBDR; // dummy read
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag
IBCR_TXAK = 1; // acknowledge disable
RD_data = IBDR;
while (!IBSR_IBIF); // wait until IBIF
IBSR_IBIF=1; // clear the interrupt event flag