#include "main.h" I2C_HandleTypeDef hi2c1; void SystemClock_Config(void); static void MX_I2C1_Init(void); static void clear_addr_tab(unsigned char *addr_tab) { unsigned int i = 0; for (i = 0; i < 128; i++) { addr_tab[i] = 0; } } unsigned char i2c_scan(unsigned char *addr_tab) { HAL_StatusTypeDef result; uint8_t addr; unsigned char found = 0; for (addr = 1; addr < 128; addr++) { result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t) (addr << 1), 2, 100); if (result != HAL_OK) { // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT // 无ACK addr_tab[addr] = 0; } else { // 有ACK:有设备存在 addr_tab[found] = addr; found += 1; } } return found; } int main(void) { // 此例程中的"volatile"仅用于观察数据(volatile会阻止编译器对目标的优化),移植的时候请去掉"volatile"修饰词 volatile unsigned char found; unsigned char addr_tab[128]; // 存找到的设备地址,地址会排在前面,不等于0的数组就是设备地址 volatile char* volatile addr_ptr = (char *)addr_tab; //没啥用,就是防止unsed 的 addr_tab被优化掉。 HAL_Init(); SystemClock_Config(); MX_I2C1_Init(); while (1) { // 初始化 found = 0; clear_addr_tab((unsigned char *)addr_tab); found = i2c_scan((unsigned char *)addr_tab); /* 扫描完毕,用debug查看found是否>=1,>=1的情况下,地址存于addr_tab,数组不是0的就是找到的设备地址 */ // 等待1ms HAL_Delay(1); } } /** * @brief 时钟配置 */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief I2C初始化 */ static void MX_I2C1_Init(void) { /* 主设备设置 */ hi2c1.Instance = I2C1; /* i2c通道 */ hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; /* i2c 占空比=50% 1:1, I2C_DUTYCYCLE_16_9 用于快速i2c模式 */ /* 从设备设置(不用管) */ hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; /* 是否初始化成功 */ if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } /* 出错啦 */ void Error_Handler(void) { __disable_irq(); while (1) { } }