From ca252d1161c0179a3940dd1a0e623ca14180476c Mon Sep 17 00:00:00 2001 From: zhaohe Date: Mon, 19 Feb 2024 17:46:46 +0800 Subject: [PATCH] add pwm generator --- .vscode/settings.json | 3 +- Core/Inc/main.h | 2 + Core/Inc/stm32f1xx_it.h | 2 +- Core/Src/main.c | 84 ++++++++++++++++++++++++++++++++--- Core/Src/stm32f1xx_hal_msp.c | 57 ++++++++++++++++++++++-- Core/Src/stm32f1xx_hal_timebase_tim.c | 65 +++++++++++++++------------ Core/Src/stm32f1xx_it.c | 30 ++++++------- README.md | 7 +++ light_src_ctrl_stm32_port.ioc | 62 +++++++++++++++++++------- usrc/light_intensity_ctrl.c | 55 +++++++++++++++++++++++ usrc/light_intensity_ctrl.h | 23 ++++++++++ usrc/project_configs.h | 3 ++ usrc/umain.c | 78 ++++++++++++++++++-------------- zlib/zlib.h | 2 + zlib/zlog.h | 49 ++++++++++++-------- zlib/ztim.c | 84 +++++++++++++++++++++++++++++++++++ zlib/ztim.h | 9 ++++ 17 files changed, 491 insertions(+), 124 deletions(-) create mode 100644 usrc/light_intensity_ctrl.c create mode 100644 usrc/light_intensity_ctrl.h create mode 100644 zlib/ztim.c create mode 100644 zlib/ztim.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 40f3048..0eb2537 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -112,7 +112,8 @@ "cdefs.h": "c", "features.h": "c", "stdlib.h": "c", - "stm32f1xx_hal_def.h": "c" + "stm32f1xx_hal_def.h": "c", + "light_intensity_ctrl.h": "c" }, "files.autoGuessEncoding": false, "files.encoding": "gbk" diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 218d3a3..0a6d94a 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -49,6 +49,8 @@ extern "C" { /* USER CODE END EM */ +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); diff --git a/Core/Inc/stm32f1xx_it.h b/Core/Inc/stm32f1xx_it.h index 2d730c2..9daab6e 100644 --- a/Core/Inc/stm32f1xx_it.h +++ b/Core/Inc/stm32f1xx_it.h @@ -57,8 +57,8 @@ void PendSV_Handler(void); void SysTick_Handler(void); void DMA1_Channel4_IRQHandler(void); void DMA1_Channel5_IRQHandler(void); +void TIM4_IRQHandler(void); void USART1_IRQHandler(void); -void TIM8_UP_IRQHandler(void); void TIM7_IRQHandler(void); /* USER CODE BEGIN EFP */ diff --git a/Core/Src/main.c b/Core/Src/main.c index ebf7a53..cadce2d 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -40,6 +40,7 @@ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ +TIM_HandleTypeDef htim5; TIM_HandleTypeDef htim6; TIM_HandleTypeDef htim7; @@ -58,6 +59,7 @@ static void MX_DMA_Init(void); static void MX_USART1_UART_Init(void); static void MX_TIM6_Init(void); static void MX_TIM7_Init(void); +static void MX_TIM5_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -99,6 +101,7 @@ int main(void) MX_USART1_UART_Init(); MX_TIM6_Init(); MX_TIM7_Init(); + MX_TIM5_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -156,6 +159,77 @@ void SystemClock_Config(void) } /** + * @brief TIM5 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM5_Init(void) +{ + + /* USER CODE BEGIN TIM5_Init 0 */ + + /* USER CODE END TIM5_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM5_Init 1 */ + + /* USER CODE END TIM5_Init 1 */ + htim5.Instance = TIM5; + htim5.Init.Prescaler = 71; + htim5.Init.CounterMode = TIM_COUNTERMODE_UP; + htim5.Init.Period = 1000; + htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&htim5) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim5) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &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(&htim5, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM5_Init 2 */ + + /* USER CODE END TIM5_Init 2 */ + HAL_TIM_MspPostInit(&htim5); + +} + +/** * @brief TIM6 Initialization Function * @param None * @retval None @@ -336,11 +410,9 @@ static void MX_GPIO_Init(void) GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); - /*Configure GPIO pins : PA0 PA1 PA2 PA3 - PA4 PA5 PA6 PA7 + /*Configure GPIO pins : PA4 PA5 PA6 PA7 PA8 PA11 PA12 PA15 */ - GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 - |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7 + GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7 |GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); @@ -388,7 +460,7 @@ static void MX_GPIO_Init(void) /** * @brief Period elapsed callback in non blocking mode - * @note This function is called when TIM8 interrupt took place, inside + * @note This function is called when TIM4 interrupt took place, inside * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment * a global variable "uwTick" used as application time base. * @param htim : TIM handle @@ -399,7 +471,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) /* USER CODE BEGIN Callback 0 */ /* USER CODE END Callback 0 */ - if (htim->Instance == TIM8) { + if (htim->Instance == TIM4) { HAL_IncTick(); } /* USER CODE BEGIN Callback 1 */ diff --git a/Core/Src/stm32f1xx_hal_msp.c b/Core/Src/stm32f1xx_hal_msp.c index 6bc1ea5..0777d4b 100644 --- a/Core/Src/stm32f1xx_hal_msp.c +++ b/Core/Src/stm32f1xx_hal_msp.c @@ -61,7 +61,9 @@ extern DMA_HandleTypeDef hdma_usart1_tx; /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ -/** + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /** * Initializes the Global MSP. */ void HAL_MspInit(void) @@ -92,7 +94,18 @@ void HAL_MspInit(void) */ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM6) + if(htim_base->Instance==TIM5) + { + /* USER CODE BEGIN TIM5_MspInit 0 */ + + /* USER CODE END TIM5_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM5_CLK_ENABLE(); + /* USER CODE BEGIN TIM5_MspInit 1 */ + + /* USER CODE END TIM5_MspInit 1 */ + } + else if(htim_base->Instance==TIM6) { /* USER CODE BEGIN TIM6_MspInit 0 */ @@ -120,6 +133,33 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) } +void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(htim->Instance==TIM5) + { + /* USER CODE BEGIN TIM5_MspPostInit 0 */ + + /* USER CODE END TIM5_MspPostInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**TIM5 GPIO Configuration + PA0-WKUP ------> TIM5_CH1 + PA1 ------> TIM5_CH2 + PA2 ------> TIM5_CH3 + PA3 ------> TIM5_CH4 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM5_MspPostInit 1 */ + + /* USER CODE END TIM5_MspPostInit 1 */ + } + +} /** * @brief TIM_Base MSP De-Initialization * This function freeze the hardware resources used in this example @@ -128,7 +168,18 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM6) + if(htim_base->Instance==TIM5) + { + /* USER CODE BEGIN TIM5_MspDeInit 0 */ + + /* USER CODE END TIM5_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM5_CLK_DISABLE(); + /* USER CODE BEGIN TIM5_MspDeInit 1 */ + + /* USER CODE END TIM5_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM6) { /* USER CODE BEGIN TIM6_MspDeInit 0 */ diff --git a/Core/Src/stm32f1xx_hal_timebase_tim.c b/Core/Src/stm32f1xx_hal_timebase_tim.c index e97fec3..59657cf 100644 --- a/Core/Src/stm32f1xx_hal_timebase_tim.c +++ b/Core/Src/stm32f1xx_hal_timebase_tim.c @@ -25,13 +25,13 @@ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ -TIM_HandleTypeDef htim8; +TIM_HandleTypeDef htim4; /* Private function prototypes -----------------------------------------------*/ -void TIM8_IRQHandler(void); +void TIM4_IRQHandler(void); /* Private functions ---------------------------------------------------------*/ /** - * @brief This function configures the TIM8 as a time base source. + * @brief This function configures the TIM4 as a time base source. * The time source is configured to have 1ms time base with a dedicated * Tick interrupt priority. * @note This function is called automatically at the beginning of program after @@ -42,54 +42,63 @@ void TIM8_IRQHandler(void); HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { RCC_ClkInitTypeDef clkconfig; - uint32_t uwTimclock = 0U; + uint32_t uwTimclock, uwAPB1Prescaler = 0U; uint32_t uwPrescalerValue = 0U; uint32_t pFLatency; HAL_StatusTypeDef status = HAL_OK; - /* Enable TIM8 clock */ - __HAL_RCC_TIM8_CLK_ENABLE(); + /* Enable TIM4 clock */ + __HAL_RCC_TIM4_CLK_ENABLE(); /* Get clock configuration */ HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); - /* Compute TIM8 clock */ - uwTimclock = HAL_RCC_GetPCLK2Freq(); + /* Get APB1 prescaler */ + uwAPB1Prescaler = clkconfig.APB1CLKDivider; + /* Compute TIM4 clock */ + if (uwAPB1Prescaler == RCC_HCLK_DIV1) + { + uwTimclock = HAL_RCC_GetPCLK1Freq(); + } + else + { + uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq(); + } - /* Compute the prescaler value to have TIM8 counter clock equal to 1MHz */ + /* Compute the prescaler value to have TIM4 counter clock equal to 1MHz */ uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U); - /* Initialize TIM8 */ - htim8.Instance = TIM8; + /* Initialize TIM4 */ + htim4.Instance = TIM4; /* Initialize TIMx peripheral as follow: - + Period = [(TIM8CLK/1000) - 1]. to have a (1/1000) s time base. + + Period = [(TIM4CLK/1000) - 1]. to have a (1/1000) s time base. + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. + ClockDivision = 0 + Counter direction = Up */ - htim8.Init.Period = (1000000U / 1000U) - 1U; - htim8.Init.Prescaler = uwPrescalerValue; - htim8.Init.ClockDivision = 0; - htim8.Init.CounterMode = TIM_COUNTERMODE_UP; - htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + htim4.Init.Period = (1000000U / 1000U) - 1U; + htim4.Init.Prescaler = uwPrescalerValue; + htim4.Init.ClockDivision = 0; + htim4.Init.CounterMode = TIM_COUNTERMODE_UP; + htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - status = HAL_TIM_Base_Init(&htim8); + status = HAL_TIM_Base_Init(&htim4); if (status == HAL_OK) { /* Start the TIM time Base generation in interrupt mode */ - status = HAL_TIM_Base_Start_IT(&htim8); + status = HAL_TIM_Base_Start_IT(&htim4); if (status == HAL_OK) { - /* Enable the TIM8 global Interrupt */ - HAL_NVIC_EnableIRQ(TIM8_UP_IRQn); + /* Enable the TIM4 global Interrupt */ + HAL_NVIC_EnableIRQ(TIM4_IRQn); /* Configure the SysTick IRQ priority */ if (TickPriority < (1UL << __NVIC_PRIO_BITS)) { /* Configure the TIM IRQ priority */ - HAL_NVIC_SetPriority(TIM8_UP_IRQn, TickPriority, 0U); + HAL_NVIC_SetPriority(TIM4_IRQn, TickPriority, 0U); uwTickPrio = TickPriority; } else @@ -105,25 +114,25 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) /** * @brief Suspend Tick increment. - * @note Disable the tick increment by disabling TIM8 update interrupt. + * @note Disable the tick increment by disabling TIM4 update interrupt. * @param None * @retval None */ void HAL_SuspendTick(void) { - /* Disable TIM8 update Interrupt */ - __HAL_TIM_DISABLE_IT(&htim8, TIM_IT_UPDATE); + /* Disable TIM4 update Interrupt */ + __HAL_TIM_DISABLE_IT(&htim4, TIM_IT_UPDATE); } /** * @brief Resume Tick increment. - * @note Enable the tick increment by Enabling TIM8 update interrupt. + * @note Enable the tick increment by Enabling TIM4 update interrupt. * @param None * @retval None */ void HAL_ResumeTick(void) { - /* Enable TIM8 Update interrupt */ - __HAL_TIM_ENABLE_IT(&htim8, TIM_IT_UPDATE); + /* Enable TIM4 Update interrupt */ + __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE); } diff --git a/Core/Src/stm32f1xx_it.c b/Core/Src/stm32f1xx_it.c index 04dd130..7531ecc 100644 --- a/Core/Src/stm32f1xx_it.c +++ b/Core/Src/stm32f1xx_it.c @@ -59,7 +59,7 @@ extern TIM_HandleTypeDef htim7; extern DMA_HandleTypeDef hdma_usart1_rx; extern DMA_HandleTypeDef hdma_usart1_tx; extern UART_HandleTypeDef huart1; -extern TIM_HandleTypeDef htim8; +extern TIM_HandleTypeDef htim4; /* USER CODE BEGIN EV */ @@ -231,31 +231,31 @@ void DMA1_Channel5_IRQHandler(void) } /** - * @brief This function handles USART1 global interrupt. + * @brief This function handles TIM4 global interrupt. */ -void USART1_IRQHandler(void) +void TIM4_IRQHandler(void) { - /* USER CODE BEGIN USART1_IRQn 0 */ + /* USER CODE BEGIN TIM4_IRQn 0 */ - /* USER CODE END USART1_IRQn 0 */ - HAL_UART_IRQHandler(&huart1); - /* USER CODE BEGIN USART1_IRQn 1 */ + /* USER CODE END TIM4_IRQn 0 */ + HAL_TIM_IRQHandler(&htim4); + /* USER CODE BEGIN TIM4_IRQn 1 */ - /* USER CODE END USART1_IRQn 1 */ + /* USER CODE END TIM4_IRQn 1 */ } /** - * @brief This function handles TIM8 update interrupt. + * @brief This function handles USART1 global interrupt. */ -void TIM8_UP_IRQHandler(void) +void USART1_IRQHandler(void) { - /* USER CODE BEGIN TIM8_UP_IRQn 0 */ + /* USER CODE BEGIN USART1_IRQn 0 */ - /* USER CODE END TIM8_UP_IRQn 0 */ - HAL_TIM_IRQHandler(&htim8); - /* USER CODE BEGIN TIM8_UP_IRQn 1 */ + /* USER CODE END USART1_IRQn 0 */ + HAL_UART_IRQHandler(&huart1); + /* USER CODE BEGIN USART1_IRQn 1 */ - /* USER CODE END TIM8_UP_IRQn 1 */ + /* USER CODE END USART1_IRQn 1 */ } /** diff --git a/README.md b/README.md index 9feef46..ffd323f 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,13 @@ STM32 4. TIM7用于波形的产生,需要使能中断,并配置成1000us一次中断触发,同时中断优先级改成0,其他中断优先级改成0+ +引脚分配: + 灯光强度PWM4路输出: + TIM5_CH1:PA0 + TIM5_CH2:PA1 + TIM5_CH3:PA2 + TIM5_CH4:PA3 + ``` ``` diff --git a/light_src_ctrl_stm32_port.ioc b/light_src_ctrl_stm32_port.ioc index 13c167d..cf5f69e 100644 --- a/light_src_ctrl_stm32_port.ioc +++ b/light_src_ctrl_stm32_port.ioc @@ -32,24 +32,30 @@ Mcu.IP0=DMA Mcu.IP1=NVIC Mcu.IP2=RCC Mcu.IP3=SYS -Mcu.IP4=TIM6 -Mcu.IP5=TIM7 -Mcu.IP6=USART1 -Mcu.IPNb=7 +Mcu.IP4=TIM5 +Mcu.IP5=TIM6 +Mcu.IP6=TIM7 +Mcu.IP7=USART1 +Mcu.IPNb=8 Mcu.Name=STM32F103Z(C-D-E)Tx Mcu.Package=LQFP144 Mcu.Pin0=PC14-OSC32_IN Mcu.Pin1=PC15-OSC32_OUT -Mcu.Pin10=VP_TIM7_VS_ClockSourceINT +Mcu.Pin10=PA13 +Mcu.Pin11=PA14 +Mcu.Pin12=VP_SYS_VS_tim4 +Mcu.Pin13=VP_TIM5_VS_ClockSourceINT +Mcu.Pin14=VP_TIM6_VS_ClockSourceINT +Mcu.Pin15=VP_TIM7_VS_ClockSourceINT Mcu.Pin2=OSC_IN Mcu.Pin3=OSC_OUT -Mcu.Pin4=PA9 -Mcu.Pin5=PA10 -Mcu.Pin6=PA13 -Mcu.Pin7=PA14 -Mcu.Pin8=VP_SYS_VS_tim8 -Mcu.Pin9=VP_TIM6_VS_ClockSourceINT -Mcu.PinsNb=11 +Mcu.Pin4=PA0-WKUP +Mcu.Pin5=PA1 +Mcu.Pin6=PA2 +Mcu.Pin7=PA3 +Mcu.Pin8=PA9 +Mcu.Pin9=PA10 +Mcu.PinsNb=16 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F103ZETx @@ -67,22 +73,26 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC.TIM4_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true NVIC.TIM7_IRQn=true\:0\:0\:true\:false\:true\:true\:true\:true -NVIC.TIM8_UP_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true -NVIC.TimeBase=TIM8_UP_IRQn -NVIC.TimeBaseIP=TIM8 +NVIC.TimeBase=TIM4_IRQn +NVIC.TimeBaseIP=TIM4 NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false OSC_IN.Mode=HSE-External-Oscillator OSC_IN.Signal=RCC_OSC_IN OSC_OUT.Mode=HSE-External-Oscillator OSC_OUT.Signal=RCC_OSC_OUT +PA0-WKUP.Signal=S_TIM5_CH1 +PA1.Signal=S_TIM5_CH2 PA10.Mode=Asynchronous PA10.Signal=USART1_RX PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO PA14.Mode=Serial_Wire PA14.Signal=SYS_JTCK-SWCLK +PA2.Signal=S_TIM5_CH3 +PA3.Signal=S_TIM5_CH4 PA9.Mode=Asynchronous PA9.Signal=USART1_TX PC14-OSC32_IN.Mode=LSE-External-Oscillator @@ -147,14 +157,32 @@ RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.TimSysFreq_Value=72000000 RCC.USBFreq_Value=72000000 RCC.VCOOutput2Freq_Value=8000000 +SH.S_TIM5_CH1.0=TIM5_CH1,PWM Generation1 CH1 +SH.S_TIM5_CH1.ConfNb=1 +SH.S_TIM5_CH2.0=TIM5_CH2,PWM Generation2 CH2 +SH.S_TIM5_CH2.ConfNb=1 +SH.S_TIM5_CH3.0=TIM5_CH3,PWM Generation3 CH3 +SH.S_TIM5_CH3.ConfNb=1 +SH.S_TIM5_CH4.0=TIM5_CH4,PWM Generation4 CH4 +SH.S_TIM5_CH4.ConfNb=1 +TIM5.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM5.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 +TIM5.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 +TIM5.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 +TIM5.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 +TIM5.IPParameters=Prescaler,Period,AutoReloadPreload,Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4 +TIM5.Period=1000 +TIM5.Prescaler=71 TIM7.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE TIM7.IPParameters=AutoReloadPreload,Prescaler,Period TIM7.Period=1000 TIM7.Prescaler=71 USART1.IPParameters=VirtualMode USART1.VirtualMode=VM_ASYNC -VP_SYS_VS_tim8.Mode=TIM8 -VP_SYS_VS_tim8.Signal=SYS_VS_tim8 +VP_SYS_VS_tim4.Mode=TIM4 +VP_SYS_VS_tim4.Signal=SYS_VS_tim4 +VP_TIM5_VS_ClockSourceINT.Mode=Internal +VP_TIM5_VS_ClockSourceINT.Signal=TIM5_VS_ClockSourceINT VP_TIM6_VS_ClockSourceINT.Mode=Enable_Timer VP_TIM6_VS_ClockSourceINT.Signal=TIM6_VS_ClockSourceINT VP_TIM7_VS_ClockSourceINT.Mode=Enable_Timer diff --git a/usrc/light_intensity_ctrl.c b/usrc/light_intensity_ctrl.c new file mode 100644 index 0000000..65f0361 --- /dev/null +++ b/usrc/light_intensity_ctrl.c @@ -0,0 +1,55 @@ +#include "light_intensity_ctrl.h" + +extern TIM_HandleTypeDef LIGHT_INTENSITY_TIM; + +static uint32_t m_light_intensity = 50; +static TIM_HandleTypeDef* m_htim = &LIGHT_INTENSITY_TIM; +static uint32_t m_freq = 1000; + +void LightIntensityCtrl_init() { + ZASSERT(m_htim->Init.AutoReloadPreload == TIM_AUTORELOAD_PRELOAD_ENABLE); + ZASSERT(m_htim->Init.CounterMode == TIM_COUNTERMODE_UP); +} +void LightIntensityCtrl_setIntensity(uint32_t intensity) { + if (intensity > 100) { + intensity = 100; + } + m_light_intensity = intensity; +} +uint32_t LightIntensityCtrl_getIntensity() { return m_light_intensity; } +void LightIntensityCtrl_start() { + uint32_t prescaler = 0; + uint32_t autoreload = 0; + + // 设置频率 + uint32_t timClkFreq = chip_get_timer_clock_sorce_freq(m_htim); + ZASSERT(chip_calculate_prescaler_and_autoreload_by_expect_freq(timClkFreq, m_freq, &prescaler, &autoreload)); + + // m_htim-> + HAL_TIM_PWM_Stop(m_htim, TIM_CHANNEL_1); + HAL_TIM_PWM_Stop(m_htim, TIM_CHANNEL_2); + HAL_TIM_PWM_Stop(m_htim, TIM_CHANNEL_3); + HAL_TIM_PWM_Stop(m_htim, TIM_CHANNEL_4); + + __HAL_TIM_SET_AUTORELOAD(m_htim, autoreload); + __HAL_TIM_SET_PRESCALER(m_htim, prescaler); + + // 配置模式 + TIM_OC_InitTypeDef sConfigOC = {0}; + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = m_light_intensity / 100.0 * __HAL_TIM_GET_AUTORELOAD(m_htim); + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + + ZSTM32_CHECK(HAL_TIM_PWM_ConfigChannel(m_htim, &sConfigOC, TIM_CHANNEL_1)); + ZSTM32_CHECK(HAL_TIM_PWM_ConfigChannel(m_htim, &sConfigOC, TIM_CHANNEL_2)); + ZSTM32_CHECK(HAL_TIM_PWM_ConfigChannel(m_htim, &sConfigOC, TIM_CHANNEL_3)); + ZSTM32_CHECK(HAL_TIM_PWM_ConfigChannel(m_htim, &sConfigOC, TIM_CHANNEL_4)); + + ZSTM32_CHECK(HAL_TIM_PWM_Start(m_htim, TIM_CHANNEL_1)); + ZSTM32_CHECK(HAL_TIM_PWM_Start(m_htim, TIM_CHANNEL_2)); + ZSTM32_CHECK(HAL_TIM_PWM_Start(m_htim, TIM_CHANNEL_3)); + ZSTM32_CHECK(HAL_TIM_PWM_Start(m_htim, TIM_CHANNEL_4)); +} \ No newline at end of file diff --git a/usrc/light_intensity_ctrl.h b/usrc/light_intensity_ctrl.h new file mode 100644 index 0000000..3c63620 --- /dev/null +++ b/usrc/light_intensity_ctrl.h @@ -0,0 +1,23 @@ +#pragma once +#include + +#include "zlib.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief + * 定时器配置参考: https://iflytop1.feishu.cn/wiki/DhNhwteIGijHy5kC53Dcfp83nZ6 + * + * + */ + +void LightIntensityCtrl_init(); +void LightIntensityCtrl_setIntensity(uint32_t intensity); +uint32_t LightIntensityCtrl_getIntensity(); +void LightIntensityCtrl_start(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/usrc/project_configs.h b/usrc/project_configs.h index 0e3f5eb..ab0c24a 100644 --- a/usrc/project_configs.h +++ b/usrc/project_configs.h @@ -15,6 +15,9 @@ #define PC_NVS_ENABLE 1 + +#define LIGHT_INTENSITY_TIM htim5 + // ===================================================================== // ===================================================================== // ===================================================================== diff --git a/usrc/umain.c b/usrc/umain.c index b9a93c0..b364137 100644 --- a/usrc/umain.c +++ b/usrc/umain.c @@ -3,6 +3,7 @@ #include #include "config_service.h" +#include "light_intensity_ctrl.h" #include "main.h" #include "zlib.h" #define TAG "MAIN" @@ -36,21 +37,14 @@ bool uart_is_rxing(UART_HandleTypeDef *huart) { // return false; } void prv_process_uart_rx_data() { - /** - * @brief 指令格式 - * - * parameter_write paramName paramVal - * parameter_read paramName - * parameter_list - * - */ + /******************************************************************************* + * 将接收到消息解析成argc,argv * + *******************************************************************************/ char *argc[10] = {0}; int argv = 0; - // clear /r/n - - for (int i = 0; i < g_uart_rx_buf_index; i++) { + for (uint32_t i = 0; i < g_uart_rx_buf_index; i++) { if (g_uart_rx_buf[i] == '\r' || g_uart_rx_buf[i] == '\n') { g_uart_rx_buf[i] = 0; } @@ -67,35 +61,40 @@ void prv_process_uart_rx_data() { argc[argv] = strtok(NULL, " "); } + /******************************************************************************* + * 处理指令 * + *******************************************************************************/ + if (strcmp(argc[0], "cfg_set") == 0 && argv == 3) { - config_t *cfg = config_get(); const char *param = argc[1]; uint32_t val = atoi(argc[2]); if (strcmp(param, "light_intensity") == 0) { if (val <= 0 || val > 100) { - printf("light_intensity should be in range 1-100\n"); + printf("FAIL,light_intensity should be in range 1-100\n"); return; } cfg->light_intensity = val; printf("OK\n"); } else if (strcmp(param, "pulse_width_ms") == 0) { if (val <= 0 || val > 100) { - printf("pulse_width_ms should be in range 1-100\n"); + printf("FAIL,pulse_width_ms should be in range 1-100\n"); return; } cfg->pulse_width_ms = val; + LightIntensityCtrl_setIntensity(val); + LightIntensityCtrl_start(); printf("OK\n"); } else if (strcmp(param, "pulse_interval_ms") == 0) { if (val > 100) { - printf("pulse_interval_ms should be in range 0-100\n"); + printf("FAIL,pulse_interval_ms should be in range 0-100\n"); return; } cfg->pulse_interval_ms = val; printf("OK\n"); } else if (strcmp(param, "cmd_echo") == 0) { if (val != 0 && val != 1) { - printf("cmd_echo should be 0 or 1\n"); + printf("FAIL,cmd_echo should be 0 or 1\n"); return; } cfg->cmd_echo = val; @@ -103,39 +102,50 @@ void prv_process_uart_rx_data() { } else { printf("FAIL,unknown parameter\n"); } - } else if (strcmp(argc[0], "cfg_get") == 0 && argv == 2) { - config_t *cfg = config_get(); + } + // + else if (strcmp(argc[0], "cfg_get") == 0 && argv == 2) { const char *param = argc[1]; if (strcmp(param, "light_intensity") == 0) { - printf("OK,%d\n", cfg->light_intensity); + printf("OK,%ld\n", cfg->light_intensity); } else if (strcmp(param, "pulse_width_ms") == 0) { - printf("OK,%d\n", cfg->pulse_width_ms); + printf("OK,%ld\n", cfg->pulse_width_ms); } else if (strcmp(param, "pulse_interval_ms") == 0) { - printf("OK,%d\n", cfg->pulse_interval_ms); + printf("OK,%ld\n", cfg->pulse_interval_ms); } else if (strcmp(param, "cmd_echo") == 0) { - printf("OK,%d\n", cfg->cmd_echo); + printf("OK,%ld\n", cfg->cmd_echo); } else { printf("FAIL,unknown parameter\n"); } - } else if (strcmp(argc[0], "cfg_flush") == 0) { + } + // + else if (strcmp(argc[0], "cfg_flush") == 0) { config_flush(); printf("OK\n"); - } else if (strcmp(argc[0], "factory_reset") == 0) { + } + // + else if (strcmp(argc[0], "factory_reset") == 0) { config_factory_reset(); printf("OK\n"); - } else if (strcmp(argc[0], "cfg_list") == 0) { + } + // + else if (strcmp(argc[0], "cfg_list") == 0) { config_t *cfg = config_get(); printf("------ param list ------\n"); - printf(" light_intensity : %d\n", cfg->light_intensity); - printf(" pulse_width_ms : %d\n", cfg->pulse_width_ms); - printf(" pulse_interval_ms : %d\n", cfg->pulse_interval_ms); - printf(" cmd_echo : %d\n", cfg->cmd_echo); + printf(" light_intensity : %ld\n", cfg->light_intensity); + printf(" pulse_width_ms : %ld\n", cfg->pulse_width_ms); + printf(" pulse_interval_ms : %ld\n", cfg->pulse_interval_ms); + printf(" cmd_echo : %ld\n", cfg->cmd_echo); - } else if (strcmp(argc[0], "reset") == 0) { + } + // + else if (strcmp(argc[0], "reset") == 0) { NVIC_SystemReset(); - } else { + } + // + else { printf("FAIL,unknown command\n"); } } @@ -144,6 +154,9 @@ void umain() { // start_generat_wave(); config_init(); + LightIntensityCtrl_init(); + LightIntensityCtrl_setIntensity(config_get()->light_intensity); + LightIntensityCtrl_start(); while (true) { /** @@ -157,8 +170,5 @@ void umain() { memset(g_uart_rx_buf, 0, sizeof(g_uart_rx_buf)); HAL_UARTEx_ReceiveToIdle_DMA(&PC_DEBUG_UART, g_uart_rx_buf, sizeof(g_uart_rx_buf) - 1); } - - // printf("Unknown command\n"); - // HAL_Delay(1000); } } diff --git a/zlib/zlib.h b/zlib/zlib.h index 39ab060..3d565a9 100644 --- a/zlib/zlib.h +++ b/zlib/zlib.h @@ -3,6 +3,7 @@ #ifdef __cplusplus extern "C" { #endif +#include #include "zbasic.h" #include "zdelay.h" @@ -10,6 +11,7 @@ extern "C" { #include "zgpio.h" #include "zlog.h" #include "zid.h" +#include "ztim.h" #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/zlib/zlog.h b/zlib/zlog.h index 5876922..4e0351f 100644 --- a/zlib/zlog.h +++ b/zlib/zlog.h @@ -4,33 +4,44 @@ extern bool g_xs_enable_log; #define ZLOG_RELEASE(TAG, fmt, ...) \ - if (g_xs_enable_log) { \ - zlog(TAG "" fmt "\n", ##__VA_ARGS__); \ + if (g_xs_enable_log) { \ + zlog(TAG "" fmt "\n", ##__VA_ARGS__); \ } -#define ZLOGI(TAG, fmt, ...) \ - if (g_xs_enable_log) { \ - zlog("%08lu INFO [%-8s] " fmt "\n",zget_ticket(), TAG, ##__VA_ARGS__); \ +#define ZLOGI(TAG, fmt, ...) \ + if (g_xs_enable_log) { \ + zlog("%08lu INFO [%-8s] " fmt "\n", zget_ticket(), TAG, ##__VA_ARGS__); \ } -#define ZLOGD(TAG, fmt, ...) \ - if (g_xs_enable_log) { \ - zlog("%08lu DEBU [%-8s] " fmt "\n",zget_ticket(), TAG, ##__VA_ARGS__); \ +#define ZLOGD(TAG, fmt, ...) \ + if (g_xs_enable_log) { \ + zlog("%08lu DEBU [%-8s] " fmt "\n", zget_ticket(), TAG, ##__VA_ARGS__); \ } -#define ZLOGE(TAG, fmt, ...) \ - if (g_xs_enable_log) { \ - zlog("%08lu ERRO [%-8s] " fmt "\n",zget_ticket(), TAG, ##__VA_ARGS__); \ +#define ZLOGE(TAG, fmt, ...) \ + if (g_xs_enable_log) { \ + zlog("%08lu ERRO [%-8s] " fmt "\n", zget_ticket(), TAG, ##__VA_ARGS__); \ } -#define ZLOGW(TAG, fmt, ...) \ - if (g_xs_enable_log) { \ - zlog("%08lu WARN [%-8s] " fmt "\n",zget_ticket(), TAG, ##__VA_ARGS__); \ +#define ZLOGW(TAG, fmt, ...) \ + if (g_xs_enable_log) { \ + zlog("%08lu WARN [%-8s] " fmt "\n", zget_ticket(), TAG, ##__VA_ARGS__); \ } #define ZASSERT(cond) \ - if (!(cond)) { \ - while (1) { \ - zlog("ASSERT: %s [%s:%d]\n", #cond, __FILE__, __LINE__); \ - zdelay_ms(1000); \ - } \ + if (!(cond)) { \ + while (1) { \ + zlog("ASSERT: %s [%s:%d]\n", #cond, __FILE__, __LINE__); \ + zdelay_ms(1000); \ + } \ + } + +#define ZSTM32_CHECK(exptr) \ + { \ + HAL_StatusTypeDef __ecode = (exptr); \ + if (__ecode != HAL_OK) { \ + while (true) { \ + zlog("STM32 HAL error: %d [%s:%d]\n", __ecode, __FILE__, __LINE__); \ + zdelay_ms(1000); \ + } \ + } \ } void zlog(const char* fmt, ...); diff --git a/zlib/ztim.c b/zlib/ztim.c new file mode 100644 index 0000000..616c333 --- /dev/null +++ b/zlib/ztim.c @@ -0,0 +1,84 @@ +#include "ztim.h" +#include "zlog.h" +static float zfeq(float val0, float val1, float eps) { + float dv = val0 - val1; + if (dv < 0) dv = -dv; + if (dv < eps) return true; + return false; +} + + bool chip_calculate_prescaler_and_autoreload_by_expect_freq(uint32_t timerInClk, float infreqhz, uint32_t* prescaler, uint32_t* autoreload) { + /** + * @brief 计算寄存器数值 + */ + ZASSERT(!zfeq(infreqhz, 0, 0.01)); + float psc_x_arr = timerInClk / infreqhz; + uint32_t psc = 0; + uint32_t arr = 65534; + for (; arr > 2; arr--) { + psc = psc_x_arr / arr; + if (psc >= 1) { + uint32_t tmparr = psc_x_arr / psc; + if (tmparr >= 65534) continue; + break; + } + } + if (psc == 0) return false; + if (arr <= 3) return false; // 定时器一周期的分辨率太小了 + arr = psc_x_arr / psc; + + //int psc_x_arr_real = arr * psc; + //float realfreq = timerInClk / psc_x_arr_real; + + arr = arr - 1; + psc = psc - 1; + // uint16_t comparevalue = 50 / 100.0 * arr; + + *prescaler = psc; + *autoreload = arr; + return true; +} + +uint32_t chip_get_timer_clock_sorce_freq(TIM_HandleTypeDef* tim) { + uint32_t timClkFreq = 0; +#if 0 + uint32_t pclk1Freq = HAL_RCC_GetPCLK1Freq(); + uint32_t pclk2Freq = HAL_RCC_GetPCLK2Freq(); + uint32_t sysClkFreq = HAL_RCC_GetSysClockFreq(); +#endif + + uint32_t pFLatency; + RCC_ClkInitTypeDef clkconfig; + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + bool isAPB2 = false; + +#ifdef TIM1 + if (tim->Instance == TIM1) isAPB2 = true; +#endif +#ifdef TIM8 + if (tim->Instance == TIM8) isAPB2 = true; +#endif +#ifdef TIM9 + if (tim->Instance == TIM9) isAPB2 = true; +#endif +#ifdef TIM10 + if (tim->Instance == TIM10) isAPB2 = true; +#endif +#ifdef TIM11 + if (tim->Instance == TIM11) isAPB2 = true; +#endif + if (isAPB2) { + if (clkconfig.APB2CLKDivider == RCC_HCLK_DIV1) { + timClkFreq = HAL_RCC_GetPCLK2Freq(); + } else { + timClkFreq = 2 * HAL_RCC_GetPCLK2Freq(); + } + } else { + if (clkconfig.APB1CLKDivider == RCC_HCLK_DIV1) { + timClkFreq = HAL_RCC_GetPCLK1Freq(); + } else { + timClkFreq = 2 * HAL_RCC_GetPCLK1Freq(); + } + } + return timClkFreq; +} diff --git a/zlib/ztim.h b/zlib/ztim.h new file mode 100644 index 0000000..6e11a3b --- /dev/null +++ b/zlib/ztim.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +#include "main.h" + +bool chip_calculate_prescaler_and_autoreload_by_expect_freq(uint32_t timerInClk, float infreqhz, uint32_t* prescaler, uint32_t* autoreload); +uint32_t chip_get_timer_clock_sorce_freq(TIM_HandleTypeDef* tim);