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

📄 thwi2c.c.svn-base

📁 最新火热的CX32 源代码
💻 SVN-BASE
字号:

#include "tdefs.h"
#include "C91Cx27U.h"
#include "THWI2C.h"
#include "ioctrl.h"

void	HWI2CDelay( void );
void	HWI2CBusErr( void );

/********************/
/* I2C BUS control	*/
/********************/
Byte	tdHWI2CErrorTimer;		/* I2C BUS error timer 					*/
Byte	*tdHWI2CDataPtr;		/* Pointer to I2C BUS transmission data	*/
Byte	tdHWI2CBuff[150];		/* I2C BUS transmission data array 		*/
Byte	tdHWI2CTransNum;		/* I2C BUS number of transmission data	*/
Byte	tdHWI2CRepeatStart;		/* I2C BUS number of transmission data until repeat start	*/
Byte	tdSlaveAddrSendFlag;	/* Flag : slave address has been sent	*/
Byte	tdHWI2CBusyFlag;		/* Flag : now transmitting				*/
Byte	tdAckFlag;				/* Flag : ACK was sent					*/


void	HWI2CProcess( void )
{
	Byte	sbi0cr2_buf;
	static Byte	cntr;
	Byte  ret_data;
	SBI0CR2 = HWI2C_SW_RESET1;
	SBI0CR2 = HWI2C_SW_RESET2;			/* Software reset */
	do{
		sbi0cr2_buf = SBI0CR2;
	}
	while( sbi0cr2_buf & SWRMON );
	
	SBI0BR0 = HWI2C_SBI0BR0;		/* <I2SBI0> = 0 		*/
	SBI0BR1 = HWI2C_CLK_EN;			/* <P4EN> = 1			*/
	I2C0AR = HWI2C_MCU_SLV;			/* Salve address		*/
	SBI0CR2 = HWI2C_BUS_FREE;		/* Bus free				*/
	
	for( tdHWI2CErrorTimer = C_1000MS20 ; ; )
	{
		sbi0cr2_buf = SBI0CR2;
		if( !( sbi0cr2_buf & BB ) )
		{			/* BUS FREE ?	*/
			SBI0DBR = *tdHWI2CDataPtr;
			tdSlaveAddrSendFlag = C_BIT_ON;
			tdHWI2CBusyFlag = C_BIT_ON;				/* I2CBUS BUSY SET				*/
			SBI0CR1 = HWI2C_ACK_8;
			SBI0CR2 = HWI2C_START;				/* START CONDITION + SLAVE OUT	*/
			for( tdHWI2CErrorTimer = C_1000MS20 ; tdHWI2CErrorTimer != HWI2C_TIMER_END ; )
			{
				if(tdHWI2CBusyFlag == C_BIT_OFF)
				{
					break;						/* EXIT */
				}
			}
			tdHWI2CBusyFlag = C_BIT_OFF;				/* I2CBUS BUSY CLR */
		}
		else
		{
			if( tdHWI2CErrorTimer != HWI2C_TIMER_END )
			{
				continue;		/* ERROR TIMER OVER ? (for F_BB == 1) */
			}
		}
		break;
	}
	if( HWI2C_TIMER_END == tdHWI2CErrorTimer )
	{
		/* BUS ERROR */
		HWI2CBusErr();							/* BUS ERR PROCESS */
	}

	tdHWI2CErrorTimer = HWI2C_TIMER_STOP;
}


/*==================================================================*/
/*	Hardware I2C bus error process									*/
/*==================================================================*/
void	HWI2CBusErr( void )
{
	/* Software reset */
	SBI0CR2 = HWI2C_SW_RESET1;
	HWI2CDelay();
	SBI0CR2 = HWI2C_SW_RESET2;
	HWI2CDelay();
}


/*==================================================================*/
/*	HWI2CDelay function													*/
/*==================================================================*/
void	HWI2CDelay( void )
{
	Word	cntr;
	for( cntr = 0xfff0 ; cntr++ != 0 ; );
}

/*==================================================================*/
/*	Hardware I2C bus interrupt routine								*/
/*==================================================================*/
void intsbi( void )
{
	Byte	sbi0cr2_buf;

	sbi0cr2_buf = SBI0CR2;
	if( sbi0cr2_buf & MST )    /* MASTER MODE ?	*/
	{				
		if( sbi0cr2_buf & TRX )    /* WRITE MODE ?	*/
		{			
			if( !( sbi0cr2_buf & LRB ) )    /* ACK = 0 ?	*/
			{	
				if(( tdHWI2CRepeatStart != 0 ) && ( --tdHWI2CRepeatStart == 0 ))    /* for E2PROM READ FORMAT */
				{	
					Word	tmr;

					SBI0CR2 = HWI2C_BUS_FREE;			/* BUS FREE */

					for( tmr = 0x8000 ; tmr != 0 ; tmr++ )
					{
						sbi0cr2_buf = SBI0CR2;
						if( sbi0cr2_buf & BB )
						{
							continue;					/* BUS BUSY ?	*/
						}
						if( !(sbi0cr2_buf & LRB) )
						{
							continue;					/* ACK = 0 ?	*/
						}
						HWI2CDelay();
						--tdHWI2CTransNum;
						SBI0DBR = *++tdHWI2CDataPtr;		/* TRANS. DATA SET	*/
						tdSlaveAddrSendFlag = C_BIT_ON;
						SBI0CR2 = HWI2C_START;			/* START CONDITION OUT	*/
						break;
					}
//					tdHWI2CErrorTimer = HWI2C_TIMER_END;
				}
				else
				{	/* WRITE MODE */
					tdSlaveAddrSendFlag = C_BIT_OFF;
					if(--tdHWI2CTransNum != 0)
					{
						SBI0DBR = *++tdHWI2CDataPtr;		/* DATA TRANS. */
					}
					else
					{
						tdAckFlag = sbi0cr2_buf & LRB;
						SBI0CR2 = HWI2C_STOP;			/* STOP CONDITION OUT	*/
						tdHWI2CBusyFlag = C_BIT_OFF;			/* DATA TRANS. END		*/
					}
				}
			}
			else
			{
				tdAckFlag = sbi0cr2_buf & LRB;
				SBI0CR2 = HWI2C_STOP;					/* STOP CONDITION OUT	*/
				tdHWI2CBusyFlag = C_BIT_OFF;					/* END					*/
			}
		}
		else
		{		/* READ MODE */
			if(tdSlaveAddrSendFlag == C_BIT_ON)
			{					/* SLAVE ADDRESS SEND ? */
				Byte	dmy_rd;					/* Dummy read buffer	*/
				tdSlaveAddrSendFlag = C_BIT_OFF;
				if(tdHWI2CTransNum == 2)
				{				/* READ DATA LAST 2 ?	*/
					SBI0CR1 = HWI2C_NACK_8;					/* 8-bit, NACK			*/
				}
				dmy_rd = SBI0DBR;						/* DUMY READ */
			}
			else{
				if(--tdHWI2CTransNum == 0)
				{
					SBI0CR2 = HWI2C_STOP;
					tdHWI2CBusyFlag = C_BIT_OFF;
				}
				else{
					if(tdHWI2CTransNum == 2)
					{			/* READ DATA LAST 2 ?	*/
						SBI0CR1 = HWI2C_NACK_8;				/* 8-bit, NACK			*/
					}
					else{
						if(tdHWI2CTransNum == 1)
						{		/* LAST READ DATA	*/
							SBI0CR1 = HWI2C_NACK_1;			/* 1-bit, NACK		*/
						}
					}
					*++tdHWI2CDataPtr = SBI0DBR;			/* DATA READ */
				}
			}
		}
	}
	else
	{	/* SLAVE MODE */
		tdHWI2CErrorTimer = HWI2C_TIMER_STOP;					/* ERR TIMER CLR */
	}
}

void tdHWI2CWriteByte(BYTE slaveadr,BYTE subadr, BYTE ucvalue)
{  
   	tdHWI2CBuff[0] = slaveadr;
	tdHWI2CBuff[1] = (Byte)subadr;
	tdHWI2CBuff[2] = ucvalue;
	tdHWI2CDataPtr = tdHWI2CBuff;
	tdHWI2CTransNum = 3;
	tdHWI2CRepeatStart = 0;
	HWI2CProcess();
}


Byte tdHWI2CReadByte(BYTE slaveadr,BYTE subadr)
{

	tdHWI2CBuff[0] = slaveadr&0xFE;    // write address
	tdHWI2CBuff[1] = (Byte)subadr;
	tdHWI2CBuff[2] = slaveadr;//|0x01;     // Read address
	tdHWI2CDataPtr = tdHWI2CBuff;
	tdHWI2CTransNum = 4;
	tdHWI2CRepeatStart = 2;
	HWI2CProcess();
			
	return  tdHWI2CBuff[3];
   
}


void	tdHWI2cWriteData(Byte slv_address,Byte sub_address, Byte *data_ptr, Byte length)
{

	Byte loop_count;
	tdHWI2CBuff[0] = slv_address&0xFE;
	tdHWI2CBuff[1] = sub_address;
	for(loop_count = 0; loop_count < length; loop_count++)
	{
		tdHWI2CBuff[loop_count + 2] = *data_ptr;
		++data_ptr;
	}
	tdHWI2CDataPtr = tdHWI2CBuff;
	tdHWI2CTransNum = length + 2;
	tdHWI2CRepeatStart = 2;
	HWI2CProcess();
	
}

void	tdHWI2CReadData(Byte slv_address,Byte sub_address, Byte *data_ptr, Byte length)
{
	Byte loop_count,uctemp;
	tdHWI2CBuff[0] = slv_address&0xFE;    // write address
	tdHWI2CBuff[1] = sub_address;
	tdHWI2CBuff[2] = slv_address|0x01;     // Read address
	uctemp = 3;
	tdHWI2CRepeatStart = 3;
	
	tdHWI2CDataPtr = tdHWI2CBuff;
	tdHWI2CTransNum = length+uctemp;
		
		
	HWI2CProcess();
		
	for(loop_count = 0; loop_count < length; loop_count++)
	{
		*data_ptr = tdHWI2CBuff[loop_count + uctemp];
		++data_ptr;
	}
		
}

void tdHWI2CInit(void)
{
    ODE = 0x0C;

	g_p6cr_buf = 0x07;
	P6CR = g_p6cr_buf; //00000111    
	g_p6fc_buf = 0x0E;
    P6FC = g_p6fc_buf; //00001110

    INTSBI = INT_PRIORITY_D;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -