完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
MCU:STM32F103
IDE:STM32CubeIDE HAL库 硬件I2C当作Slave,模拟EEPROM行为 测试工具:树莓派为I2C主机,使用I2C-tools进行测试 配置I2C:从机地址可直接在代码中修改,记得开启中断 main.c代码: /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stdio.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart1; /* USER CODE BEGIN PV */ #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { HAL_UART_Transmit(&huart1,(uint8_t*)&ch, 1, 0xFFFF); return ch; } /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_USART1_UART_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ uint8_t r_flag = 0,t_flag = 0; uint8_t flag_0 = 0,flag_1 = 0,flag_2 = 0,flag_3 = 0,flag_4 = 0,flag_5 = 0; uint16_t rx_len = 0; uint16_t tx_len = 0; uint16_t rx_count = 0; uint8_t RX_Buffer[256]; uint8_t rx_buff[256] = {0x00}; uint8_t tx_buff[260] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, }; void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) { __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); if(r_flag == 1) { rx_count = (255 - hi2c->XferCount); memcpy((RX_Buffer + rx_len),rx_buff,rx_count); rx_len = rx_count + rx_len; } if(t_flag == 1) { tx_len = (255 - hi2c->XferCount) + tx_len; } if(rx_count == 2) //模拟EEPROM写寄存器值功能 { tx_buff[rx_buff[0]] = rx_buff[1] ; } if(TransferDirection == I2C_DIRECTION_RECEIVE) //需要发送 { flag_0++; t_flag = 1; //置发送标志 r_flag = 0; //清楚读标志 // HAL_I2C_Slave_Transmit_IT(&hi2c1, (tx_buff + rx_buff[0]), 1); //该函数发送会使总线死掉 HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, (tx_buff + rx_buff[0]), 255, I2C_FIRST_FRAME); //模拟EEPROM获取寄存器值行为 } else if(TransferDirection == I2C_DIRECTION_TRANSMIT)//需要接收 { flag_1++; t_flag = 0; //清除发送标志 r_flag = 1; //置读标志 // HAL_I2C_Slave_Receive_IT(&hi2c1, rx_buff, 1); //该函数接受会使总线死掉 HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, rx_buff, 255, I2C_FIRST_FRAME); } else {} } void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) //监听中断回调,说明传输结束 { flag_2++; if(r_flag == 1) { rx_count = (255 - hi2c->XferCount); memcpy((RX_Buffer + rx_len),rx_buff,rx_count); rx_len = rx_count + rx_len; } if(t_flag == 1) { tx_len = (255 - hi2c->XferCount) + tx_len; } t_flag = 0; //清除发送标志 r_flag = 0; //清除读标志 HAL_I2C_EnableListen_IT(hi2c); // Restart } void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) //全部发送完成回调,发送256字节回调 { flag_3++; } void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) //全部接收完成回调,收到256字节回调 { flag_4++; } void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) { flag_5++; } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ uint16_t i; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_I2C1_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_I2C_EnableListen_IT(&hi2c1); // HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, rx_buff, 255, I2C_LAST_FRAME); //开启从机中断接收 HAL_I2C_Slave_Receive_IT(&hi2c1, rx_buff, 1); printf("start test i2c!nr"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ #if 1 if (flag_0 > 0) { printf("T:%dnr",flag_0); flag_0 = 0; } if(flag_1 > 0) { printf("R:%dnr",flag_1); flag_1 = 0; } if(flag_2 > 0) { printf("lc:%dnr",flag_2); flag_2 = 0; } if(flag_3 > 0) { printf("tc:%dnr",flag_3); flag_3 = 0; } if(flag_4 > 0) { printf("rc:%dnr",flag_4); flag_4 = 0; } if(flag_5 > 0) { printf("er:%dnr",flag_5); flag_5 = 0; } #endif #if 1 if((rx_len > 0) && (r_flag == 0) && (t_flag == 0)) { #if 0 HAL_Delay(2000); for(i=0;i printf("%x ",RX_Buffer); } printf("nr"); #endif memset(RX_Buffer,0,rx_len); rx_len = 0; tx_len = 0; } #endif /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 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_1) != HAL_OK) { Error_Handler(); } } /** * @brief I2C1 Initialization Function * @param None * @retval None */ static void MX_I2C1_Init(void) { /* USER CODE BEGIN I2C1_Init 0 */ /* USER CODE END I2C1_Init 0 */ /* USER CODE BEGIN I2C1_Init 1 */ /* USER CODE END I2C1_Init 1 */ hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0x30; 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(); } /* USER CODE BEGIN I2C1_Init 2 */ /* USER CODE END I2C1_Init 2 */ } /** * @brief USART1 Initialization Function * @param None * @retval None */ static void MX_USART1_UART_Init(void) { /* USER CODE BEGIN USART1_Init 0 */ /* USER CODE END USART1_Init 0 */ /* USER CODE BEGIN USART1_Init 1 */ /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_MultiProcessor_Init(&huart1, 0, UART_WAKEUPMETHOD_IDLELINE) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART1_Init 2 */ /* USER CODE END USART1_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %drn", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1537 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1490 浏览 1 评论
910 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
654 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1538 浏览 2 评论
1845浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
596浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
499浏览 3评论
499浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
483浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-5 13:24 , Processed in 0.641769 second(s), Total 45, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号