📄 i2c.c
字号:
#include "i2c.h"
#include "iom16c62p.h"
#include "inthandler.h"
#include "uart.h"
#define FREE 0
#define BUSY 1
int ACK_IS_SET = 0;
int ACK;
int STOP_START = 0;
static struct I2CStatus currentStatus;
/* ACK ISR */
void UART2_recv_ISR(void)
{
ACK_IS_SET = 1;
ACK = 0;
_printf("ACK interrupt\n");
}
/* NACK ISR */
void UART2_transmit_ISR(void)
{
ACK_IS_SET = 1;
ACK = 1;
_printf("NACK interrupt\n");
}
/* Bus collision ISR */
void BUS_COLLISION_ISR(void)
{
STOP_START = 1; // Start condition sent
_printf("BUS Collition interrupt\n");
}
//--------------------------------------------------------------------------------------
// Name: InitI2C
// Parameters: None
// Returns: None
// Description: This routine configures UART2 as I2C
//--------------------------------------------------------------------------------------
void InitI2C()
{
_printf("InitI2C\n");
//asm("fclr i");
PD7.BIT.PD7_1 = 0; // SCL2 output port
PD7.BIT.PD7_0 = 0; // SDA2 input port
/* set the initial state for the SCL2 and SDA2 */
/*U2SMR.BYTE= 0x01; // IICM=1 mode
U2MR.BYTE = 0x00; // SMD2 to SMD0 bits in the UiMR register = 000b (Serial interface disabled).
P7.BIT.P7_1 = 1; // SCL2 level
P7.BIT.P7_0 = 1; // SDA2 level*/
/* set uart2 to i2c mode */
U2BRG = 49; // Clock 100 kHz
U2MR.BYTE = 0x02; // SMD2-SMD0=010b I2C MODE, CKDIR=0 master internal clock, IOPOL=0 no conversion
U2C0.BYTE = 0x90; // Uartform:msb, transmission/receiption at SCL falling/rising edge, SDA2 SCL2 n channel, f1
U2C1.BYTE = 0x05; // Enable reception and transmission
UCON.BYTE = 0x00; // Reset to 0.
U2SMR.BYTE = 0x07; // IIC mode, BBS=0 STOP condition detected, arbitration lost by byte
U2SMR2.BYTE = 0x02; // Clock delayed, clock out cmos, with no data delay
U2SMR3.BYTE = 0x20; // If IICM2=0 (ACKint), CKPH=1, then the initial and ultimate values for CLK2 are LOW
U2SMR4.BYTE = 0x30; // Clock delayed, clock out cmos, with no data delay
S2RIC.BYTE = 0x04; // UART2 ACK interrupt enabled level 4
S2TIC.BYTE = 0x04; // UART2 NACK interrupt enabled level 4
BCNIC.BYTE = 0x04; // UART2 bus collision detection interrupt enabled level 4
//asm("fset i");
}
//--------------------------------------------------------------------------------------
// Name: StartI2C
// Parameters: None
// Returns: None
// Description: Generates the start condition in the I2C line
//--------------------------------------------------------------------------------------
void StartI2C()
{
//_printf("StartI2C1\n");
U2SMR4.BIT.STAREQ = 1; // Start condition generate bit
Delay();
//_printf("StartI2C2\n");
U2SMR4.BIT.STSPSE = 1; // Output the start on the bus
//Delay();
//Delay();
//_printf("StartI2C3\n");
while (!STOP_START) {
_printf("while: startstop: %i\n", STOP_START);
} // Wait for start condition to be outputted
U2SMR4.BIT.STSPSE = 0; // Reset the output bit
STOP_START = 0; // Reset the flag
_printf("StartI2C\n");
}
//--------------------------------------------------------------------------------------
// Name: RestartI2C
// Parameters: None
// Returns: None
// Description: Generates the restart condition in the I2C line
//--------------------------------------------------------------------------------------
void RestartI2C()
{
U2SMR4.BIT.RSTARE = 1; // Restart condition generate bit
U2SMR4.BIT.STSPSE = 1; // Output the restart on the bus
Delay();
U2SMR4.BIT.STSPSE = 0; // Reset the output bit
U2SMR4.BIT.RSTARE = 0; // Reset the restart bit
}
//--------------------------------------------------------------------------------------
// Name: StopI2C
// Parameters: None
// Returns: None
// Description: Generates the stop condition in the I2C line
//--------------------------------------------------------------------------------------
void StopI2C()
{
U2SMR4.BIT.STPREQ = 1; // Stop condition generate bit
U2SMR4.BIT.STSPSE = 1; // Output the stop on the bus
Delay();
U2SMR4.BIT.STSPSE = 0; // Reset the output bit
U2SMR4.BIT.STPREQ = 0; // Reset the stop bit
}
//--------------------------------------------------------------------------------------
// Name: WriteI2C
// Parameters: c
// Returns: None
// Description: Puts c out on the bus
//--------------------------------------------------------------------------------------
char WriteI2C(unsigned char c)
{
/* Check if transmit buffer already is full */
/*if (U2C1.BIT.TI_U2C1 == 1) {
_printf("ERROR! Transmitt buffer full\n");
return -1;
}*/
//U2C1.BIT.TE_U2C1 = 0; // Disable transmission
U2TB.BYTE.U2TBL = c; // Put the data in the transmit buffer
//U2C1.BIT.TE_U2C1 = 1; // Enable transmission
while(U2C1.BIT.TI_U2C1 == 1); // Wait for transmission to finish
/*if ((U2RB.BYTE.U2RBH && 0x01) == 1) {
_printf("NACK received!\n");
return -1;
}*/
/* Wait for an ACK or NACK */
while (!ACK_IS_SET);
if (ACK == 1) { // If NACK return -1
_printf("ERROR! NACK received\n");
return -1;
}
_printf("WriteI2C OK!\n");
return 1;
}
//--------------------------------------------------------------------------------------
// Name: ReadI2C
// Parameters: None
// Returns: Byte sent on bus
// Description: Reads data sent on the bus
//--------------------------------------------------------------------------------------
int ReadI2C()
{
if (U2C1.BIT.RI_U2C1 == 0) {
_printf("ERROR! No data in recieve buffer\n");
return -1;
}
return U2RB.BYTE.U2RBL;
}
//--------------------------------------------------------------------------------------
// Name: AckI2C
// Parameters: None
// Returns: Nono
// Description: Sends an ACK on the bus
//--------------------------------------------------------------------------------------
void AckI2C()
{
U2SMR4.BIT.ACKD = 0;
U2SMR4.BIT.ACKC = 1;
U2SMR4.BIT.ACKC = 0;
}
//--------------------------------------------------------------------------------------
// Name: NackI2C
// Parameters: None
// Returns: None
// Description: Sends an NACK on the bus
//--------------------------------------------------------------------------------------
void NackI2C()
{
U2SMR4.BIT.ACKD = 1;
U2SMR4.BIT.ACKC = 1;
U2SMR4.BIT.ACKC = 0;
}
//--------------------------------------------------------------------------------------
// Name: IdleI2C
// Parameters: None
// Returns: None
// Description: Wait's until the I2C bus is idle
//--------------------------------------------------------------------------------------
void IdleI2C()
{
//while (U2SMR.BIT.BBS == 1);
//_printf("IdleI2C OK!\n");
}
void Delay() {
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
}
struct I2CStatus getStatusI2C() {
return currentStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -