STM32F0 硬件I2C驱动调试
本以为很快能搞定,结果还是花了大半天,大意地把下面两句合并成一句了:
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6 | GPIOB, GPIO_PinSource7, GPIO_AF_1); //错误写法
下面把代码贴出来,供大家参考,避免浪费时间。
void I2C1_init()
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
I2C_DeInit(I2C1);
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);//时钟源设定
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //使能I2C1的时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1); //配置PB6 PB7 成第二功能引脚
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x01;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_Timing = 0x40B22536; //100kHz 0x10950C27; //400kHz
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
/*************************************************************
* 名 称:I2C_ByteWrite
* 功 能:I2C写入单字节
* 入口参数:addr 写入数据的地址
* data 写入数据
* 出口参数:无
* 说 明:
**************************************************************/
void I2C_ByteWrite(INT8U addr, INT8U data)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);
I2C_TransferHandling(I2C1, MPL3115_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);
I2C_SendData(I2C1, addr);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TCR) == RESET);
I2C_TransferHandling(I2C1, MPL3115_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);
I2C_SendData(I2C1, data);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);
}
/*************************************************************
* 名 称:I2C_ByteRead
* 功 能:I2C读取单字节
* 入口参数:读取地址
* 出口参数:读取的一个字节
* 说 明:每个AD字0.305mV
**************************************************************/
UINT8 I2C_ByteRead(INT8U addr)
{
UINT8 ret;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);
I2C_TransferHandling(I2C1, MPL3115_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);
I2C_SendData(I2C1, addr);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET);
I2C_TransferHandling(I2C1,MPL3115_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET);
ret = I2C_ReceiveData(I2C1);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);
return ret;
}
以上实现了读取单个字节,如果需要连续读写多个字节,只须在读写字节部分增加循环读写就可以。