[MCU] 灵动微 MM32F103CxT6硬件IIC

火辣西米秀   2022-3-17 07:25 楼主

/**

  * [url=home.php?mod=space&uid=159083]@brief [/url]  Configures I2C Device port.

  * @param  ulSpeed I2C baudrate.

  * @retval None

  */

static void Config_I2cDevice ( uint32_t ulSpeed )

{

        GPIO_InitTypeDef xGPIO_InitStruct;

        I2C_InitTypeDef xI2C_InitStruct;

        

        /* Enable clock. */

        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );        

        RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );

        

        /* Configure scl & sda GPIO parameters. */

        xGPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;

        xGPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

        xGPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;

        GPIO_Init( GPIOB, &xGPIO_InitStruct );

        

        /* Configure I2C parameters. */

        xI2C_InitStruct.I2C_ClockSpeed = ulSpeed;

        xI2C_InitStruct.I2C_Mode = I2C_Mode_MASTER;

        xI2C_InitStruct.I2C_OwnAddress = 0x0;

        if ( ulSpeed <= 100000 ) { /* Configure speed in standard mode */

                xI2C_InitStruct.I2C_Speed = I2C_Speed_STANDARD;

        } else { /* Configure speed in fast mode */

                xI2C_InitStruct.I2C_Speed = I2C_Speed_FAST;

        }

        I2C_Init( I2C1, &xI2C_InitStruct );

        

        /* Enable i2c1 port. */

        I2C_Cmd( I2C1, ENABLE );

}

I2C 硬件驱动
(a)、 根据官方提供源码修改,并且将其封装在 HAL_i2c 库文件内;
(b)、 该OLED 仅需要 写操作;
(c)、 在发送 STOP 停止信号前需延时 5us 才能正常显示(后续再找原因)。

复制
/**

  * @brief  Writes buffer of data to the I2C EEPROM.

  * @param  pxIO :typedef struct { GPIO_TypeDef* xPort; uint16_t usScl; uint16_t usSda; }I2C_GPIO_t;

  * @param  pBuffer : pointer to the buffer  containing the data to be written 

  *         to the EEPROM.

  * @param  WriteAddr : EEPROM's internal address to write to.

  * @param  NumByteToWrite : number of bytes to write to the EEPROM.

  * @retval None

  */

ErrorStatus I2C_WriteBuffer( const I2C_GPIO_t* pxIO, I2C_TypeDef* I2Cx, uint8_t DeviceAddr, uint8_t WriteAddr, uint16_t NumByteToWrite, uint8_t* pBuffer)

{

        uint32_t I2C_Timeout;

        uint16_t write_Num;

        

        GPIO_InitTypeDef xGPIO_InitStruct;

        xGPIO_InitStruct.GPIO_Pin  = pxIO->usScl | pxIO->usSda;

        xGPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;

        xGPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;

        GPIO_Init( pxIO->xPort, &xGPIO_InitStruct );

        I2C_Cmd(I2Cx, DISABLE);

        I2C_Send7bitAddress( I2Cx, DeviceAddr, I2C_Direction_Transmitter );

        I2C_Cmd(I2Cx, ENABLE);

        

        xGPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;

        GPIO_Init( pxIO->xPort, &xGPIO_InitStruct );

        

        I2C_SendData( I2Cx, WriteAddr );

        I2C_Timeout = 0x1000;

        

        while ( ( I2C_GetFlagStatus( I2Cx, I2C_STATUS_FLAG_TFE ) ) == RESET ) {

                if ( ( I2C_Timeout-- ) == 0 ) {

                        return ERROR;

                }

        }

        

        for ( write_Num=0; write_Num<NumByteToWrite; write_Num++ ) {

                I2C_Timeout = 0x1000;

        

                while ( ( I2C_GetFlagStatus( I2Cx, I2C_STATUS_FLAG_TFE ) ) == RESET ) {

                        if ( ( I2C_Timeout-- ) == 0 ) {

                                return ERROR;

                        }

                }

                I2C_SendData( I2Cx, *( pBuffer + write_Num ) );

        }

        

        /* 96MHz 工作频率下,延时5us. */

        for ( uint16_t i=480; i>0; i-- );

        

        I2C_GenerateSTOP( I2Cx, ENABLE );

        I2C_Timeout = 0x1000;

        

        while ( ( I2C_GetITStatus( I2Cx, I2C_IT_STOP_DET ) ) == RESET ) {

                if ( ( I2C_Timeout-- ) == 0 ) {

                        return ERROR;

                }

        }

        

        /* If all operations OK, return sEE_OK (0) */

  return SUCCESS;

}

OLED 程序模块
仅提供 Cmd & Data 部分,大部分和网络上的大同小异,可参考(正点原子、中景园电子、etc)。这篇**主要是 MM32 的 I2C

复制
/**

  * @brief  Write commands to the screen.

  * @param  ucCmd    Write command to be written.

  * @retval None.

  */

static void Screen_WriteCmd( uint8_t ucCmd )

{

        I2C_WriteBuffer( &xConfig, I2C_DEVICE, I2C_ADDR, 0x00, 1, &ucCmd );

}

/**

  * @brief  Write data to the screen.

  * @param  ucCmd    Write data to be written.

  * @retval None.

  */

static void Screen_WriteDat( uint8_t ucDat )

{

        I2C_WriteBuffer( &xConfig, I2C_DEVICE, I2C_ADDR, 0x40, 1, &ucDat );

}

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复