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;
}

以上实现了读取单个字节,如果需要连续读写多个字节,只须在读写字节部分增加循环读写就可以。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值