普通のIOポートシミュレーションはI 2 C通信と応用解析を実現する


I 2 C通信仕様(具体的には「浅談I 2 Cバス」を参照)によれば、通常のIOポートシミュレーションにより、スレーブデバイスとのI 2 C通信を実現することができる.ここで、SCLはIOポート遅延高低レベル変化により実現され、SDAは、SCL状態変化に応じて開始信号を生成し、終了信号を生成し、受信データの送信を実現する.以下、関連コード
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* @Purpose:  I2C Communication driver(By IO)
* @Author:  Purple
* @Version:  1.0
* @Date:  Create By Purple 2014.08.09
* 
* 
* Copyright (C) BlueWhale Tech.   
* All rights reserved.  
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


#ifndef IICDRV_H
#define IICDRV_H


/* Include Files */


/* Macros */
#define I2C_SDA			PTT_PTT0   //   Freescale PT0   SDA ,PT1   SCL 
#define I2C_SDA_IO		DDRT_DDRT0
#define I2C_SCL			PTT_PTT1
#define I2C_SCL_IO		DDRT_DDRT1

#define IO_OUT_MODE		1	//Freescale:1     ,0     ;NEC:0     ,1     
#define IO_IN_MODE		0


/* Function Prototypes */
void I2CStart(void);
void I2CStop(void);
void I2CFree(void);
void I2CSendACK(void);
void I2CSendNoACK(void);
bool I2CCheckACK(void);
void I2CNoAck(void);
void I2CSendByte(unsigned char sendData);
unsigned char I2CReceiveByte(void);


#endif
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* @Purpose:  I2C Communication driver(By IO)
* @Author:  Purple
* @Version:  1.0
* @Date:  Create By Purple 2014.08.09
* 
* 
* Copyright (C) BlueWhale Tech.   
* All rights reserved.  
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


/* Include Files */
#include "IICDrv.h"


/* Function Prototypes */
static void I2CDelay(void);


/* Function Definitions */
/*
 * FunctionName: I2CDelay
 * Purpose: I2C    SCL    (  ),    Slave            
 * Parameters:  
*/
static void I2CDelay(void)
{
	_asm("nop");
	_asm("nop");
	_asm("nop");
	_asm("nop");
	_asm("nop");
}


/*
 * FunctionName: I2CStart
 * Purpose:   I2C    
 * Parameters:  
*/
void I2CStart(void)
{
	I2C_SDA_IO=IO_OUT_MODE;     //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;     //  SCL       
	
	I2C_SCL=1;
	I2CDelay();
	I2C_SDA=1;
	I2CDelay();
	I2C_SDA=0;
	I2CDelay();
	I2C_SCL=0;
	I2CDelay();
}

/*
 * FunctionName: I2CStop
 * Purpose:   I2C    
 * Parameters:  
*/
void I2CStop(void)
{
	I2C_SDA_IO=IO_OUT_MODE;     //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;     //  SCL       
	
	I2C_SCL = 0;
	I2CDelay();
	I2C_SDA = 0;
	I2CDelay();
	I2C_SDA = 1;
	I2CDelay();
	I2C_SCL = 1;
	I2CDelay();
}

/*
 * FunctionName: I2CFree
 * Purpose:   I2C      
 * Parameters:  
*/
void I2CFree(void)
{
	I2C_SDA_IO=IO_OUT_MODE;     //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;     //  SCL       
	
	I2C_SDA = 1;
	I2CDelay();
	I2C_SCL = 1;
	I2CDelay();
}

/*
 * FunctionName: I2CSendACK
 * Purpose:   I2C  ACK  
 * Parameters:  
*/
void I2CSendACK(void)
{
	I2C_SDA_IO=IO_OUT_MODE;     //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;     //  SCL       
	
	I2C_SCL=0;
	I2CDelay();
	I2C_SDA=0;
	I2CDelay();
	I2C_SCL=1;
	I2CDelay();
	I2C_SCL=0;
	I2CDelay();
}

/*
 * FunctionName: I2CSendNoACK
 * Purpose:   I2C ACK  
 * Parameters:  
*/
void I2CSendNoACK(void)
{
	I2C_SDA_IO=IO_OUT_MODE;	  //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;	  //  SCL       

	I2C_SCL=0;
	I2CDelay();
	I2C_SDA=1;
	I2CDelay();
	I2C_SCL=1;
	I2CDelay();
	I2C_SCL=0;
	I2CDelay();
}

/*
 * FunctionName: I2CCheckACK
 * Purpose:   I2C   ACK  
 * Parameters:  
*/
bool I2CCheckACK(void)
{
	bool tempACK;
	
	I2C_SDA_IO=IO_OUT_MODE;	  //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;	  //  SCL       

	I2C_SDA=1;
	I2CDelay();
	I2C_SCL = 1;
	I2C_SDA_IO=IO_IN_MODE;	  //  SDA       ,  Slave     
	I2CDelay();
	if(I2C_SDA)
		tempACK=FALSE;
	else
		tempACK=TRUE;

	I2C_SCL=0;
	I2CDelay();

	return tempACK ;
}

/*
 * FunctionName: I2CSendByte
 * Purpose:   I2C        
 * Parameters: sendData-         
*/
void I2CSendByte(unsigned char sendData)
{
	unsigned char serialNum = 0;

	I2C_SDA_IO=IO_OUT_MODE;	  //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;	  //  SCL       

	for(serialNum=8;serialNum>=1;serialNum--)   // MSB            
	{
		I2C_SDA = (sendData>>(serialNum-1))&0x01;
		I2CDelay();
		I2C_SCL = 1;
		I2CDelay();
		I2C_SCL = 0;
		I2CDelay();
	}
}

/*
 * FunctionName: I2CReceiveByte
 * Purpose:   I2C        
 * Parameters:  
*/
unsigned char I2CReceiveByte(void)
{	
	unsigned char serialNum = 0;
	unsigned char dataValue=0;

	I2C_SDA_IO=IO_IN_MODE;	  //  SDA       
	I2C_SCL_IO=IO_OUT_MODE;	  //  SCL       

	for(serialNum=0;serialNum<=7;serialNum++)// MSB            
	{
		I2C_SCL=1;
		I2CDelay();
		if(I2C_SDA) dataValue|=(0b10000000>>serialNum);
		I2C_SCL=0;
		I2CDelay();
	}

	return dataValue;
}

なお、シミュレーションSCLで採用される遅延時間は、スレーブ機器の特性に応じて調整する必要があり、遅延時間は、スレーブ機器の最小SCL間隔時間より小さくてはならない
IOポートを介してI 2 C通信が実現された以上、上記のコードで対応するスレーブ機器I 2 Cとの通信を実現することができ、EEPROM 24 C 04を例にとると、以下はEEPROMデータ関連関数の読み取りと書き込みのコードである
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* @Purpose:  Communication with EEPROM 24C04
* @Author:  Purple
* @Version:  1.0
* @Date:  Create By Purple 2014.08.09
* 
* 
* Copyright (C) BlueWhale Tech.   
* All rights reserved.  
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


/* Include Files */
#include "EEApp.h"



/* Function Definitions */
/*
 * FunctionName: Slave24C04Write
 * Purpose:  EEPROM24C04         
 * Parameters: tarAddress-         
 *             wrNumber-        (    )
 *             wrPointer-           
*/
void Slave24C04Write(unsigned char tarAddress,unsigned char wrNumber,unsigned char* wrPointer)
{
	bool rxdACK;

	I2CStart();

	I2CSendByte(SLAVE_ADDRESS);   //  24C04     ,  LSB     0    ,1    
	rxdACK=I2CCheckACK();
	I2CSendByte(tarAddress);   //           
	rxdACK=I2CCheckACK();

	for(;wrNumber!=0;wrNumber--,wrPointer++)
	{
	  	I2CSendByte(*wrPointer);   //       
		rxdACK=I2CCheckACK();
	}

	I2CStop();
}

/*
 * FunctionName: Slave24C04Read
 * Purpose:  EEPROM24C04         
 * Parameters: tarAddress-         
 *             wrNumber-       (    )
 *             wrPointer-            
*/
void Slave24C04Read(unsigned char tarAddress,unsigned char rdNumber,unsigned char* rdPointer)
{
	bool rxdACK;
	
	I2CStart();
	I2CSendByte(SLAVE_ADDRESS);   //  24C04     
	rxdACK=I2CCheckACK();
	I2CSendByte(tarAddress);   //           
	rxdACK=I2CCheckACK();

	I2CStart();
	I2CSendByte(SLAVE_ADDRESS+1);  //  24C04     ,  LSB     1    
	rxdACK=I2CCheckACK();

	for(;rdNumber!=0;rdNumber--,rdPointer++)
	{
	    *rdPointer=I2CReceiveByte();   //       

		if(rdNumber!=1)
			I2CSendACK();
		else
			I2CSendNoACK();
	}

	I2CStop();
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* @Purpose:  Communication with EEPROM 24C04
* @Author:  Purple
* @Version:  1.0
* @Date:  Create By Purple 2014.08.09
* 
* 
* Copyright (C) BlueWhale Tech.   
* All rights reserved.  
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


#ifndef EEAPP_H
#define EEAPP_H


/* Include Files */
#include "IICDrv.h"


/* Macros */
#define SLAVE_ADDRESS	(0xA0)


/* Function Prototypes */
void Slave24C04Write(unsigned char tarAddress,unsigned char wrNumber,unsigned char* wrPointer);
void Slave24C04Read(unsigned char tarAddress,unsigned char rdNumber,unsigned char* rdPointer);



#endif

異なるスレーブデバイスは、アプリケーション回路に従って対応するスレーブデバイスアドレスを調整する必要があることに注意してください.
IOポートを用いてI 2 C通信をシミュレートするが、一般的にはシングルチップマシンにI 2 C機能がない場合にのみ使用される.シングルチップマシン自体がI 2 C機能を有する場合、シングルチップマシン対応のレジスタを構成することによってI 2 C通信を中断することによって実現すべきである.シミュレーションSCLが採用する遅延は空待ちであり、オペレーティングシステム全体にとって資源の浪費であるため、また、他のタスクの実行にも影響を及ぼす可能性があります.