⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 基于瑞萨 M16C 的最新版本 IIC 通信
💻 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 + -