📄 i2csiteb.c
字号:
#include "hpa449lib.h"
/*****************************************************************************
** [File]
** i2cSiteB.c
** [Purpose]
** Generate I2C protocol using bit banging on ports
** [Changes]
** 16.06.2002 Roger Neumair
** started
** 04/08/26 GH
** implemented both I2C busses on HPA449, fixed some bugs
**
*/
// site B P2.0(SCL) and P2.1(SDA)
#define SCL_B 0x01
#define SDA_B 0x02
#define I2C_B_OUTP P2OUT
#define I2C_B_DIR P2DIR
#define I2C_B_IN P2IN
// Standard implementation SCL and SDA drive low and high impedance;
void I2C_B_Init(void)
{
// Initialize the port for use with I2C
// Set direction of SDA and SCL to input to drive it high through pullup
I2C_B_DIR &= ~(SDA_B | SCL_B);
// Set output bit to low (drives only 0 if switched to output direction)
I2C_B_OUTP &= ~(SDA_B | SCL_B);
}
void I2C_B_Wait(void)
{
// check for I2C wait states
// If slave drives SCL low wait until it releases the SCL line
I2C_B_DIR &= ~SCL_B; // SCL is input
while(!(I2C_B_IN & SCL_B))
; // Wait for slave to release SCL
}
void I2C_B_Start(void)
{
// Set direction of SDA and SCL to input to drive it high through pullup
I2C_B_DIR &= ~(SDA_B | SCL_B);
I2C_B_DIR |= SDA_B; // START condition. Drive SDA low while SCL high
I2C_B_DIR |= SCL_B; // now drive SCL low
}
// Generate a STOP condition on the I2C bus
void I2C_B_Stop(void)
{
I2C_B_DIR |= SDA_B; // make sure SDA is low
I2C_B_DIR &= ~SCL_B;
I2C_B_DIR &= ~SDA_B;
}
//----------------------------------------------------------------------------
// [function]
// I2C_B_SendByte
// [Purpose]
// Sends a byte on the I2C port on site B
// [parameters]
// byte: the byte to send
// [returns]
// true if the addressed device acknoledges
// false if the address device times out acknowledging
// [remarks]
// -
int I2C_B_SendByte(unsigned char byte)
{
int n, ack;
unsigned char mask = 0x80; // Start with MSB
for(n=7; n>=0; n--) // Process 8 bits
{
if((byte & mask) != 0) // bit is high
{
I2C_B_DIR &= ~SDA_B; // Set SDA
}
else // bit is low
{
I2C_B_DIR |= SDA_B; // Reset SDA
}
I2C_B_Wait();
I2C_B_DIR |= SCL_B; // get ready for next bit
mask >>= 1; // shift mask one bit right
}
I2C_B_DIR &= ~SDA_B; // make sure SDA is an input when testing ACK
// Acknowledge
I2C_B_Wait();
// Last clock cycle
ack = (I2C_B_IN & SDA_B) ? 0 : 1;
// set clock back to 0
I2C_B_DIR |= SCL_B;
return ack;
}
//----------------------------------------------------------------------------
// [function]
// I2C_B_ReceiveByte
// [Purpose]
// Receives a byte on the I2C port on site B
// [parameters]
// ack: acknowledge
// [returns]
// byte received
// [remarks]
// -
unsigned char I2C_B_ReceiveByte(int fAck)
{
int n;
unsigned char ByteReceived = 0;
unsigned char mask = 0x80;
for(n=7; n>=0; n--) // Process 8 bits
{
I2C_B_Wait();
if (I2C_B_IN & SDA_B)
ByteReceived |= mask;
I2C_B_DIR |= SCL_B; // get ready for next bit
mask >>= 1; // shift mask one bit right
}
// Acknowledge
if (fAck)
I2C_B_DIR |= SDA_B; // pull SDA low
else
I2C_B_DIR &= ~SDA_B;
I2C_B_Wait();
I2C_B_DIR |= SCL_B;
// release SDA
I2C_B_DIR &= ~ SDA_B;
return ByteReceived;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -