STM32的硬件I2C调试确实要比模拟麻烦很多啊,一大堆的配置,调通F系列的,本以为直接移植到L系列会很轻松,没想到问题依然很多,现直接附上STM32L系列的I2C初始化及读写函数:
1.GPIO的初始化:
static void ADXL_LowLevel_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能与 I2C1 有关的时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*!< Configure sEE_I2C pins: SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect PXx to I2C_SCL*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
/* Connect PXx to I2C_SDA*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
}
2.I2C的初始化:
void I2C_ADXL_Init(void)
{
I2C_InitTypeDef I2C_InitStructure;
ADXL_LowLevel_Init();
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = ADXL_ADRESS;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
/* ADXL_I2C Peripheral Enable */
I2C_Cmd(I2C1, ENABLE);
/* Apply MEMS_I2C configuration after enabling it */
I2C_Init(I2C1, &I2C_InitStructure);
}
3.读
u8 I2C_ADXL_ByteRead(u8 ReadAddr)
{
u8 RxData;
/*wait until I2C bus is not busy*/
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send ADXL address for write */
I2C_Send7bitAddress(I2C1, ADXL_ADRESS, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* Send the ADXL's Register address to write to */
I2C_SendData(I2C1, ReadAddr);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET);
/* Send STRAT condition a second time */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send ADXL address for read */
I2C_Send7bitAddress(I2C1, ADXL_ADRESS, I2C_Direction_Receiver);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET);
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2C1, DISABLE);
(void)I2C1->SR2;
/*!< Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET);
/* Read a byte from the ADXL Register */
RxData = I2C_ReceiveData(I2C1);
while(I2C1->CR1 & I2C_CR1_STOP);
I2C_AcknowledgeConfig(I2C1, ENABLE);
return RxData;
}
4. 写
void I2C_ADXL_ByteWrite(u8 pBuffer, u8 WriteAddr)
{
/*wait until I2C bus is not busy*/
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send MMA address for write */
I2C_Send7bitAddress(I2C1, ADXL_ADRESS, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* Send the MMA's Register address to write to */
I2C_SendData(I2C1, WriteAddr);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send the byte to be written */
I2C_SendData(I2C1, pBuffer);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}