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

📄 i2c.bak

📁 IIC通信
💻 BAK
字号:
#pragma sfr
#pragma DI
#pragma EI
#pragma NOP

#include "defines.h"

#define  MEMORY_IMS_SET		0xC8
#define  MEMORY_IXS_SET		0x0A		//for 881

typedef	unsigned char	UCHAR;
typedef	unsigned int	UINT;

UCHAR a[1]={0x01};
UCHAR b[1];

bit ACK;

void main(void);
extern void hdwinit(void);
extern void Lvi_Init(void);
void I2C_Init( void );
void Start( void );
void Stop( void );
void Ack( void );
void NoAck( void );
void CHECK_ack( void );
void Send( UCHAR Data );
UCHAR Read(void);
UCHAR WrToROM(UCHAR Data[],UCHAR Address,UCHAR Page);
UCHAR RdFromROM(UCHAR DATA[],UCHAR Address,UCHAR Page);
void WT(UCHAR number );

void hdwinit( void )  //PM == 0 output
{						                 
	DI();
	IMS = MEMORY_IMS_SET;    
	IXS = MEMORY_IXS_SET;
										// Clock operation port mode (OSCCTL register)
	AMPH   = 0;       // select the external Clock frequency range(4MHz < fXH <= 10MHz)
    EXCLK  = 0;       //select the externa High-speed system clock operation mode(fX or fEXCLK or STOP)
    OSCSEL = 1;                         // External resonator connected to fX1 and fX2 input
	EXCLKS = 0;                         //(fXT or fEXCLKS or STOP)
	OSCSELS = 0;						// XT1 stop working
	
	// (permit) High-speed input clock operating (X1)
    MOC  = 0x00;                        
                                        // 00000000 = 0x00
                                        // |-------   High-speed input clock operation
                                        // |-------   --------------------------------
                                        // |-------   fXH input clock             | External clock input
                                        // |-------   ----------------------------+-------------------------
                                        // 0 -------- fXH input clock oscillating | External clock operating
                                        // 1 -------- fXH input clock stopped     | External clock stopped

// Check Oscillation stabilization time status

//waiting for the X1 clock oscillation stabilization time 
//--------------------------------------------
// The necessary oscillation stabilization time must be known beforehand.
// Pls. refer to the DS or UM of the oscillator manufacturer.
    while(OSTC < 0x1f)                  // Wait until fXH clock stabilization
    {                                   // time has been elapsed

        //----------------------------------------------------------
        // During X1 oscillation stabilization time status check
        // some other initializations, e.g. ports, can be done,
        // dependent on the needed X1 oscillation stabilization time
        // 102.4祍...3.28ms @ 20MHz
        //----------------------------------------------------------

        NOP();
    }

  //Oscillation stabilization time after STOP mode release
  //The wait time set by OSTS is valid only after the STOP mode is released with the X1 clock selected as the CPU clock. 
    OSTS = 0x01;                        // 512us@4MHz wait after STOP mode release (RESET value)
                                        // 00000101 = 0x05
                                        // -----|||   Osc. stabilization time
                                        // -----|||   -----------------------
                                        // -----001 - 2^11/fx
                                        // -----010 - 2^13/fx
                                        // -----011 - 2^14/fx
                                        // -----100 - 2^15/fx
                                        // -----101 - 2^16/fx
                                        // -----other settings prohibited



//This register is used to select the CPU clock and the division ratio
//---------------------------------------------
    PCC  = 0x00;                        // Use high speed mode fCPU = 4MHz
                                        // 00000000 = 0x00
                                        // -----|||   CPU clock selection fCPU
                                        // -----|||   ------------------------
                                        // -----000 - fx
                                        // -----001 - fx/2
                                        // -----010 - fx/2^2
                                        // -----011 - fx/2^3
                                        // -----100 - fx/2^4
                                        // -----other settings prohibited


// selects the main system clock supplied to CPU clock and clock supplied to peripheral hardware clock. 
//-----------------------------------------------------------------
// The maximum time required to switch between ring oscillator clock and
// fXH clock is 2 clocks

 // fXH clock supplied to the peripherals
    XSEL = 1;                         

    do
    {
        MCM0 = 1;                       // fXH clock supplied to CPU
                                        // 00000001 = 0x01
                                        // -----|||   CPU clock status
                                        // -----|||   ----------------
                                        // -----||0 - Operates with ring oscillator clock
                                        // -----||1 - Operates with X1 input clock
                                        // -----||
                                        // -----||    Selection of clock supplied to CPU and peripherals
                                        // -----||    --------------------------------------------------
                                        // -----00 -- fCPU = fRH / fPRS = fRH
                                        // -----01 -- fCPU = fRH / fPRS = fRH
                                        // -----10 -- fCPU = fRH / fPRS = fXH
                                        // -----11    fCPU = fXH / fPRS = fXH <---
                                        //      |
                                        //      +---- XSEL

    }
   while(MCS != 1);                    // Check if CPU operates with fXH clock( bit MCS IS read-only)
                                        // If no  => Retry to switch CPU clock
                                        // If yes => continue

// Switch off the high-speed and the low-speed Ring-OSC
//-----------------------------------------------------
// select the operation mode of internal oscillator  (all stop) 
    RCM  = 0x01;                        // High-speed Ring-OSC oscillating
                                        // High-speed Ring-OSC low accuracy (stop)
                                        // Low-speed Ring-OSC oscillating (stop)
                                        // 00000000 = 0x00
                                        // |-----||   High-speed Ring-OSC operation
                                        // |-----||   -----------------------------
                                        // |-----|0 - High-speed Ring-OSC oscillating
                                        // |-----|1 - High-speed Ring-OSC stopped
                                        // |-----|
                                        // |-----|    Low-speed Ring-OSC operation
                                        // |-----|    ----------------------------
                                        // |-----0 -- Low-speed Ring-OSC oscillating
                                        // |-----1 -- Low-speed Ring-OSC stopped
                                        // |
                                        // |          High-speed Ring-OSC accuracy status
                                        // |          -----------------------------------
                                        // 0 -------- High-speed Ring-OSC low accuracy
                                        // 1 -------- High-speed Ring-OSC high accuracy
	EI();
}

void Lvi_Init( void )
{
	LVIMK = 1;					//disable LVI interrupt
	LVISEL = 0;					//Detect level of supply voltage
	LVIS = 0X02;				//detection voltage level:3.93V
	//LVIIF = 0;
	//LVIMK = 0;
	//LVIPR = 1;
	LVIMD = 0;					//generates intenal reset when the level is detected
	LVION = 1;					//enable LVI operation
}


void Start( void )
{
	Data_direction = 0;        //output mode
  	Sda = 1;
  	NOP();
	Scl = 1;
  	delay4_7;					// >4.7us
  	Sda = 0;                 // a high-to-low transition of SDA with SCL high
  	delay4;					// >4us
  	Scl = 0;
  	NOP();
  	NOP();
  	NOP();
  	NOP();
}

void Stop( void )  
{
  	Data_direction = 0;      //output mode
  	Sda = 0;
  	NOP();
  	Scl = 1;
  	delay4;					// >4us
  	Sda = 1;                //a low-to-high transition of SDA with SCL high
  	delay4_7;					// >4.7us
  	Scl = 0;
  	NOP();
  	NOP();
  	NOP();
  	NOP();
}

void Ack( void ) 
{
  	Data_direction = 0;					// output mode
  	Sda = 0;
  	NOP();
  	NOP();
  	NOP();
  	NOP();
  	Scl = 1;
  	delay4;					// >4us
  	Scl = 0;               // in the output mode of SDA, a high-to-low transition of SCL with SDA low
  	NOP();
  	NOP();
  	NOP();
  	NOP();
  	Sda = 1;
}

void NoAck( void )
{
  	Data_direction = 0;					// output mode
  	Sda = 1;
  	NOP();
  	NOP();
  	NOP();
  	NOP();
  	Scl = 1;
  	delay4;					// >4us
  	Scl = 0;
  	NOP();
  	NOP();
  	NOP();
  	NOP();
  	Sda = 0;
}

void CHECK_ack( void )
{
	UCHAR error_time = 255;
	ACK = 1;
	Sda = 1;
	Scl = 1;
	Data_direction = 1;					//input mode
  	NOP();
  	NOP();
  	NOP();
  	NOP();
	while ( Sda )
	{
		error_time--;
		if( error_time == 0 )
		{	
			ACK = 0;
			Data_direction = 0;					//output mode
			Scl = 0;
  			NOP();
  			NOP();
  			NOP();
  			NOP();
			return;
		}
	}
	ACK = 1;
	Data_direction = 0;					//output mode
	Scl = 0;
  	NOP();
  	NOP();
  	NOP();
  	NOP();
}

void Send( UCHAR Data ) 
{
  	UCHAR BitCounter; 					//bit number control
  	Data_direction = 0;							//output mode
  	for( BitCounter = 0;BitCounter < 8;BitCounter++ )
  	{
  		if( (Data << BitCounter) & 0x80 )
  			Sda = 1;
  		else
  			Sda = 0;
  		NOP();
  		NOP();
  		NOP();
  		NOP();
  		Scl = 1;
  		delay4;					// >4us
  		Scl = 0;
  	}
}

UCHAR Read(void) 
{
  	UCHAR temp=0;
  	UCHAR BitCounter;
  	Data_direction = 1;							// input mode
  	for( BitCounter = 0;BitCounter < 8;BitCounter++ )
  	{
  		NOP();
  		Scl = 0;
  		delay4_7;					// >4.7us
  		Scl = 1;						//Data available
  		NOP();
  		NOP();
  		NOP();
  		NOP();
  		temp <<= 1;
  		if( Sda == 1 ) temp++;
  		NOP();
  		NOP();
  		NOP();
  		NOP();
  	}
  	Scl = 0;
  	NOP();
  	NOP();
  	NOP();
  	NOP();
	Data_direction = 0;					//output mode
  	return( temp );
}

UCHAR WrToROM(UCHAR Data[],UCHAR Address,UCHAR Page)
{
    UCHAR *s;
	s=Data;	
	
	Start();                   
	Send(Page); 			      
	CHECK_ack();
	if( !ACK ) return(0);      
	
	Send(Address); 
	CHECK_ack();
	if( !ACK ) return(0);      
	
	Send(*s);
	CHECK_ack();
	if( !ACK ) return(0);      

   	Stop();
   	return(1);
}  

UCHAR RdFromROM(UCHAR DATA[],UCHAR Address,UCHAR Page)
{
    UCHAR *c;	
	c = DATA;    
    
	Start();                   
	Send(Page); 			      
	CHECK_ack();
	if( !ACK ) return(0);      
	
	Send(Address); 
	CHECK_ack();
	if( !ACK ) return(0);      
	
	Start();                   
	Send(Page+1); 			      
	CHECK_ack();
	if( !ACK ) return(0);      

	*c= Read();
    NoAck();
    
	Stop();
	return(1);                 
}
void WT(UCHAR number )
{
	WTIIF = 0;
	WTIMK = 1;
	WTIPR = 1;		        /* low priority level */
	WTM= 0x70;	            /* interval time: 2^11/fw */
	/* Enable Watch timer operation */
	WTM0 = 1;
	while(number--){
	                while(!WTIIF);
	                }
	WTM0 = 0;
}

void I2C_Init( void )
{
	PM6.0 = 0;
	PM6.1 = 0;
	P6.0 = 0;
	P6.1 = 0;
}

void main(void)
{
  UCHAR W_Flag,R_Flag;
  DI();
  hdwinit();
  Lvi_Init();
  I2C_Init();
  EI();
  
  W_Flag=WrToROM(a,0x05,0xA0);
  WT(10);
  if(W_Flag)
  {
    R_Flag=RdFromROM(b,0x05,0xA0);
   }
  else
  {
    NOP();
  }
  while(1);
}


⌨️ 快捷键说明

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