/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ #define AP3216C_ADDR_W (0x3C) #define AP3216C_ADDR_R (0x3D) #define AP3216CCMD_ALS_L (0x0C) #define AP3216CCMD_ALS_H (0x0D) // #define SEG_ADDR (0x60) //#define SEG_ADDR (0x70) /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ uint8_t Light_Switch = 0; uint8_t Light_Mod = 0; /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim3; UART_HandleTypeDef huart4; /* USER CODE BEGIN PV */ uint8_t Seg_Point[8] = {0,0,0,0,0,0,0,0}; uint8_t Seg_Buf[8] = {10,10,10,10,10,10,10,10}; uint8_t Seg_Char[12] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40 //共阴 0-9,全灭 和 - //0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xB0 //共阳 0-9,全灭 和 - }; uint8_t Seg_Pos = 0; uint16_t Seg_Slow_Down = 0; uint8_t Key_Slow_Down,Key_Val,Key_Old,Key_Down,Key_Up; uint8_t ALS_H,ALS_L,AP3216C_Start = 0x03,AP3216C_Reset = 0x04; uint16_t ALS = 0,Light_Slow_Down; uint8_t Light_Level,Light_Level_Hand = 5,Light_Level_Auto; /* 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_TIM2_Init(void); static void MX_TIM3_Init(void); static void MX_UART4_Init(void); /* USER CODE BEGIN PFP */ //重写printf函数,使用UART4输出 int __io_putchar(int ch) { HAL_UART_Transmit(&huart4,(uint8_t*)&ch,1,10); return ch; } //读取AP3216C的ALS数据 int AP3216CALS_Read() { uint16_t temp = 0; //AP3216C初始化 HAL_I2C_Mem_Write(&hi2c1,AP3216C_ADDR_W,0x00,1,&AP3216C_Reset,1,100); HAL_Delay(150); HAL_I2C_Mem_Write(&hi2c1,AP3216C_ADDR_W,0x00,1,&AP3216C_Start,1,100); HAL_Delay(150); //读取ALS数据 HAL_I2C_Mem_Read(&hi2c1,AP3216C_ADDR_R, AP3216CCMD_ALS_L, 1,&ALS_L,1, 100); HAL_Delay(150); HAL_I2C_Mem_Read(&hi2c1,AP3216C_ADDR_R, AP3216CCMD_ALS_H, 1,&ALS_H,1, 100); HAL_Delay(150); temp = ((ALS_H << 8) | ALS_L); return temp; } //读取按键状态 int Key_Read(void) { uint8_t temp = 0; if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_9) == GPIO_PIN_RESET) temp = 3; else if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_2) == GPIO_PIN_RESET) temp = 4; else if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_1) == GPIO_PIN_RESET) temp = 5; else if(HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_0) == GPIO_PIN_RESET) temp = 6; return temp; } //按键处理 void Key_Proc() { //延时消抖,下面相似代码同理 if(Key_Slow_Down) return; Key_Slow_Down = 1; Key_Val = Key_Read(); Key_Down = Key_Val & (Key_Old ^ Key_Val); Key_Up = ~Key_Val & (Key_Old ^ Key_Val); Key_Old = Key_Val; if(Key_Down == 3) { Light_Switch = !Light_Switch; } if(Light_Switch == 1) { if(Key_Down == 6) Light_Mod = !Light_Mod; if(Key_Down == 4) { Light_Level_Hand++; if(Light_Level_Hand >= 11) Light_Level_Hand = 10; } else if(Key_Down == 5) { Light_Level_Hand--; if(Light_Level_Hand <= 0) Light_Level_Hand = 1; } } } //灯光处理 void Light_Proc() { if(Light_Slow_Down) return; Light_Slow_Down = 1; if(Light_Mod == 1) { Light_Level_Auto = AP3216CALS_Read() / 10 % 10; //如果ALS数据小于5,则灯光亮度为ALS数据+5,保证自动调节的灯光亮度不会过低 if(Light_Level_Auto <= 5) Light_Level = Light_Level_Auto + 5; else Light_Level = Light_Level_Auto; } else //手动调节灯光亮度 Light_Level = Light_Level_Hand; //根据灯光开关状态,设置灯光亮度 if(Light_Switch) { switch(Light_Level) { case 0: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); break; case 1: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 100); break; case 2: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 200); break; case 3: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 300); break; case 4: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 400); break; case 5: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 500); break; case 6: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 600); break; case 7: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 700); break; case 8: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 800); break; case 9: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 900); break; case 10: __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 1000); break; } } else //关闭灯光 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); //输出所有状态 printf("Open_Status:%d Mod:%d Auto_Light:%d Hand_Light:%d Light_Level:%d\n",Light_Switch,Light_Mod,Light_Level_Auto,Light_Level_Hand,Light_Level); } //数码管显示 void Seg_Disp(uint8_t Wela, uint8_t Dula, uint8_t IsPoint) { uint8_t seg_data = Seg_Char[Dula]; // 使用临时变量 if(IsPoint) seg_data |= 0x80; // 设置小数点 else seg_data &= 0x7F; // 清除小数点 HAL_I2C_Mem_Write(&hi2c1,SEG_ADDR,0x10+Wela, 1, &seg_data, 1, 100); } //数码管显示处理 void Seg_Proc() { if(Seg_Slow_Down) return; Seg_Slow_Down = 1; Seg_Buf[0] = 10; Seg_Buf[1] = Light_Switch; Seg_Buf[2] = 10; Seg_Buf[3] = Light_Mod; Seg_Buf[4] = 10; Seg_Buf[5] = Light_Level_Hand % 10; Seg_Buf[6] = 10; Seg_Buf[7] = Light_Level % 10; } /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* 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 */ if(IS_ENGINEERING_BOOT_MODE()) { /* 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_TIM2_Init(); MX_TIM3_Init(); MX_UART4_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htim2); HAL_TIM_Base_Start_IT(&htim3); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { Key_Proc(); Light_Proc(); Seg_Proc(); /* USER CODE END WHILE */ /* 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 RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL4.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** RCC Clock Config */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_ACLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_PCLK3|RCC_CLOCKTYPE_PCLK4 |RCC_CLOCKTYPE_PCLK5; RCC_ClkInitStruct.AXISSInit.AXI_Clock = RCC_AXISSOURCE_HSI; RCC_ClkInitStruct.AXISSInit.AXI_Div = RCC_AXI_DIV1; RCC_ClkInitStruct.MCUInit.MCU_Clock = RCC_MCUSSOURCE_HSI; RCC_ClkInitStruct.MCUInit.MCU_Div = RCC_MCU_DIV1; RCC_ClkInitStruct.APB4_Div = RCC_APB4_DIV1; RCC_ClkInitStruct.APB5_Div = RCC_APB5_DIV1; RCC_ClkInitStruct.APB1_Div = RCC_APB1_DIV1; RCC_ClkInitStruct.APB2_Div = RCC_APB2_DIV1; RCC_ClkInitStruct.APB3_Div = RCC_APB3_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != 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.Timing = 0x10707DBC; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } /** Configure Analogue filter */ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { Error_Handler(); } /** Configure Digital filter */ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2C1_Init 2 */ /* USER CODE END I2C1_Init 2 */ } /** * @brief TIM2 Initialization Function * @param None * @retval None */ static void MX_TIM2_Init(void) { /* USER CODE BEGIN TIM2_Init 0 */ /* USER CODE END TIM2_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM2_Init 1 */ /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 63; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ /* USER CODE END TIM2_Init 2 */ } /** * @brief TIM3 Initialization Function * @param None * @retval None */ static void MX_TIM3_Init(void) { /* USER CODE BEGIN TIM3_Init 0 */ /* USER CODE END TIM3_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; /* USER CODE BEGIN TIM3_Init 1 */ /* USER CODE END TIM3_Init 1 */ htim3.Instance = TIM3; htim3.Init.Prescaler = 63; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 999; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM3_Init 2 */ /* USER CODE END TIM3_Init 2 */ HAL_TIM_MspPostInit(&htim3); } /** * @brief UART4 Initialization Function * @param None * @retval None */ static void MX_UART4_Init(void) { /* USER CODE BEGIN UART4_Init 0 */ /* USER CODE END UART4_Init 0 */ /* USER CODE BEGIN UART4_Init 1 */ /* USER CODE END UART4_Init 1 */ huart4.Instance = UART4; huart4.Init.BaudRate = 115200; huart4.Init.WordLength = UART_WORDLENGTH_8B; huart4.Init.StopBits = UART_STOPBITS_1; huart4.Init.Parity = UART_PARITY_NONE; huart4.Init.Mode = UART_MODE_TX_RX; huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart4.Init.OverSampling = UART_OVERSAMPLING_16; huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1; huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart4) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetTxFifoThreshold(&huart4, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetRxFifoThreshold(&huart4, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_DisableFifoMode(&huart4) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN UART4_Init 2 */ /* USER CODE END UART4_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /*Configure GPIO pins : PG2 PG0 PG1 */ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); /*Configure GPIO pin : PE9 */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } /* 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 */ __disable_irq(); while (1) { } /* 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, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */