I2CInit
IIC初始化步骤:
1、复位外设:LPC_SYSCON->PRESETCTRL |= (0x1<<1);
2、时钟使能:LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);
3、定义GPIO管脚,选择IIC功能管脚SCL、SDA:
LPC_IOCON->PIO0_4 &= ~0x3F; /* I2C I/O config */
LPC_IOCON->PIO0_4 |= 0x01; /* I2C SCL */
LPC_IOCON->PIO0_5 &= ~0x3F;
LPC_IOCON->PIO0_5 |= 0x01; /* I2C SDA */
4、清空IIC寄存器
LPC_I2C->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
5、设置高低电平寄存器
LPC_I2C->SCLL
LPC_I2C->SCLH
6、设置从地址寄存器
7、中断使能
NVIC_EnableIRQ(I2C_IRQn);
8、接口使能
LPC_I2C->CONSET = I2CONSET_I2EN;
具体步骤完成如下:
1、 IIC复位外设
LPC_SYSCON->PRESETCTRL |= (0x1<<1);
LPC_SYSCON:系统控制
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000) //APB外设系统控制地址
#define LPC_APB0_BASE (0x40000000UL) //APB外设在系统中的地址
1.1、外设复位控制,复位取消
LPC_SYSCON->PRESETCTRL |= (0x1<<1); //IIC复位取消
LPC_SYSCON_TypeDef->PRESETCTRL //默认值
__IO uint32_t PRESETCTRL; /*!< Offset: 0x004 Peripheral reset control (R/W) */
2、使能IIC时钟(AHBCLKCTRL寄存器控制系统和外设寄存器接口的时钟使能)
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
__IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 System AHB clock control (R/W) */
3、定义GPIO管脚,选择IIC功能管脚SCL、SDA
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_APB0_BASE (0x40000000UL)
3.1、LPC_IOCON->PIO0_4 &= ~0x3F; /* I2C I/O config [5:0]=0*/
3.2、LPC_IOCON->PIO0_4 |= 0x01; /* I2C SCL */
__IO uint32_t PIO0_4; /*!< Offset: 0x030 I/O configuration for pin PIO0_4/SCL (R/W) */
3.3、LPC_IOCON->PIO0_5 &= ~0x3F; /* I2C I/O config [5:0]=0*/
3.4、LPC_IOCON->PIO0_5 |= 0x01; /* I2C SDA */
4、清空IIC寄存器
4.1、#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE)
#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000)
#define LPC_APB0_BASE (0x40000000UL)
/*--- Clear flags ---*/
I2CONCLR寄存器控制对I2CON寄存器中的位的清零,这些位控制I2C接口的操作。向该寄存器写入1会清零寄存器中对应的位,向这个寄存器中写入0无效
LPC_I2C->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
__O uint32_t CONCLR; /*!< Offset: 0x018 I2C Control Clear Register ( /W) */
#define I2CONCLR_AAC 0x00000004 /*[2:0]=0000 0100*/ /* I2C Control clear Register */
#define I2CONCLR_SIC 0x00000008 /*[3:0]=0000 1000*/
#define I2CONCLR_STAC 0x00000020 /*[5:0]=0010 0000*/
#define I2CONCLR_I2ENC 0x00000040 /*[6:0]=0100 0000*/
5、设定IIC时钟高低电平时间比
#if FAST_MODE_PLUS
5.1、LPC_IOCON->PIO0_4 |= (0x1<<9);
5.2、LPC_IOCON->PIO0_5 |= (0x1<<9);
5.1、LPC_I2C->SCLL = I2SCLL_HS_SCLL; // IIC时钟的低电平时间
5.2、LPC_I2C->SCLH = I2SCLH_HS_SCLH; //IIC时钟的高电平时
__IO uint32_t SCLH; /*!< Offset: 0x010 SCH Duty Cycle Register High Half Word (R/W) */
__IO uint32_t SCLL; /*!< Offset: 0x014 SCL Duty Cycle Register Low Half Word (R/W) */
#define I2SCLH_HS_SCLH 0x00000020 /* Fast Plus I2C SCL Duty Cycle High Reg */
#define I2SCLL_HS_SCLL 0x00000020 /* Fast Plus I2C SCL Duty Cycle Low Reg */
#else
5.3、LPC_I2C->SCLL = I2SCLL_SCLL;
5.4、LPC_I2C->SCLH = I2SCLH_SCLH;
#endif
#define I2SCLH_SCLH 0x00000180 /* I2C SCL Duty Cycle High Reg */
#define I2SCLL_SCLL 0x00000180 /* I2C SCL Duty Cycle Low Reg */
6、设置从地址寄存器
if ( I2cMode == I2CSLAVE )
{
LPC_I2C->ADR0 = slaveAddr;
}
#define I2CSLAVE 0x02
__IO uint32_t ADR0; /*!< Offset: 0x00C I2C Slave Address Register 0 (R/W) */
7、IIC中断使能
/* Enable the I2C Interrupt */
NVIC_EnableIRQ(I2C_IRQn);
/**
* @brief Enable Interrupt in NVIC Interrupt Controller
* @param IRQn The positive number of the external interrupt to enable
* Enable a device specific interupt in the NVIC interrupt controller.
* The interrupt number cannot be a negative value.
*/
static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
}
#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
8、IIC接口使能
LPC_I2C->CONSET = I2CONSET_I2EN;
#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE)
__IO uint32_t CONSET; /*!< Offset: 0x000 I2C Control Set Register (R/W) */
#define I2CONSET_I2EN 0x00000040 /*[6:0]=0100 0000*/ /* I2C Control Set Register */