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

📄 upsd_i2c.c

📁 Demo for I2C Master and Slave
💻 C
📖 第 1 页 / 共 2 页
字号:
return value:I2C_MR_END		8			//Indicate a receiving has been finished in master modelI2C_TIME_OUT	9			//Indicate I2C overtime.I2C_NACK		13			//Indicate I2C no acknowledgeI2C_BUSLOST		14			//Indicate I2C bus lostI2C_BUSY		16			//Indicate I2C bus is busy-------------------------------------------------------------------------*/unsigned char upsd_i2c_Master_Recv (unsigned char Slave_Addr, 							unsigned char* Data_Ptr,							unsigned char N){	EA=0;	i2c_master = 1;  					// set up for master	i2c_rcv_buf= Data_Ptr;	if(upsd_i2c_Busycheck(1000)==1){		S2CON&=~STA;		S2CON|=STO;				dummybyte=S2DAT;		i2c_state=I2C_BUSY;		return (i2c_state);	}					 				// Bus busy and return current state of I2C	i2c_data_len=N;	     				// Initialize i2c_data_len to specify communicated data length	i2c_master = 1;	i2c_xmitr = 0;						// set flags for master receiver	S2DAT = (Slave_Addr | 0x01);		// set up i2c address (set R/W bit)	S2CON |= ENI;		   				// Set ENI (Enable I2C-2)	S2CON &= ~STO;						// Clr STO in S1CON	S2CON |= STA;						// Set STA (Send start bit)	S2CON &= ~AA;						// Clr AA in S2CON	i2c_data_index=0;	i2c_state=I2C_MR;	EA=1;	if(upsd_i2c_Timeout(I2C_MR,1000)==1){		EA=0; 		S2CON&=~STA;		S2CON|=STO;		dummybyte=S2DAT;		S2CON&=~ENI;S2CON|=ENI;		i2c_state=I2C_TIME_OUT;		return (i2c_state);	}									// I2C master receive timeout	else {		EA=0;		return(i2c_state); 	}									// return I2C current state}/*-------------------------------------------------------------------------unsigned char upsd_i2c_Slave_Xmit(unsigned char* Data_Ptr,								  unsigned char* N_Ptr)This function is used to transmit data to master, only for Slave.Data_Ptr	- unsigned char*			- address pointer of transmit bufferN_Ptr		- unsigned char*			- the length of data buffer transmitted to master. return value:I2C_SX_END		6			//Indicate a transmitting has been finished in Slave modelI2C_TIME_OUT	9			//Indicate I2C overtime.I2C_NACK		13			//Indicate I2C no acknowledgeI2C_BUSLOST		14			//Indicate I2C bus lostI2C_BUSY		16			//Indicate I2C bus is busy-------------------------------------------------------------------------*/unsigned char upsd_i2c_Slave_Xmit(unsigned char* Data_Ptr,								  unsigned char* N_Ptr){	EA=0;	i2c_xmit_buf=Data_Ptr;	i2c_master = 0;	i2c_xmitr = 1;								// set up for Slave transmitter	S2CON &= ~AA;						    	// disable ACK and STOP control bit to prepare transmit data	S2CON &= ~STO;	i2c_data_index=0;	S2DAT = i2c_xmit_buf[i2c_data_index];  		//Send first data to master	i2c_data_index++;	i2c_state=I2C_SX;	EA=1;	if(upsd_i2c_Timeout(I2C_SX,1000)==1){		EA=0;		i2c_state=I2C_TIME_OUT;		S2DAT=dummy;		return(i2c_state);	}	   										// I2C Slave timeout return	else {		EA=0;		*N_Ptr=i2c_data_index;		S2DAT=dummy;		return(i2c_state);	}			    							// return current I2C state and the length of data 												//  buffer transmitted to master.}/*-------------------------------------------------------------------------unsigned char upsd_i2c_Slave_Recv(unsigned char* Data_Ptr,								  unsigned char* N_Ptr)This function is used to receive data from master, only for Slave.Data_Ptr	- unsigned char*			- address pointer of receive bufferN_Ptr		- unsigned char*			- the length of data buffer received from master. return value:I2C_TIME_OUT	9			//Indicate I2C overtime.I2C_SR_END		11			//Indicate a receiving has been finished in Slave modelI2C_NACK		13			//Indicate I2C no acknowledgeI2C_BUSLOST		14			//Indicate I2C bus lostI2C_SX_APP		15			//Indicate I2C Slave is required to transmit data to masterI2C_BUSY		16			//Indicate I2C bus is busy-------------------------------------------------------------------------*/unsigned char upsd_i2c_Slave_Recv(unsigned char* Data_Ptr,								  unsigned char* N_Ptr){	EA=0;	i2c_rcv_buf=Data_Ptr;	i2c_master = 0;  	i2c_xmitr = 0;					// set up for Slave transmitter	i2c_data_index=0;	i2c_state=I2C_SR;	slave_addressed = 0;			S2CON|=AA;//	idle_mode = 0;					// indicate not in idle mode#if IDLE_MODE_DEMO				    // only here for idle mode demonstration purposes	ET0 = 0;						// disable timer 0 int. so only I2C int brings uPSD out of idle mode//	idle_mode = 1;					// indicate in idle mode (I2C init function and ISR clears this flag)	PSD8xx_reg.DATAOUT_B&=0xFC;		// PB0 & PB1 = 0 - (LEDs on)#endif	EA=1;#if IDLE_MODE_DEMO				    // only here for idle mode demonstration purposes	PCON |= 0x01;   				// puts uPSD in idle mode	PSD8xx_reg.DATAOUT_B|=0x03;		// PB0 & PB1 = 1 - (LEDs off)	ET0 = 1;						// enable timer 0 interrupt#endif	if(upsd_i2c_Timeout(I2C_SR,1000)==1){		EA=0;		i2c_state=I2C_TIME_OUT;		return(i2c_state); 	}	    									//Slave receive timeout	else {		EA=0;   				*N_Ptr=i2c_data_index-1;		return(i2c_state);	}											// Return I2C current state}/*------------------------------------------------------------------------	 I2C Interrupt Service Routine------------------------------------------------------------------------*/ void i2c_isr (void) interrupt I2C_VECTOR using 2 {	dummybyte=S2STA;											// Clear INTR flag	toggle = 0;													// Reset timeout counter	//------Master transmit operation--------------------------------------------	if (i2c_master & i2c_xmitr)									// mstr transmitter mode	{		S2CON &= ~STA;											// clear STA		if ((S2STA & BLOST) !=0) 								// if bus lost, read dummybyte to turn to Slave mode		{			S2DAT=dummy;			i2c_state=I2C_BUSLOST;								// Indicate the bus lost			return;		}			else if ((S2STA & _ACKREP) !=0)		{			S2CON |=STO;			S2DAT=dummy; 										// if no ACK, send STOP condition to Bus			i2c_state=I2C_NACK;									// Indicate no ACK			return;  											}		if((i2c_data_index)<(i2c_data_len-1))		{			S2DAT = i2c_xmit_buf[i2c_data_index];	 			// send data from Master			i2c_data_index++;  									// increment data-pointer		}		else if((i2c_data_index)==(i2c_data_len-1))		{   			S2CON |= STO;										// set STO (stop bit) for last data byte to send			S2DAT = i2c_xmit_buf[i2c_data_index];	 			// send data from Master			i2c_data_index++; 						 			}		else if((i2c_data_index)==(i2c_data_len))		{			S2DAT=dummy;			i2c_state=I2C_MX_END;					   			// Indicate the operation has completed		}	}	//------Master receive operation--------------------------------------------	if (i2c_master & ~i2c_xmitr)								// master receive mode	{		S2CON &= ~STA;											// clear STA		if(i2c_data_index<i2c_data_len)		{			if((S2CON&AA)==0)			{				S2DAT=dummy;									//				if ((dummybyte & _ACKREP) !=0)				{					S2CON |=STO;					i2c_data_index=0;					S2DAT=dummy;					i2c_state=I2C_NACK;							// indicate no ACK					return;  													}				else if(i2c_data_len == 1)				{					S2CON&=~AA;					i2c_data_index ++;					return;				}				else				{					S2CON |= AA;   								// enable ACK					i2c_data_index ++;					return;				}			}  					else			{																// Begin receiving data				i2c_rcv_buf[i2c_data_index-1] = S2DAT;	   		// receive data				i2c_data_index++;						  		// increment data-pointer				if(i2c_data_index==i2c_data_len){S2CON&=~AA;}			}		}		else if(i2c_data_index==i2c_data_len) 					// End the reception of data		{			S2CON |=STO;			i2c_rcv_buf[i2c_data_index-1] = S2DAT;			i2c_state=I2C_MR_END;								// indicate operation has completed		}	}	//------Slave operation--------------------------------------------	if(i2c_master==0)	{ 		if(((S2CON&ADDR)!=0)||!i2c_processing)	// if ADDR bit is set or if coming out of idle		{									    //   mode, then a START and address match detected.			i2c_processing = 1;					// indicate processing I2C transaction			S2CON&=~ADDR;										//Clear ADDR flag			slave_addressed = 1;			if(dummybyte & TX_MODE)			{				i2c_state=I2C_SX_APP;							// indicate Slave is required to transmit data to master				S2CON &= ~AA;								    // disable ACK				}			else			{				S2DAT=dummy;  									// Write dummy				i2c_xmitr=0; 									// set up for Slave receive				S2CON |=AA;							    		// enable ACK to prepare receive data				i2c_data_index=0;				i2c_state=I2C_SR;								// indicate Slave is receiving			}		}		else		{			if(slave_addressed != 1)			{				return;			}			else if(i2c_xmitr==1)								//Slave transmit data				  			{				if(((dummybyte&STOP)!=0)||((dummybyte&_ACKREP)!=0)) //if STOP or NACK received, then master																	// is done reading data from slave.				{						S2DAT=dummy;					i2c_state=I2C_SX_END;						// indicate Slave transmitted all data					i2c_processing = 0;			        		// indicate not processing I2C transaction				}				else				{					S2DAT = i2c_xmit_buf[i2c_data_index];		// Send data					i2c_data_index++;							// Increment data-pointer				}			}			else if(i2c_xmitr==0)								// Slave receive data mode			{   		    	if((dummybyte & STOP)!=0)				{					S2DAT = dummy;						// STOP bit received while in slave receiver mode					S2CON &= ~ENI;						// This disable/enable I2C is needed for transfers					S2CON |= ENI;						//  from master without data (START-ADDR-WRITE-STOP).														// This type of transfer is used by a master as a														//  type of device detect.  If the slave ACKS, then														//  the device is detected by the master.					i2c_state = I2C_SR_END;				// Indicate the data has been received completely 					i2c_processing = 0;			        // indicate not processing I2C transaction					S2CON &= ~AA; 						// Disable ACK.				}				i2c_rcv_buf[i2c_data_index] = S2DAT;			// Get data byte from Master				i2c_data_index++;								// increment data-pointer			}		}	}}

⌨️ 快捷键说明

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