STM32 FMPI2C 简单访问代码

本文详细介绍了STM32微控制器中FMPI2C模块的使用方法,包括初始化配置、读写操作的实现代码。通过具体的代码示例,帮助读者理解如何在STM32上实现I2C通信,特别适用于DMAStream占用情况下的直接访问编程。

网上这方面内容较少,又由于DMA Stream全部被占,所以自己写了一个简单的直接访问代码,供需要者参考。

1. 初始化:

void InitFMPI2C(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    FMPI2C_InitTypeDef  I2C_InitStructure;
  
    printf("Init FMP I2C\r\n");
    
    RCC_AHB1PeriphClockCmd(PERI_FMPI2C1_SCL_GPIO_CLK | PERI_FMPI2C1_SDA_GPIO_CLK, ENABLE);
    RCC_APB1PeriphClockCmd(PERI_FMPI2C1_CLK, ENABLE);
    RCC_APB1PeriphResetCmd(PERI_FMPI2C1_CLK, ENABLE);    
   
    RCC_APB1PeriphResetCmd(PERI_FMPI2C1_CLK, DISABLE);

    /* Connect PXx to I2C_SCL*/
    GPIO_PinAFConfig(PERI_FMPI2C1_SCL_GPIO_PORT, PERI_FMPI2C1_SCL_SOURCE, PERI_FMPI2C1_SCL_AF);    
    /* Connect PXx to I2C_SDA*/
    GPIO_PinAFConfig(PERI_FMPI2C1_SDA_GPIO_PORT, PERI_FMPI2C1_SDA_SOURCE, PERI_FMPI2C1_SDA_AF);
    
    /* GPIO configuration */  
    /* Configure sEE_I2C pins: SCL */
    GPIO_InitStructure.GPIO_Pin = PERI_FMPI2C1_SCL_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(PERI_FMPI2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
    
    /* Configure sEE_I2C pins: SDA */
    GPIO_InitStructure.GPIO_Pin = PERI_FMPI2C1_SDA_PIN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_Init(PERI_FMPI2C1_SDA_GPIO_PORT, &GPIO_InitStructure);    

    I2C_InitStructure.FMPI2C_Mode = FMPI2C_Mode_FMPI2C;
    I2C_InitStructure.FMPI2C_Timing = 0x00308FF9; //0x00303D5B;  // 此数由Stm32CubeMX工具产生。
    I2C_InitStructure.FMPI2C_AnalogFilter = FMPI2C_AnalogFilter_Enable;
    I2C_InitStructure.FMPI2C_AcknowledgedAddress = FMPI2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.FMPI2C_Ack = FMPI2C_Ack_Enable;

    FMPI2C_Init(PERI_FMPI2C1, &I2C_InitStructure);
    FMPI2C_Cmd(PERI_FMPI2C1, ENABLE);
}
 

2. Read,Write 实现:

static BYTE FMPI2C_CheckBusy(void)
{
    DWORD TimeOut = I2C_LONG_TIMEOUT;
    BYTE return_flag = I2C_OK;
    while (FMPI2C_GetFlagStatus(FMPI2C1, FMPI2C_FLAG_BUSY))
    {
        if((TimeOut--) == 0)
        {
            return_flag = I2C_NOT_FREE;
            break;
        }
    }

    return return_flag;
}

static BYTE FMPI2C_Start(BYTE dAddr, BYTE nSize, BYTE mode)
{
    FMPI2C_MasterRequestConfig(FMPI2C1, mode);
    FMPI2C_SlaveAddressConfig(FMPI2C1, dAddr);
    FMPI2C_NumberOfBytesConfig(FMPI2C1, nSize);
    FMPI2C_AutoEndCmd(FMPI2C1, ENABLE);
    FMPI2C_GenerateSTART(FMPI2C1, ENABLE);
    return I2C_OK;
}

static BYTE FMPI2C_GetByte()
{
    BYTE read;

    I2CTimeout = I2C_LONG_TIMEOUT;
    while(FMPI2C_GetFlagStatus(FMPI2C1, FMPI2C_FLAG_RXNE) == RESET)
        {if((I2CTimeout--) == 0) return I2C_TIME_OUT;}
    
    read = FMPI2C_ReceiveData(FMPI2C1);

    return read;
}

static void FMPI2C_Clear(void)
{
    FMPI2C1->ICR = 0x0000FFFF;
}

static BYTE FMPI2C_Wait_Event(DWORD event)
{
    DWORD TimeOut = I2C_LONG_TIMEOUT;
    BYTE return_flag = SET;
    while (!FMPI2C_GetFlagStatus(FMPI2C1, event))
    {
        if((TimeOut--) == 0)
        {
            return_flag = RESET;
            break;
        }
    }

    return return_flag;
    
}

//--------------------------------------------------------------------------------------------------------------------------
BYTE FMPI2C_Write(BYTE dAddr, BYTE rAddr, PBYTE pBuff, WORD bytes)
{
    uint32_t i = 0, j = 0;

    if(FMPI2C_CheckBusy())
    {
        printf("FMP I2C Busy!\r\n");
        return I2C_NOT_FREE;
        
    }
    FMPI2C_Clear();

    FMPI2C_Start(dAddr, bytes+1, I2C_Direction_Transmitter);
    
    if(FMPI2C_Wait_Event(FMPI2C_FLAG_TXIS))
    {
        FMPI2C_SendData(FMPI2C1, rAddr);
        j = 0;
    }
    else {
        printf("FMP I2C Write Error Start[%08X]\r\n", FMPI2C1->ISR);
        return I2C_NOT_START;
    }
    
    for (i=0; i<bytes; i++)
    {
        if(FMPI2C_Wait_Event(FMPI2C_FLAG_TXIS))
        {
            FMPI2C_SendData(FMPI2C1, pBuff[i]);
            j++;
        }
        else
        {
            printf("FMP I2C Write Data Error[%d][%08X]\r\n", j, FMPI2C1->ISR);
        }
    }
    
    if(!FMPI2C_Wait_Event(FMPI2C_FLAG_STOPF))
    {
        printf("FMP I2C Write STOP error[%08X]\r\n", FMPI2C1->ISR);
    }
    FMPI2C_Clear();

    return I2C_OK;
}

//--------------------------------------------------------------------------------------------------------------------------
BYTE FMPI2C_Read(BYTE dAddr, BYTE rAddr, PBYTE pBuff, WORD bytes)
{
    uint32_t i;

    if(FMPI2C_CheckBusy())
    {
        printf("FMP I2C Busy!\r\n");
        return I2C_NOT_FREE;
    }
    FMPI2C_Clear();

    FMPI2C_Start(dAddr, 1, I2C_Direction_Transmitter);
    if(FMPI2C_Wait_Event(FMPI2C_FLAG_TXIS))
    {
        FMPI2C_SendData(FMPI2C1, rAddr);
    }
    else {
        printf("FMP I2C Error Start[%08X]\r\n", FMPI2C1->ISR);
        return I2C_NOT_START;
    }
    FMPI2C_Wait_Event(FMPI2C_FLAG_STOPF);
    
    //printf("FMP I2C Write STOP [%08X]\r\n", FMPI2C1->ISR);

    FMPI2C_ClearFlag(FMPI2C1, FMPI2C_FLAG_STOPF);

    //return I2C_NO_DATA;
    if(FMPI2C_CheckBusy())
    {
        printf("FMP I2C Busy!\r\n");
        return I2C_NOT_FREE;
    }
    FMPI2C_Clear();
    
    FMPI2C_Start(dAddr, bytes, I2C_Direction_Receiver);

    for (i=0; i<bytes; i++){
        pBuff[i] = FMPI2C_GetByte();
    }
        
    FMPI2C_Wait_Event(FMPI2C_FLAG_STOPF);
    FMPI2C_Clear();

    return I2C_OK; 
}
 

 

*** Using Compiler 'V5.06 update 5 (build 528)', folder: 'D:\Keil 524\ARM\ARMCC\Bin' Rebuild target 'Target 1' assembling startup_stm32f411xe.s... compiling stm32f4xx_dcmi.c... compiling stm32f4xx_it.c... compiling stm32f4xx_dac.c... compiling stm32f4xx_cryp_tdes.c... compiling misc.c... compiling stm32f4xx_cryp_des.c... compiling stm32f4xx_can.c... compiling stm32f4xx_dbgmcu.c... compiling stm32f4xx_adc.c... compiling stm32f4xx_cryp.c... compiling stm32f4xx_cec.c... compiling stm32f4xx_crc.c... compiling system_stm32f4xx.c... compiling stm32f4xx_cryp_aes.c... compiling stm32f4xx_dfsdm.c... compiling stm32f4xx_dma.c... compiling stm32f4xx_dma2d.c... compiling stm32f4xx_flash.c... compiling stm32f4xx_dsi.c... compiling stm32f4xx_exti.c... compiling stm32f4xx_flash_ramfunc.c... compiling stm32f4xx_ltdc.c... compiling stm32f4xx_iwdg.c... compiling stm32f4xx_i2c.c... compiling stm32f4xx_lptim.c... compiling stm32f4xx_fmpi2c.c... compiling stm32f4xx_gpio.c... compiling stm32f4xx_hash.c... compiling stm32f4xx_hash_md5.c... compiling stm32f4xx_hash_sha1.c... compiling main.c... ..\USER\main.c(2): error: #5: cannot open source input file "tjc_usart_hmi.h": No such file or directory #include "tjc_usart_hmi.h" ..\USER\main.c: 0 warnings, 1 error compiling tjc_usart_hmi.c... tjc_usart_hmi.h(27): warning: #1-D: last line of file ends without a newline #endif tjc_usart_hmi.c(7): error: #5: cannot open source input file "stm32f10x_usart.h": No such file or directory #include <stm32f10x_usart.h> tjc_usart_hmi.c: 1 warning, 1 error compiling stm32f4xx_qspi.c... compiling stm32f4xx_pwr.c... compiling stm32f4xx_rtc.c... compiling stm32f4xx_rcc.c... compiling stm32f4xx_sai.c... compiling stm32f4xx_rng.c... compiling stm32f4xx_syscfg.c... compiling stm32f4xx_sdio.c... compiling stm32f4xx_wwdg.c... compiling stm32f4xx_spdifrx.c... compiling stm32f4xx_spi.c... compiling stm32f4xx_usart.c... compiling stm32f4xx_tim.c... "..\OUTPUT\STM32F411CEU6.axf" - 2 Error(s), 1 Warning(s). Target not created. Build Time Elapsed: 00:03:35
08-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值