📄 i2cdrive.c
字号:
#include "i2cexprt.h"
/* Immediate data to write into I2CON */
/* CRSEL = 0 -> CLK determined by I2SCLH / L */
#define GENERATE_STOP 0x54 /* STO=1, STA=0, SI=0 */
#define RELEASE_BUS_ACK 0x44 /* STO=STA=SI=0, AA=1 */
#define RELEASE_BUS_NOACK 0x40 /* STO=STA=SI=AA=0 */
#define RELEASE_BUS_STA 0x64 /* (rep)START, STA=1 */
static I2C_TRANSFER *tfr; /* Ptr to active trf block */
static I2C_MESSAGE *msg; /* ptr to active msg block */
static BYTE msgCount; /* Nr of messages to sent */
static BYTE dataCount; /* bytes send/received */
void I2C_Interrupt(void) interrupt 6 using 1
{
switch(I2STAT)
{
case 0x00: /* Bus Error has occured */
I2CON = GENERATE_STOP;
break;
case 0x08:
case 0x10:
I2DAT = msg->address;
I2CON = RELEASE_BUS_ACK;
break;
case 0x18:
case 0x28:
if (dataCount < msg->nrBytes)
{
I2DAT = msg->buf[dataCount++];
I2CON = RELEASE_BUS_ACK;
}
else
{
if (msgCount < tfr->nrMessages)
{
dataCount = 0;
msg = tfr->p_message[msgCount++];
I2CON = RELEASE_BUS_STA;
}
else
{
I2CON = GENERATE_STOP;
I2C_Ready(I2C_OK, msgCount);
}
}
break;
case 0x20:
case 0x48:
I2C_Ready(I2C_NACK_ON_ADDRESS, msgCount);
I2CON = GENERATE_STOP;
break;
case 0x30:
I2C_Ready(I2C_NACK_ON_DATA, msgCount);
I2CON = GENERATE_STOP;
break;
case 0x38:
I2CON = RELEASE_BUS_STA;
break;
case 0x40:
if (msg->nrBytes == 1)
I2CON = RELEASE_BUS_NOACK;
else
I2CON = RELEASE_BUS_ACK;
break;
case 0x50:
msg->buf[dataCount++] = I2DAT;
if (dataCount + 1 == msg->nrBytes)
I2CON = RELEASE_BUS_NOACK;
else
I2CON = RELEASE_BUS_ACK;
break;
case 0x58:
msg->buf[dataCount] = I2DAT;
if (msgCount < tfr->nrMessages)
{
dataCount = 0;
msg = tfr->p_message[msgCount++];
I2CON = RELEASE_BUS_STA;
}
else
{
I2CON = GENERATE_STOP;
I2C_Ready(I2C_OK, msgCount);
}
break;
default: break;
}
}
void I2C_Init(void)
/*****************/
{
// Fpclk = 7.373 Mhz internal oscillator
// I2c speed = Fpclk / (2*(I2SCLH+I2SCLL)
P1M1 |= 0x0C; /* P1.2 and P1.3 to open drain */
P1M2 |= 0x0C;
I2ADR = 0x26; /* default slave address */
I2SCLH = 19; /* speed ~100KHz, 50% duty */
I2SCLL = 19;
I2CON = RELEASE_BUS_ACK; /* enable I2C hardware */
EI2C = 1; /* enable I2C interrupt */
}
void I2C_Transfer(I2C_TRANSFER *p)
{
tfr = p;
msgCount = 0;
dataCount = 0;
msg = tfr->p_message[msgCount++];
I2CON = RELEASE_BUS_STA;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -