STM32H750XB_RT-THREAD/46-DCMI—OV5640摄像头实验/User/i2c/bsp_i2c.c
2025-07-21 14:34:29 +08:00

162 lines
4.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
******************************************************************************
* @file i2c.c
* @author fire
* @version V1.0
* @date 2015-xx-xx
* @brief i2c 总线驱动方便与各种I2C传感器通讯。
******************************************************************************
* @attention
*
* 实验平台:野火 STM32 H750 开发板
* 论坛 :http://www.firebbs.cn
* 淘宝 :http://firestm32.taobao.com
*
******************************************************************************
*/
#include "./i2c/bsp_i2c.h"
#include "./delay/core_delay.h"
I2C_HandleTypeDef I2C_Handle;
/******************************* Function ************************************/
/**
* @brief 初始化I2C总线使用I2C前需要调用
* @param 无
* @retval 无
*/
void I2CMaster_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能I2Cx时钟 */
SENSORS_I2C_RCC_CLK_ENABLE();
/* 使能I2C GPIO 时钟 */
SENSORS_I2C_SCL_GPIO_CLK_ENABLE();
SENSORS_I2C_SDA_GPIO_CLK_ENABLE();
/* 配置I2Cx引脚: SCL ----------------------------------------*/
GPIO_InitStructure.Pin = SENSORS_I2C_SCL_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Pull= GPIO_NOPULL;
GPIO_InitStructure.Alternate=SENSORS_I2C_AF;
HAL_GPIO_Init(SENSORS_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
/* 配置I2Cx引脚: SDA ----------------------------------------*/
GPIO_InitStructure.Pin = SENSORS_I2C_SDA_GPIO_PIN;
HAL_GPIO_Init(SENSORS_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
if(HAL_I2C_GetState(&I2C_Handle) == HAL_I2C_STATE_RESET)
{
/* 强制复位I2C外设时钟 */
SENSORS_I2C_FORCE_RESET();
/* 释放I2C外设时钟复位 */
SENSORS_I2C_RELEASE_RESET();
/* I2C 配置 */
I2C_Handle.Instance = SENSORS_I2C;
I2C_Handle.Init.Timing = 0x40604E73;//100KHz
I2C_Handle.Init.OwnAddress1 = 0;
I2C_Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2C_Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2C_Handle.Init.OwnAddress2 = 0;
I2C_Handle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
I2C_Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2C_Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
/* 初始化I2C */
HAL_I2C_Init(&I2C_Handle);
/* 使能模拟滤波器 */
HAL_I2CEx_AnalogFilter_Config(&I2C_Handle, I2C_ANALOGFILTER_ENABLE);
}
Delay(100);
}
/**
* @brief Manages error callback by re-initializing I2C.
* @param Addr: I2C Address
* @retval None
*/
static void I2Cx_Error(void)
{
/* 恢复I2C寄存器为默认值 */
HAL_I2C_DeInit(&I2C_Handle);
/* 重新初始化I2C外设 */
I2CMaster_Init();
}
/**
* @brief 写一字节数据到OV2640寄存器
* @param Addr: OV2640 的寄存器地址
* @param Data: 要写入的数据
* @retval 返回0表示写入正常0xFF表示错误
*/
uint8_t OV5640_WriteReg(uint16_t Addr, uint8_t Data)
{
// I2Cx_WriteMultiple(&I2C_Handle, OV2640_DEVICE_WRITE_ADDRESS, (uint16_t)Addr, I2C_MEMADD_SIZE_8BIT,(uint8_t*)&Data, 1);
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&I2C_Handle, OV5640_DEVICE_ADDRESS, (uint16_t)Addr, I2C_MEMADD_SIZE_16BIT, (uint8_t*)&Data, 1, 1000);
/* Check the communication status */
if(status != HAL_OK)
{
/* Re-Initiaize the I2C Bus */
I2Cx_Error();
}
return status;
}
/**
* @brief 从OV2640寄存器中读取一个字节的数据
* @param Addr: 寄存器地址
* @retval 返回读取得的数据
*/
uint8_t OV5640_ReadReg(uint16_t Addr)
{
uint8_t Data = 0;
// I2Cx_ReadMultiple(&I2C_Handle, OV2640_DEVICE_READ_ADDRESS, Addr, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&Data, 1);
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Read(&I2C_Handle, OV5640_DEVICE_ADDRESS, (uint16_t)Addr, I2C_MEMADD_SIZE_16BIT, (uint8_t*)&Data, 1, 1000);
/* Check the communication status */
if(status != HAL_OK)
{
/* I2C error occurred */
I2Cx_Error();
}
/* return the read data */
return Data;
}
/**
* @brief 将固件写入到OV5640片内MCU
* @param Addr: OV5640 的MCU基地址0x8000
* @param Data: 要写入的数据
* @retval 返回0表示写入正常0xFF表示错误
*/
uint8_t OV5640_WriteFW(uint8_t *pBuffer ,uint16_t BufferSize)
{
uint16_t Addr=0x8000;
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&I2C_Handle, OV5640_DEVICE_ADDRESS, (uint16_t)Addr, I2C_MEMADD_SIZE_16BIT, pBuffer, BufferSize, 1000);
/* 检查通信状态 */
if(status != HAL_OK)
{
/* 发生错误重新初始化I2C */
I2Cx_Error();
}
return status;
}