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 + -
显示快捷键?