i2c.c

来自「我写的针对lpc2141的ucos源码」· C语言 代码 · 共 196 行

C
196
字号
#include <LPC214X.H>
#include "i2c.h"
#include "irq.h"
#include "stdio.h"

static I2C_WR_UNIT *wr_unit;
static uint8 unit_num;
static uint8 unit_index;
static uint8 i2c_master_state;

// for debug
uint8 state_flag;

/*****************************************************************************
** Function name:		i2c0_init
**
** Descriptions:		Initialize I2C0 controller
**
** parameters:			I2c_mode is either MASTER or SLAVE
** Returned value:		true or false, return false if the I2C
**				interrupt handler was not installed correctly
** 
*****************************************************************************/
uint8 i2c0_init(uint8 i2c_mode)
{
	PINSEL0|=0X50;	 // pin select
	IODIR0|= 0x0C;	 /* set port 0.2 and port 0.3 to output, high */
    IOSET0|= 0x0C;

	/*--- Clear flags ---*/
    I2C0CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC; 

	I2C0SCLH=I2C0SCLH_SCLH;
	I2C0SCLL=I2C0SCLL_SCLL;

	if(i2c_mode==I2CSLAVE) {
		//load address to I2C0ADR and set AA
	}

    /* Install interrupt handler */	
    if ( install_irq( I2C0_INT, (void *)i2c0_irq_handler ) == FALSE )
    {
	return( FALSE );
    }
    I2C0CONSET = I2CONSET_I2EN;
    return( TRUE );
}

uint8 i2c0_start()
{
    uint32 timeout = 0;
    uint8 returnValue = FALSE;
 
    /*--- Issue a start condition ---*/
    I2C0CONSET = I2CONSET_STA;	/* Set Start flag */
    
    /*--- Wait until START transmitted ---*/
    while( 1 ){
		if ( i2c_master_state == I2C_STARTED ){
	    	returnValue = TRUE;
	    	break;	
		}
		
		if ( timeout >= MAX_TIMEOUT ){
	    	returnValue = FALSE;
	    	break;
		}
		timeout++;	
    }
    return( returnValue ); 

}

uint8 i2c0_stop()
{
    I2C0CONSET = I2CONSET_STO;      /* Set Stop flag */ 
    I2C0CONCLR = I2CONCLR_SIC;  /* Clear SI flag */ 
            
    /*--- Wait for STOP detected ---*/
    while( I2C0CONSET & I2CONSET_STO );//fix me
    return TRUE;
}

extern void i2c0_irq_handler( void ) __irq
{
	uint8 state;
	//static uint8 counter;
	state=I2C0STAT;
	//sendchar(state);
	//printf("state:%x\n",state);
	switch(state) {
		case 0x08:
			I2C0DAT=wr_unit[unit_index].device_addr;
			i2c_master_state=I2C_STARTED;
			I2C0CONCLR=I2CONCLR_STAC|I2CONCLR_SIC;
			break;

		case 0x10:
			//printf("state:%x\n",state);
			I2C0DAT=wr_unit[unit_index].device_addr;
			i2c_master_state=I2C_RESTARTED;
			I2C0CONCLR=I2CONCLR_STAC|I2CONCLR_SIC;
			break;

		case 0x18:
		case 0x20:
		case 0x28:
		case 0x30:
			if(wr_unit[unit_index].counter<wr_unit[unit_index].length) {
				I2C0DAT=wr_unit[unit_index].buffer[wr_unit[unit_index].counter];
				wr_unit[unit_index].counter++;
				i2c_master_state=I2C_DATA_ACK;
				I2C0CONCLR=I2CONCLR_SIC;
			}else {
				unit_index++;
				if(unit_index<unit_num) {
					i2c_master_state=I2C_REPEATED_START;
					I2C0CONSET=I2CONSET_STA;
				}else 
					i2c_master_state=I2C_DATA_NACK;
				I2C0CONCLR=I2CONCLR_SIC;	
			}
			break;

		case 0x40:
			if(wr_unit[unit_index].counter+1<wr_unit[unit_index].length)
				I2C0CONSET=I2CONSET_AA;
			else
				I2C0CONCLR=I2CONCLR_AAC;
			I2C0CONCLR=I2CONCLR_SIC;
			break;

		case 0x48:
			i2c_master_state=I2C_DATA_NACK;
			I2C0CONCLR=I2CONCLR_SIC;
			break;

		case 0x50:
			wr_unit[unit_index].buffer[wr_unit[unit_index].counter]=I2C0DAT;
			wr_unit[unit_index].counter++;
			if(wr_unit[unit_index].counter+1<wr_unit[unit_index].length) {
				i2c_master_state=I2C_DATA_ACK;
				I2C0CONSET=I2CONSET_AA;	
			}else
				I2C0CONCLR=I2CONCLR_AAC;
			I2C0CONCLR=I2CONCLR_SIC;
			break;

		case 0x58:
			wr_unit[unit_index].buffer[wr_unit[unit_index].counter]=I2C0DAT;
			unit_index++;
			if(unit_index<unit_num) {
				i2c_master_state=I2C_REPEATED_START;
				I2C0CONSET=I2CONSET_STA;
			}else 
				i2c_master_state=I2C_DATA_NACK;
			I2C0CONCLR=I2CONCLR_SIC;	
			break;
		default:
			break;
	}
	VICVectAddr=0x0;

}


uint8 i2c0_operation(I2C_WR_UNIT *operation, uint8 num)
{
	uint8 i;
	wr_unit=operation;
	unit_num=num;
	unit_index=0;

	for(i=0;i<unit_num;i++)
		wr_unit[i].counter=0;

	
	i2c_master_state=I2C_IDLE;

	if ( i2c0_start() != TRUE ){
		i2c0_stop();
		return ( FALSE );
    }

	while(1) {
		if(i2c_master_state==I2C_DATA_NACK) {
			i2c0_stop();
			break;
		}
	}
	return TRUE;

}


⌨️ 快捷键说明

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