diff --git a/Core/Src/main.c b/Core/Src/main.c index 88ec0c9..68e5012 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -42,6 +42,7 @@ /* Private variables ---------------------------------------------------------*/ ADC_HandleTypeDef hadc1; +TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim4; /* USER CODE BEGIN PV */ @@ -53,6 +54,7 @@ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM4_Init(void); static void MX_ADC1_Init(void); +static void MX_TIM1_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -92,9 +94,11 @@ int main(void) MX_GPIO_Init(); MX_TIM4_Init(); MX_ADC1_Init(); + MX_TIM1_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htim4); + HAL_TIM_Base_Start_IT(&htim1); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); @@ -107,13 +111,28 @@ int main(void) uint32_t adc = 0; - const float Kp = 0.0; - const float Ki = 0.0; + uint16_t t = htim1.Instance->CNT; + uint16_t dt = 0; + uint16_t pt = 0; - bool automode = true; + const float Kp = 12.5; + const float Ki = 15; + + float error = 0.0; + float integral = 0.0; + + bool automode = false; char change = 0; - bool page = false; - bool convert = false; + char page = 2; + bool convert = true; + + float uTarget = 5.0; + float pi = 0.0; + uint16_t ccr = 0; + + #define r1 14820 + #define r2 9940 + const float ratio = (float)(r1 + r2) / (float)r2; /* USER CODE END 2 */ /* Infinite loop */ @@ -132,58 +151,102 @@ int main(void) unsigned int freq = 84000000 / clkCnt; float dc = ((float)pwmCnt / (float)clkCnt) * 100.0; - #define r1 14820 - #define r2 9940 - const float ratio = (float)(r1 + r2) / (float)r2; + // Timer + t = htim1.Instance->CNT; + dt = t - pt; + pt = t; + // Read ADC HAL_ADC_Start(&hadc1); if(HAL_ADC_PollForConversion(&hadc1, 5) == HAL_OK) { adc = HAL_ADC_GetValue(&hadc1); } - if (page) + // ADC to Volts + float u = ((float)(adc / 4095.0) * 3.0); + + if (automode) { - // PWM CCR - LCD_XY(0, 0); - LCD_puts("CCR "); - LCD_putint(pwmCnt); + error = uTarget - (u * ratio); + integral += (float)(error * (float)(dt / 1000000.0)); - // CLOCK CCR - LCD_XY(8, 0); - LCD_puts(" AR "); - LCD_putint(clkCnt); - } - else - { - // PWM CCR - LCD_XY(0, 0); - LCD_puts("ADC "); - LCD_XY(4, 0); - LCD_putint(adc); + pi = Kp * error + Ki * integral + 50; + ccr = (float)(pi / 100.0) * clkCnt; - // ADC to Volts - float u = ((float)(adc / 4095.0) * 3.0); - - // Convert with resistor divider in mind if enabled - if (convert) - { - u = u * ratio; + if (ccr >= 0 && ccr <= clkCnt) { + htim4.Instance->CCR1 = ccr; + htim4.Instance->CCR3 = ccr; } + } - char ustr[7] = {0}; - sprintf(&ustr, "%.2f V", u); - LCD_XY(10, 0); - LCD_puts(ustr); + // Display + char ustr[8] = {0}; + + switch(page){ + case 0: + // PWM CCR + LCD_XY(0, 0); + LCD_puts("CCR "); + LCD_putint(pwmCnt); + + // CLOCK CCR + LCD_XY(8, 0); + LCD_puts(" AR "); + LCD_putint(clkCnt); + break; + + case 1: + case 2: + LCD_XY(0, 0); + + if (page == 1) { + // ADC value in spot 1 + LCD_puts("ADC "); + LCD_XY(4, 0); + LCD_putint(adc); + } else { + // Target voltage in spot 1 + sprintf(&ustr, "Ut %.2f V", uTarget); + LCD_puts(ustr); + } + + memset(&ustr, '0', 8); + + // Convert with resistor divider in mind if enabled + float uC = u; + if (convert) + { + uC = u * ratio; + } + + // Measured voltage in spot 2 + sprintf(&ustr, "%.2f V", uC); + LCD_XY(10, 0); + LCD_puts(ustr); + break; + case 3: + sprintf(&ustr, "Out %.2f", pi); + LCD_XY(0, 0); + LCD_puts(ustr); + + memset(&ustr, '0', 8); + + sprintf(&ustr, "r %d", ccr); + LCD_XY(10, 0); + LCD_puts(ustr); + break; } // Frequency LCD_XY(0, 1); - LCD_putint(freq); - LCD_puts(" Hz"); + LCD_putint(freq / 1000); + LCD_puts("KHz"); // Dutycycle - LCD_XY(10, 1); - LCD_putint((int)dc); + LCD_XY(8, 1); + char dcstr[4] = {0}; + sprintf(&dcstr, "%.1f", dc); + LCD_puts(dcstr); LCD_putchar('%'); // Auto mode enabled @@ -194,6 +257,7 @@ int main(void) { change = result; + // Set frequency if (result == 1) { htim4.Instance->ARR = 2799; @@ -208,6 +272,8 @@ int main(void) htim4.Instance->CCR3 = (htim4.Instance->ARR + 1) / 2; LCD_clear(); } + + // Set dutycycle else if (result == 4) { htim4.Instance->CCR1 = htim4.Instance->CCR1 + (clkCnt / 20); @@ -218,18 +284,59 @@ int main(void) { htim4.Instance->CCR1 = htim4.Instance->CCR1 - (clkCnt / 20); htim4.Instance->CCR3 = htim4.Instance->CCR3 - (clkCnt / 20); + } + + else if (result == 11) + { + htim4.Instance->CCR1 = htim4.Instance->CCR1 + (clkCnt / 100); + htim4.Instance->CCR3 = htim4.Instance->CCR3 + (clkCnt / 100); } + else if (result == 12) + { + htim4.Instance->CCR1 = htim4.Instance->CCR1 - (clkCnt / 100); + htim4.Instance->CCR3 = htim4.Instance->CCR3 - (clkCnt / 100); + } + + // Set target voltage (step .1 V) + else if (result == 2) + { + uTarget = uTarget + 0.5; + } + else if (result == 6) + { + uTarget = uTarget - 0.5; + } + + // Set target voltage (step .5 V) + else if (result == 3) + { + uTarget = uTarget + 0.1; + } + else if (result == 7) + { + uTarget = uTarget - 0.1; + } + + // Convert ADC to actual voltage else if (result == 13) { convert = !convert; LCD_clear(); } + + // Switch pages else if (result == 15) { - page = !page; + if (page + 1 == 4) { + page = 0; + } else { + page++; + } LCD_clear(); } + + // Switch off PI control else if (result == 16) { automode = !automode; @@ -237,8 +344,6 @@ int main(void) } else { change = 0; } - - HAL_Delay(100); } /* USER CODE END 3 */ } @@ -340,6 +445,80 @@ static void MX_ADC1_Init(void) } +/** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM1_Init(void) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + htim1.Instance = TIM1; + htim1.Init.Prescaler = 1680-1; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 65535; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_OC_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_TIMING; + sConfigOC.Pulse = 0; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; + sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; + sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; + sBreakDeadTimeConfig.DeadTime = 0; + sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; + sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; + sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; + if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + +} + /** * @brief TIM4 Initialization Function * @param None diff --git a/Core/Src/stm32f4xx_hal_msp.c b/Core/Src/stm32f4xx_hal_msp.c index f0db5ce..e455781 100644 --- a/Core/Src/stm32f4xx_hal_msp.c +++ b/Core/Src/stm32f4xx_hal_msp.c @@ -150,7 +150,18 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) */ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM4) + if(htim_base->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspInit 0 */ + + /* USER CODE END TIM1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM1_CLK_ENABLE(); + /* USER CODE BEGIN TIM1_MspInit 1 */ + + /* USER CODE END TIM1_MspInit 1 */ + } + else if(htim_base->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspInit 0 */ @@ -202,7 +213,18 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM4) + if(htim_base->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspDeInit 0 */ + + /* USER CODE END TIM1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM1_CLK_DISABLE(); + /* USER CODE BEGIN TIM1_MspDeInit 1 */ + + /* USER CODE END TIM1_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspDeInit 0 */ diff --git a/HW_Ont_sem5.ioc b/HW_Ont_sem5.ioc index 3f3f137..2ac6905 100644 --- a/HW_Ont_sem5.ioc +++ b/HW_Ont_sem5.ioc @@ -19,8 +19,9 @@ Mcu.IP0=ADC1 Mcu.IP1=NVIC Mcu.IP2=RCC Mcu.IP3=SYS -Mcu.IP4=TIM4 -Mcu.IPNb=5 +Mcu.IP4=TIM1 +Mcu.IP5=TIM4 +Mcu.IPNb=6 Mcu.Name=STM32F407V(E-G)Tx Mcu.Package=LQFP100 Mcu.Pin0=PE3 @@ -37,7 +38,9 @@ Mcu.Pin18=PD0 Mcu.Pin19=PE1 Mcu.Pin2=PE5 Mcu.Pin20=VP_SYS_VS_Systick -Mcu.Pin21=VP_TIM4_VS_ClockSourceINT +Mcu.Pin21=VP_TIM1_VS_ClockSourceINT +Mcu.Pin22=VP_TIM1_VS_no_output1 +Mcu.Pin23=VP_TIM4_VS_ClockSourceINT Mcu.Pin3=PE6 Mcu.Pin4=PC13-ANTI_TAMP Mcu.Pin5=PC14-OSC32_IN @@ -45,7 +48,7 @@ Mcu.Pin6=PC15-OSC32_OUT Mcu.Pin7=PH0-OSC_IN Mcu.Pin8=PH1-OSC_OUT Mcu.Pin9=PC1 -Mcu.PinsNb=22 +Mcu.PinsNb=24 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F407VGTx @@ -185,7 +188,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_TIM4_Init-TIM4-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_TIM4_Init-TIM4-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM1_Init-TIM1-false-HAL-true RCC.48MHZClocksFreq_Value=48000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -231,6 +234,9 @@ SH.S_TIM4_CH1.0=TIM4_CH1,PWM Generation1 CH1 SH.S_TIM4_CH1.ConfNb=1 SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3 SH.S_TIM4_CH3.ConfNb=1 +TIM1.Channel-Output\ Compare1\ No\ Output=TIM_CHANNEL_1 +TIM1.IPParameters=Channel-Output Compare1 No Output,Prescaler +TIM1.Prescaler=1680-1 TIM4.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE TIM4.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 @@ -242,6 +248,10 @@ TIM4.Pulse-PWM\ Generation1\ CH1=1400 TIM4.Pulse-PWM\ Generation3\ CH3=1400 VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM1_VS_ClockSourceINT.Mode=Internal +VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT +VP_TIM1_VS_no_output1.Mode=Output Compare1 No Output +VP_TIM1_VS_no_output1.Signal=TIM1_VS_no_output1 VP_TIM4_VS_ClockSourceINT.Mode=Internal VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT board=STM32F407G-DISC1