合并代码(有错)

This commit is contained in:
许晟昊 2024-11-26 14:16:38 +08:00
parent c32647126a
commit 3f0e203c4c
317 changed files with 117961 additions and 17237 deletions

View File

@ -1,5 +1,5 @@
[PreviousLibFiles]
LibFiles=Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_system.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dmamux.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_bus.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_crs.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_utils.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_exti.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dac.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_i2c.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_spi.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_tim.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_usart.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_i2c.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_system.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dmamux.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_bus.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_crs.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_utils.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_exti.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dac.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_i2c.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_spi.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_tim.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l476xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l4xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\system_stm32l4xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
LibFiles=Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_system.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dmamux.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_bus.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_crs.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_utils.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_exti.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dac.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_spi.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_tim.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_usart.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_gpio.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_system.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_adc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dma.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dmamux.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_bus.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_cortex.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_rcc.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_crs.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_utils.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_exti.h;Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_pwr.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_dac.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_spi.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_tim.h;Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l476xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l4xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Include\system_stm32l4xx.h;Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
[PreviousUsedIarFiles]
SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\adc.c;..\Core\Src\dac.c;..\Core\Src\dma.c;..\Core\Src\i2c.c;..\Core\Src\iwdg.c;..\Core\Src\spi.c;..\Core\Src\tim.c;..\Core\Src\usart.c;..\Core\Src\stm32l4xx_it.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_i2c.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;..\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;..\Core\Src\system_stm32l4xx.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_i2c.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;..\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;..\Core\Src\system_stm32l4xx.c;;;
@ -7,41 +7,39 @@ HeaderPath=..\Drivers\STM32L4xx_HAL_Driver\Inc;..\Drivers\CMSIS\Device\ST\STM32L
CDefines=USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:4000000;EXTERNALSAI1_CLOCK_VALUE:2097000;EXTERNALSAI2_CLOCK_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;STM32L476xx;USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:4000000;EXTERNALSAI1_CLOCK_VALUE:2097000;EXTERNALSAI2_CLOCK_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;
[PreviousUsedKeilFiles]
SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\adc.c;..\Core\Src\dac.c;..\Core\Src\dma.c;..\Core\Src\i2c.c;..\Core\Src\spi.c;..\Core\Src\tim.c;..\Core\Src\usart.c;..\Core\Src\stm32l4xx_it.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_i2c.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;..\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;..\Core\Src\system_stm32l4xx.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_i2c.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;..\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;..\Core\Src\system_stm32l4xx.c;;;
SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\adc.c;..\Core\Src\dac.c;..\Core\Src\dma.c;..\Core\Src\spi.c;..\Core\Src\tim.c;..\Core\Src\usart.c;..\Core\Src\stm32l4xx_it.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;..\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;..\Core\Src\system_stm32l4xx.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_utils.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_exti.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_gpio.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_adc.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dma.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_dac.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_spi.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_pwr.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_tim.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_usart.c;..\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_ll_rcc.c;..\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c;..\Core\Src\system_stm32l4xx.c;;;
HeaderPath=..\Drivers\STM32L4xx_HAL_Driver\Inc;..\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\Drivers\CMSIS\Include;..\Middlewares\ST\ARM\DSP\Inc;..\Core\Inc;
CDefines=USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:16000000;EXTERNALSAI1_CLOCK_VALUE:2097000;EXTERNALSAI2_CLOCK_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:1;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;STM32L476xx;USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:16000000;EXTERNALSAI1_CLOCK_VALUE:2097000;EXTERNALSAI2_CLOCK_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:1;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;
CDefines=USE_FULL_LL_DRIVER;HSE_VALUE:11059200;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:16000000;EXTERNALSAI1_CLOCK_VALUE:2097000;EXTERNALSAI2_CLOCK_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;STM32L476xx;USE_FULL_LL_DRIVER;HSE_VALUE:11059200;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:16000000;EXTERNALSAI1_CLOCK_VALUE:2097000;EXTERNALSAI2_CLOCK_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;
[]
SourceFiles=;;
[PreviousGenFiles]
AdvancedFolderStructure=true
HeaderFileListSize=11
HeaderFileListSize=10
HeaderFiles#0=..\Core\Inc\gpio.h
HeaderFiles#1=..\Core\Inc\adc.h
HeaderFiles#2=..\Core\Inc\dac.h
HeaderFiles#3=..\Core\Inc\dma.h
HeaderFiles#4=..\Core\Inc\i2c.h
HeaderFiles#5=..\Core\Inc\spi.h
HeaderFiles#6=..\Core\Inc\tim.h
HeaderFiles#7=..\Core\Inc\usart.h
HeaderFiles#8=..\Core\Inc\stm32l4xx_it.h
HeaderFiles#9=..\Core\Inc\stm32_assert.h
HeaderFiles#10=..\Core\Inc\main.h
HeaderFiles#4=..\Core\Inc\spi.h
HeaderFiles#5=..\Core\Inc\tim.h
HeaderFiles#6=..\Core\Inc\usart.h
HeaderFiles#7=..\Core\Inc\stm32l4xx_it.h
HeaderFiles#8=..\Core\Inc\stm32_assert.h
HeaderFiles#9=..\Core\Inc\main.h
HeaderFolderListSize=1
HeaderPath#0=..\Core\Inc
HeaderFiles=;
SourceFileListSize=10
SourceFileListSize=9
SourceFiles#0=..\Core\Src\gpio.c
SourceFiles#1=..\Core\Src\adc.c
SourceFiles#2=..\Core\Src\dac.c
SourceFiles#3=..\Core\Src\dma.c
SourceFiles#4=..\Core\Src\i2c.c
SourceFiles#5=..\Core\Src\spi.c
SourceFiles#6=..\Core\Src\tim.c
SourceFiles#7=..\Core\Src\usart.c
SourceFiles#8=..\Core\Src\stm32l4xx_it.c
SourceFiles#9=..\Core\Src\main.c
SourceFiles#4=..\Core\Src\spi.c
SourceFiles#5=..\Core\Src\tim.c
SourceFiles#6=..\Core\Src\usart.c
SourceFiles#7=..\Core\Src\stm32l4xx_it.c
SourceFiles#8=..\Core\Src\main.c
SourceFolderListSize=1
SourcePath#0=..\Core\Src
SourceFiles=;

View File

@ -1,20 +1,20 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "C:\\MinGW\\bin\\gcc.exe",
"cStandard": "c11",
"cppStandard": "gnu++14",
"intelliSenseMode": "windows-gcc-x86"
}
],
"version": 4
"configurations": [
{
"name": "windows-gcc-x64",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "C:/TDM-GCC-64/bin/gcc.exe",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}

4
.vscode/launch.json vendored
View File

@ -8,8 +8,8 @@
"args": [],
"stopAtEntry": false,
"externalConsole": true,
"cwd": "c:/Users/xushenghao/Desktop/controller-hd/User/application/mode",
"program": "c:/Users/xushenghao/Desktop/controller-hd/User/application/mode/build/Debug/outDebug",
"cwd": "e:/work/stm32/不经常用的代码/controller-hd/User/system/bsp",
"program": "e:/work/stm32/不经常用的代码/controller-hd/User/system/bsp/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [

View File

@ -37,7 +37,6 @@ extern "C" {
/* USER CODE END Private defines */
void MX_ADC1_Init(void);
void MX_ADC2_Init(void);
/* USER CODE BEGIN Prototypes */

View File

@ -1,50 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file i2c.h
* @brief This file contains all the function prototypes for
* the i2c.c file
******************************************************************************
* @attention
*
* Copyright (c) 2024 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __I2C_H__
#define __I2C_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_I2C1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __I2C_H__ */

View File

@ -31,7 +31,6 @@ extern "C" {
#include "stm32l4xx_ll_adc.h"
#include "stm32l4xx_ll_dac.h"
#include "stm32l4xx_ll_dma.h"
#include "stm32l4xx_ll_i2c.h"
#include "stm32l4xx_ll_crs.h"
#include "stm32l4xx_ll_rcc.h"
#include "stm32l4xx_ll_bus.h"
@ -78,8 +77,8 @@ void Error_Handler(void);
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define PWM_OUT_Pin LL_GPIO_PIN_5
#define PWM_OUT_GPIO_Port GPIOE
#define DAC161P997_Pin LL_GPIO_PIN_5
#define DAC161P997_GPIO_Port GPIOE
#define RTC_SCL_Pin LL_GPIO_PIN_0
#define RTC_SCL_GPIO_Port GPIOC
#define RTC_SDA_Pin LL_GPIO_PIN_1
@ -88,6 +87,8 @@ void Error_Handler(void);
#define SWO1_GPIO_Port GPIOC
#define SWO2_Pin LL_GPIO_PIN_3
#define SWO2_GPIO_Port GPIOC
#define ADC_LOOP_CHANNEL_Pin LL_GPIO_PIN_0
#define ADC_LOOP_CHANNEL_GPIO_Port GPIOA
#define ADC_PSB_CHANNEL_Pin LL_GPIO_PIN_1
#define ADC_PSB_CHANNEL_GPIO_Port GPIOA
#define ADC_BP_CHANNEL_Pin LL_GPIO_PIN_2
@ -108,8 +109,8 @@ void Error_Handler(void);
#define ADC_BPB_CHANNEL_GPIO_Port GPIOC
#define HART_PWR_Pin LL_GPIO_PIN_0
#define HART_PWR_GPIO_Port GPIOB
#define IP_PWR_Pin LL_GPIO_PIN_1
#define IP_PWR_GPIO_Port GPIOB
#define ADC_VDD_CHANNEL_Pin LL_GPIO_PIN_1
#define ADC_VDD_CHANNEL_GPIO_Port GPIOB
#define IP_H_PWR_Pin LL_GPIO_PIN_2
#define IP_H_PWR_GPIO_Port GPIOB
#define BP_A_PWR_Pin LL_GPIO_PIN_7
@ -128,6 +129,8 @@ void Error_Handler(void);
#define LCD_CS_GPIO_Port GPIOB
#define LCD_SCK_Pin LL_GPIO_PIN_13
#define LCD_SCK_GPIO_Port GPIOB
#define LCD_EXTCOMIN_Pin LL_GPIO_PIN_14
#define LCD_EXTCOMIN_GPIO_Port GPIOB
#define LCD_MOSI_Pin LL_GPIO_PIN_15
#define LCD_MOSI_GPIO_Port GPIOB
#define LCD_DISP_Pin LL_GPIO_PIN_8
@ -164,8 +167,11 @@ void Error_Handler(void);
#define BLE_TX_GPIO_Port GPIOC
#define HART_CD_Pin LL_GPIO_PIN_0
#define HART_CD_GPIO_Port GPIOD
#define HART_CD_EXTI_IRQn EXTI0_IRQn
#define BLE_RX_Pin LL_GPIO_PIN_2
#define BLE_RX_GPIO_Port GPIOD
#define EE3_CS_Pin LL_GPIO_PIN_4
#define EE3_CS_GPIO_Port GPIOD
#define EE2_CS_Pin LL_GPIO_PIN_5
#define EE2_CS_GPIO_Port GPIOD
#define EE1_CS_Pin LL_GPIO_PIN_6
@ -186,10 +192,6 @@ void Error_Handler(void);
#define I2C1_SCL_GPIO_Port GPIOB
#define I2C1_SDA_Pin LL_GPIO_PIN_9
#define I2C1_SDA_GPIO_Port GPIOB
#define I2C2_SCL_Pin LL_GPIO_PIN_0
#define I2C2_SCL_GPIO_Port GPIOE
#define I2C2_SDA_Pin LL_GPIO_PIN_1
#define I2C2_SDA_GPIO_Port GPIOE
#ifndef NVIC_PRIORITYGROUP_0
#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
4 bits for subpriority */

View File

@ -55,13 +55,12 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void EXTI0_IRQHandler(void);
void DMA1_Channel1_IRQHandler(void);
void DMA1_Channel2_IRQHandler(void);
void DMA1_Channel5_IRQHandler(void);
void DMA1_Channel6_IRQHandler(void);
void DMA1_Channel7_IRQHandler(void);
void ADC1_2_IRQHandler(void);
void I2C1_EV_IRQHandler(void);
void TIM1_UP_TIM16_IRQHandler(void);
void TIM1_TRG_COM_TIM17_IRQHandler(void);
void USART1_IRQHandler(void);
void UART5_IRQHandler(void);
void TIM6_DAC_IRQHandler(void);

View File

@ -40,6 +40,8 @@ void MX_TIM2_Init(void);
void MX_TIM3_Init(void);
void MX_TIM6_Init(void);
void MX_TIM7_Init(void);
void MX_TIM16_Init(void);
void MX_TIM17_Init(void);
/* USER CODE BEGIN Prototypes */

View File

@ -45,6 +45,7 @@ void MX_ADC1_Init(void)
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
/**ADC1 GPIO Configuration
PA0 ------> ADC1_IN5
PA1 ------> ADC1_IN6
@ -55,8 +56,9 @@ void MX_ADC1_Init(void)
PA7 ------> ADC1_IN12
PC4 ------> ADC1_IN13
PC5 ------> ADC1_IN14
PB1 ------> ADC1_IN16
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|ADC_PSB_CHANNEL_Pin|ADC_BP_CHANNEL_Pin|ADC_IPSB_CHANNEL_Pin
GPIO_InitStruct.Pin = ADC_LOOP_CHANNEL_Pin|ADC_PSB_CHANNEL_Pin|ADC_BP_CHANNEL_Pin|ADC_IPSB_CHANNEL_Pin
|ADC_NTC_CHANNEL_Pin|ADC_VIP_CHANNEL_Pin|ADC_DCDC_CHANNEL_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
@ -67,11 +69,18 @@ void MX_ADC1_Init(void)
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
LL_GPIO_EnablePinAnalogControl(GPIOA, LL_GPIO_PIN_0|ADC_PSB_CHANNEL_Pin|ADC_BP_CHANNEL_Pin|ADC_IPSB_CHANNEL_Pin
GPIO_InitStruct.Pin = ADC_VDD_CHANNEL_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(ADC_VDD_CHANNEL_GPIO_Port, &GPIO_InitStruct);
LL_GPIO_EnablePinAnalogControl(GPIOA, ADC_LOOP_CHANNEL_Pin|ADC_PSB_CHANNEL_Pin|ADC_BP_CHANNEL_Pin|ADC_IPSB_CHANNEL_Pin
|ADC_NTC_CHANNEL_Pin|ADC_VIP_CHANNEL_Pin|ADC_DCDC_CHANNEL_Pin);
LL_GPIO_EnablePinAnalogControl(GPIOC, ADC_BPA_CHANNEL_Pin|ADC_BPB_CHANNEL_Pin);
LL_GPIO_EnablePinAnalogControl(ADC_VDD_CHANNEL_GPIO_Port, ADC_VDD_CHANNEL_Pin);
/* ADC1 DMA Init */
/* ADC1 Init */
@ -92,7 +101,7 @@ void MX_ADC1_Init(void)
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
/* ADC1 interrupt Init */
NVIC_SetPriority(ADC1_2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),14, 0));
NVIC_SetPriority(ADC1_2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(ADC1_2_IRQn);
/* USER CODE BEGIN ADC1_Init 1 */
@ -106,14 +115,14 @@ void MX_ADC1_Init(void)
ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS;
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_CHANNEL_VREFINT|LL_ADC_CHANNEL_TEMPSENSOR);
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV64;
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV16;
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
@ -137,180 +146,78 @@ void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_6);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_6, LL_ADC_SAMPLINGTIME_47CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_6, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_6, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_7);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SAMPLINGTIME_47CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_8);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SAMPLINGTIME_47CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_9);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, LL_ADC_CHANNEL_11);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_7, LL_ADC_CHANNEL_12);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_8, LL_ADC_CHANNEL_13);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_13, LL_ADC_SAMPLINGTIME_47CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_13, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_13, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_9, LL_ADC_CHANNEL_14);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_14, LL_ADC_SAMPLINGTIME_47CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_14, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_14, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_10, LL_ADC_CHANNEL_VREFINT);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_VREFINT, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_VREFINT, LL_ADC_SINGLE_ENDED);
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_10, LL_ADC_CHANNEL_16);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_16, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_16, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_11, LL_ADC_CHANNEL_TEMPSENSOR);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_TEMPSENSOR, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_TEMPSENSOR, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_TEMPSENSOR, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_12, LL_ADC_CHANNEL_VREFINT);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_VREFINT, LL_ADC_SAMPLINGTIME_12CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_VREFINT, LL_ADC_SINGLE_ENDED);
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/* ADC2 init function */
void MX_ADC2_Init(void)
{
/* USER CODE BEGIN ADC2_Init 0 */
/* USER CODE END ADC2_Init 0 */
LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1);
/* Peripheral clock enable */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
/**ADC2 GPIO Configuration
PA0 ------> ADC2_IN5
PA1 ------> ADC2_IN6
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|ADC_PSB_CHANNEL_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
LL_GPIO_EnablePinAnalogControl(GPIOA, LL_GPIO_PIN_0|ADC_PSB_CHANNEL_Pin);
/* ADC2 DMA Init */
/* ADC2 Init */
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_2, LL_DMA_REQUEST_0);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MDATAALIGN_HALFWORD);
/* ADC2 interrupt Init */
NVIC_SetPriority(ADC1_2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),14, 0));
NVIC_EnableIRQ(ADC1_2_IRQn);
/* USER CODE BEGIN ADC2_Init 1 */
/* USER CODE END ADC2_Init 1 */
/** Common config
*/
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
LL_ADC_Init(ADC2, &ADC_InitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS;
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
LL_ADC_REG_Init(ADC2, &ADC_REG_InitStruct);
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV64;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC2), &ADC_CommonInitStruct);
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC2), LL_ADC_PATH_INTERNAL_NONE);
/* Disable ADC deep power down (enabled by default after reset state) */
LL_ADC_DisableDeepPowerDown(ADC2);
/* Enable ADC internal voltage regulator */
LL_ADC_EnableInternalRegulator(ADC2);
/* Delay for ADC internal voltage regulator stabilization. */
/* Compute number of CPU cycles to wait for, from delay in us. */
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles (depends on compilation optimization). */
/* Note: If system core clock frequency is below 200kHz, wait time */
/* is only a few CPU processing cycles. */
uint32_t wait_loop_index;
wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
while(wait_loop_index != 0)
{
wait_loop_index--;
}
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC2, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5);
LL_ADC_SetChannelSamplingTime(ADC2, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC2, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC2, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_6);
LL_ADC_SetChannelSamplingTime(ADC2, LL_ADC_CHANNEL_6, LL_ADC_SAMPLINGTIME_640CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC2, LL_ADC_CHANNEL_6, LL_ADC_SINGLE_ENDED);
/* USER CODE BEGIN ADC2_Init 2 */
/* USER CODE END ADC2_Init 2 */
}
/* USER CODE BEGIN 1 */

View File

@ -46,31 +46,22 @@ void MX_DMA_Init(void)
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),14, 0));
NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_IRQn interrupt configuration */
NVIC_SetPriority(DMA1_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* DMA1_Channel5_IRQn interrupt configuration */
NVIC_SetPriority(DMA1_Channel5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),14, 0));
NVIC_SetPriority(DMA1_Channel5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(DMA1_Channel5_IRQn);
/* DMA1_Channel6_IRQn interrupt configuration */
NVIC_SetPriority(DMA1_Channel6_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA1_Channel6_IRQn);
/* DMA1_Channel7_IRQn interrupt configuration */
NVIC_SetPriority(DMA1_Channel7_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA1_Channel7_IRQn);
/* DMA2_Channel1_IRQn interrupt configuration */
NVIC_SetPriority(DMA2_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_SetPriority(DMA2_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(DMA2_Channel1_IRQn);
/* DMA2_Channel2_IRQn interrupt configuration */
NVIC_SetPriority(DMA2_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_SetPriority(DMA2_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(DMA2_Channel2_IRQn);
/* DMA2_Channel6_IRQn interrupt configuration */
NVIC_SetPriority(DMA2_Channel6_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_SetPriority(DMA2_Channel6_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(DMA2_Channel6_IRQn);
/* DMA2_Channel7_IRQn interrupt configuration */
NVIC_SetPriority(DMA2_Channel7_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_SetPriority(DMA2_Channel7_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(DMA2_Channel7_IRQn);
}

View File

@ -44,6 +44,7 @@
void MX_GPIO_Init(void)
{
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
@ -54,20 +55,20 @@ void MX_GPIO_Init(void)
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD);
/**/
LL_GPIO_ResetOutputPin(GPIOE, DAC161P997_Pin|BP_A_PWR_Pin|BP_S_PWR_Pin|BP_B_PWR_Pin);
/**/
LL_GPIO_ResetOutputPin(GPIOC, RTC_SCL_Pin|RTC_SDA_Pin|SWO1_Pin|SWO2_Pin
|HART_RST_Pin);
/**/
LL_GPIO_ResetOutputPin(GPIOB, HART_PWR_Pin|IP_PWR_Pin|IP_H_PWR_Pin|LCD_PWR_Pin
|LCD_CS_Pin);
LL_GPIO_ResetOutputPin(GPIOB, HART_PWR_Pin|IP_H_PWR_Pin|LCD_PWR_Pin|LCD_CS_Pin
|I2C1_SCL_Pin|I2C1_SDA_Pin);
/**/
LL_GPIO_ResetOutputPin(GPIOE, BP_A_PWR_Pin|BP_S_PWR_Pin|BP_B_PWR_Pin|I2C2_SCL_Pin
|I2C2_SDA_Pin);
/**/
LL_GPIO_ResetOutputPin(GPIOD, LCD_DISP_Pin|EE2_CS_Pin|EE1_CS_Pin|BLE_PWR_Pin);
LL_GPIO_ResetOutputPin(GPIOD, LCD_DISP_Pin|EE3_CS_Pin|EE2_CS_Pin|EE1_CS_Pin
|BLE_PWR_Pin);
/**/
LL_GPIO_ResetOutputPin(GPIOA, HART_RTS_Pin|BLE_RST_Pin);
@ -77,13 +78,21 @@ void MX_GPIO_Init(void)
|LED5_Pin);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_2|LL_GPIO_PIN_3|LL_GPIO_PIN_4|LL_GPIO_PIN_6
|LL_GPIO_PIN_10|LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_13
|LL_GPIO_PIN_14;
GPIO_InitStruct.Pin = LL_GPIO_PIN_2|LL_GPIO_PIN_3|LL_GPIO_PIN_6|LL_GPIO_PIN_10
|LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_13|LL_GPIO_PIN_14
|LL_GPIO_PIN_0|LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = DAC161P997_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
LL_GPIO_Init(DAC161P997_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15|LL_GPIO_PIN_11;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
@ -107,12 +116,12 @@ void MX_GPIO_Init(void)
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = HART_PWR_Pin|IP_PWR_Pin;
GPIO_InitStruct.Pin = HART_PWR_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LL_GPIO_Init(HART_PWR_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = IP_H_PWR_Pin|LCD_PWR_Pin;
@ -133,7 +142,7 @@ void MX_GPIO_Init(void)
/**/
GPIO_InitStruct.Pin = KEY_AUTO_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(KEY_AUTO_GPIO_Port, &GPIO_InitStruct);
/**/
@ -145,14 +154,13 @@ void MX_GPIO_Init(void)
LL_GPIO_Init(LCD_CS_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_14;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LCD_EXTCOMIN_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(LCD_EXTCOMIN_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LCD_DISP_Pin|LED1_Pin|LED2_Pin|LED3_Pin
|LED4_Pin|LED5_Pin|EE2_CS_Pin|BLE_PWR_Pin;
GPIO_InitStruct.Pin = LCD_DISP_Pin|EE3_CS_Pin|EE2_CS_Pin|BLE_PWR_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
@ -160,15 +168,24 @@ void MX_GPIO_Init(void)
LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = KEY6_Pin|KEY5_Pin|HART_CD_Pin;
GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin
|LED5_Pin|EE1_CS_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = KEY6_Pin|KEY5_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = KEY4_Pin|KEY3_Pin|KEY2_Pin|KEY1_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/**/
@ -194,26 +211,39 @@ void MX_GPIO_Init(void)
LL_GPIO_Init(HART_RST_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_1|LL_GPIO_PIN_3|LL_GPIO_PIN_4;
GPIO_InitStruct.Pin = LL_GPIO_PIN_1|LL_GPIO_PIN_3;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = EE1_CS_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(EE1_CS_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = I2C2_SCL_Pin|I2C2_SDA_Pin;
GPIO_InitStruct.Pin = I2C1_SCL_Pin|I2C1_SDA_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/**/
LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTD, LL_SYSCFG_EXTI_LINE0);
/**/
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_0;
EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
EXTI_InitStruct.LineCommand = ENABLE;
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
LL_EXTI_Init(&EXTI_InitStruct);
/**/
LL_GPIO_SetPinPull(HART_CD_GPIO_Port, HART_CD_Pin, LL_GPIO_PULL_UP);
/**/
LL_GPIO_SetPinMode(HART_CD_GPIO_Port, HART_CD_Pin, LL_GPIO_MODE_INPUT);
/* EXTI interrupt init*/
NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(EXTI0_IRQn);
}

View File

@ -1,124 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file i2c.c
* @brief This file provides code for the configuration
* of the I2C instances.
******************************************************************************
* @attention
*
* Copyright (c) 2024 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 "i2c.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* I2C1 init function */
void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
LL_I2C_InitTypeDef I2C_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
/**I2C1 GPIO Configuration
PB8 ------> I2C1_SCL
PB9 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = I2C1_SCL_Pin|I2C1_SDA_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
/* I2C1 DMA Init */
/* I2C1_RX Init */
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_7, LL_DMA_REQUEST_3);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_7, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MODE_NORMAL);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MDATAALIGN_BYTE);
/* I2C1_TX Init */
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_6, LL_DMA_REQUEST_3);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_6, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MODE_NORMAL);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MDATAALIGN_BYTE);
/* I2C1 interrupt Init */
NVIC_SetPriority(I2C1_EV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(I2C1_EV_IRQn);
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
/** I2C Initialization
*/
LL_I2C_EnableAutoEndMode(I2C1);
LL_I2C_DisableOwnAddress2(I2C1);
LL_I2C_DisableGeneralCall(I2C1);
LL_I2C_EnableClockStretching(I2C1);
I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct.Timing = 0x00000E14;
I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
I2C_InitStruct.DigitalFilter = 0;
I2C_InitStruct.OwnAddress1 = 0;
I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
LL_I2C_Init(I2C1, &I2C_InitStruct);
LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@ -21,7 +21,6 @@
#include "adc.h"
#include "dac.h"
#include "dma.h"
#include "i2c.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
@ -121,8 +120,8 @@ int main(void)
MX_USART1_UART_Init();
MX_TIM6_Init();
MX_TIM7_Init();
MX_I2C1_Init();
MX_ADC2_Init();
MX_TIM17_Init();
MX_TIM16_Init();
/* USER CODE BEGIN 2 */
leds_dinit(); // LED Deinitialization
@ -167,7 +166,7 @@ void SystemClock_Config(void)
{
}
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 8, LL_RCC_PLLR_DIV_2);
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 12, LL_RCC_PLLR_DIV_6);
LL_RCC_PLL_EnableDomain_SYS();
LL_RCC_PLL_Enable();
@ -183,13 +182,13 @@ void SystemClock_Config(void)
{
}
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_8);
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
LL_Init1msTick(4000000);
LL_Init1msTick(5529600);
LL_SetSystemCoreClock(4000000);
LL_SetSystemCoreClock(5529600);
}
/**
@ -198,7 +197,7 @@ void SystemClock_Config(void)
*/
void PeriphCommonClock_Config(void)
{
LL_RCC_PLLSAI1_ConfigDomain_ADC(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 8, LL_RCC_PLLSAI1R_DIV_2);
LL_RCC_PLLSAI1_ConfigDomain_ADC(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 12, LL_RCC_PLLSAI1R_DIV_8);
LL_RCC_PLLSAI1_EnableDomain_ADC();
LL_RCC_PLLSAI1_Enable();

View File

@ -130,7 +130,7 @@ void MX_SPI2_Init(void)
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4;
SPI_InitStruct.BitOrder = LL_SPI_LSB_FIRST;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_InitStruct.CRCPoly = 7;

View File

@ -27,7 +27,7 @@
#include "bsp.h"
#include "sys.h"
#include "app.h"
#include "diagnosis.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -58,7 +58,6 @@
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
extern uart_t *uarts[APP_UART_MAX];
extern i2c_t *eeprom_fm24_i2c;
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
@ -71,8 +70,8 @@ extern i2c_t *eeprom_fm24_i2c;
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
@ -86,24 +85,25 @@ void NMI_Handler(void)
}
/**
* @brief This function handles Hard fault interrupt.
*/
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
leds_off_all();
leds_on(LEDS_1_RED);
leds_on(LEDS_RED);
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
DBG_ASSERT(FALSE __DBG_LINE);
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
@ -117,8 +117,8 @@ void MemManage_Handler(void)
}
/**
* @brief This function handles Prefetch fault, memory access fault.
*/
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
@ -132,8 +132,8 @@ void BusFault_Handler(void)
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
@ -147,8 +147,8 @@ void UsageFault_Handler(void)
}
/**
* @brief This function handles System service call via SWI instruction.
*/
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
@ -160,8 +160,8 @@ void SVC_Handler(void)
}
/**
* @brief This function handles Debug monitor.
*/
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
@ -173,8 +173,8 @@ void DebugMon_Handler(void)
}
/**
* @brief This function handles Pendable request for system service.
*/
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
@ -186,8 +186,8 @@ void PendSV_Handler(void)
}
/**
* @brief This function handles System tick timer.
*/
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
@ -207,8 +207,29 @@ void SysTick_Handler(void)
/******************************************************************************/
/**
* @brief This function handles DMA1 channel1 global interrupt.
*/
* @brief This function handles EXTI line0 interrupt.
*/
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
/* USER CODE END EXTI0_IRQn 0 */
if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_0) != RESET)
{
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0);
/* USER CODE BEGIN LL_EXTI_LINE_0 */
uart_rx_cd_callback(uarts[APP_UART_1]); // HART CD
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0);
/* USER CODE END LL_EXTI_LINE_0 */
}
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel1 global interrupt.
*/
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
@ -217,27 +238,12 @@ void DMA1_Channel1_IRQHandler(void)
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
adc_dma_callback(ADCS_1);
adc_dma_callback(ADCS_2);
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel2 global interrupt.
*/
void DMA1_Channel2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
/* USER CODE END DMA1_Channel2_IRQn 0 */
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
/* USER CODE END DMA1_Channel2_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel5 global interrupt.
*/
* @brief This function handles DMA1 channel5 global interrupt.
*/
void DMA1_Channel5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
@ -245,41 +251,13 @@ void DMA1_Channel5_IRQHandler(void)
/* USER CODE END DMA1_Channel5_IRQn 0 */
/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
lcd->info.spi->interface.spi_dma_callback(lcd->info.spi);
/* USER CODE END DMA1_Channel5_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel6 global interrupt.
*/
void DMA1_Channel6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel6_IRQn 0 */
/* USER CODE END DMA1_Channel6_IRQn 0 */
/* USER CODE BEGIN DMA1_Channel6_IRQn 1 */
i2c_dma_callback(eeprom_fm24_i2c);
/* USER CODE END DMA1_Channel6_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel7 global interrupt.
*/
void DMA1_Channel7_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel7_IRQn 0 */
/* USER CODE END DMA1_Channel7_IRQn 0 */
/* USER CODE BEGIN DMA1_Channel7_IRQn 1 */
i2c_dma_callback(eeprom_fm24_i2c);
/* USER CODE END DMA1_Channel7_IRQn 1 */
}
/**
* @brief This function handles ADC1 and ADC2 interrupts.
*/
* @brief This function handles ADC1 and ADC2 interrupts.
*/
void ADC1_2_IRQHandler(void)
{
/* USER CODE BEGIN ADC1_2_IRQn 0 */
@ -288,27 +266,53 @@ void ADC1_2_IRQHandler(void)
/* USER CODE BEGIN ADC1_2_IRQn 1 */
adc_env_callback(ADCS_1);
adc_env_callback(ADCS_2);
/* USER CODE END ADC1_2_IRQn 1 */
}
/**
* @brief This function handles I2C1 event interrupt.
*/
void I2C1_EV_IRQHandler(void)
* @brief This function handles TIM1 update interrupt and TIM16 global interrupt.
*/
void TIM1_UP_TIM16_IRQHandler(void)
{
/* USER CODE BEGIN I2C1_EV_IRQn 0 */
/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */
/* USER CODE END I2C1_EV_IRQn 0 */
/* USER CODE END TIM1_UP_TIM16_IRQn 0 */
/* USER CODE BEGIN I2C1_EV_IRQn 1 */
i2c_ev_callback(eeprom_fm24_i2c);
/* USER CODE END I2C1_EV_IRQn 1 */
/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */
if (IS_TIM_IT_FLAG(HART_TIM))
{
TIM_IRQ_HANDLER(HART_TIM);
hart_timer_interupt_cb();
}
/* USER CODE END TIM1_UP_TIM16_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
* @brief This function handles TIM1 trigger and commutation interrupts and TIM17 global interrupt.
*/
void TIM1_TRG_COM_TIM17_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 0 */
/* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */
/* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 1 */
if (IS_TIM_IT_FLAG(MODE_GATHE_TIM))
{
TIM_IRQ_HANDLER(MODE_GATHE_TIM);
mode_ctrl_gather();
mode_ctrl_output();
if (rt_data.flag.bits.app_init_over == TRUE)
{
scheduler_time_1s_irqhandler(100);
}
}
/* USER CODE END TIM1_TRG_COM_TIM17_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
@ -316,12 +320,20 @@ void USART1_IRQHandler(void)
/* USER CODE END USART1_IRQn 0 */
/* USER CODE BEGIN USART1_IRQn 1 */
uart_reception_callback(uarts[APP_UART_1]);
if (uarts[APP_UART_1]->rx_index > 1)
{
if (hart_timeout_compare() == FALSE)
{
uart_data_storage_reset(uarts[APP_UART_1]);
}
}
hart_timer_start(HART_BYTE_INTERVAL_TIME);
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles UART5 global interrupt.
*/
* @brief This function handles UART5 global interrupt.
*/
void UART5_IRQHandler(void)
{
/* USER CODE BEGIN UART5_IRQn 0 */
@ -333,8 +345,8 @@ void UART5_IRQHandler(void)
}
/**
* @brief This function handles TIM6 global interrupt, DAC channel1 and channel2 underrun error interrupts.
*/
* @brief This function handles TIM6 global interrupt, DAC channel1 and channel2 underrun error interrupts.
*/
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
@ -342,36 +354,45 @@ void TIM6_DAC_IRQHandler(void)
/* USER CODE END TIM6_DAC_IRQn 0 */
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
if (IS_TIM_IT_FLAG(TIM6))
if (IS_TIM_IT_FLAG(TASK_TIM))
{
TIM_IRQ_HANDLER(TIM6);
FLOW_TICK_UPDATE();
TIM_IRQ_HANDLER(TASK_TIM);
LL_IncTick();
if (rt_data.flag.bits.app_init_over == TRUE)
{
FLOW_TICK_UPDATE();
#if HART_SOFTWARE_TEST_ENABLE == FALSE
button_ticks();
#endif
}
}
/* USER CODE END TIM6_DAC_IRQn 1 */
}
/**
* @brief This function handles TIM7 global interrupt.
*/
* @brief This function handles TIM7 global interrupt.
*/
void TIM7_IRQHandler(void)
{
/* USER CODE BEGIN TIM7_IRQn 0 */
/* USER CODE END TIM7_IRQn 0 */
/* USER CODE BEGIN TIM7_IRQn 1 */
if (IS_TIM_IT_FLAG(TIM7))
if (IS_TIM_IT_FLAG(MODE_TIM))
{
TIM_IRQ_HANDLER(TIM7);
mode_process();
TIM_IRQ_HANDLER(MODE_TIM);
if (rt_data.flag.bits.app_init_over == TRUE)
{
mode_ctrl_process();
}
}
/* USER CODE END TIM7_IRQn 1 */
}
/**
* @brief This function handles DMA2 channel1 global interrupt.
*/
* @brief This function handles DMA2 channel1 global interrupt.
*/
void DMA2_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Channel1_IRQn 0 */
@ -384,8 +405,8 @@ void DMA2_Channel1_IRQHandler(void)
}
/**
* @brief This function handles DMA2 channel2 global interrupt.
*/
* @brief This function handles DMA2 channel2 global interrupt.
*/
void DMA2_Channel2_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Channel2_IRQn 0 */
@ -398,8 +419,8 @@ void DMA2_Channel2_IRQHandler(void)
}
/**
* @brief This function handles DMA2 channel6 global interrupt.
*/
* @brief This function handles DMA2 channel6 global interrupt.
*/
void DMA2_Channel6_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Channel6_IRQn 0 */
@ -412,8 +433,8 @@ void DMA2_Channel6_IRQHandler(void)
}
/**
* @brief This function handles DMA2 channel7 global interrupt.
*/
* @brief This function handles DMA2 channel7 global interrupt.
*/
void DMA2_Channel7_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Channel7_IRQn 0 */

View File

@ -44,7 +44,7 @@ void MX_TIM2_Init(void)
/* USER CODE END TIM2_Init 1 */
TIM_InitStruct.Prescaler = 0;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 3999;
TIM_InitStruct.Autoreload = 5529;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM2, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM2);
@ -56,7 +56,7 @@ void MX_TIM2_Init(void)
TIM_OC_InitStruct.CompareValue = 0;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct);
LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH4);
LL_TIM_OC_EnableFast(TIM2, LL_TIM_CHANNEL_CH4);
LL_TIM_SetOCRefClearInputSource(TIM2, LL_TIM_OCREF_CLR_INT_NC);
LL_TIM_DisableExternalClock(TIM2);
LL_TIM_ConfigETR(TIM2, LL_TIM_ETR_POLARITY_NONINVERTED, LL_TIM_ETR_PRESCALER_DIV1, LL_TIM_ETR_FILTER_FDIV1);
@ -98,19 +98,19 @@ void MX_TIM3_Init(void)
/* USER CODE END TIM3_Init 1 */
TIM_InitStruct.Prescaler = 0;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 3999;
TIM_InitStruct.Autoreload = 11;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM3, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM3);
LL_TIM_SetClockSource(TIM3, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH3);
LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH2);
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.CompareValue = 0;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH3, &TIM_OC_InitStruct);
LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH3);
LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);
LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH2);
LL_TIM_SetOCRefClearInputSource(TIM3, LL_TIM_OCREF_CLR_INT_NC);
LL_TIM_DisableExternalClock(TIM3);
LL_TIM_ConfigETR(TIM3, LL_TIM_ETR_POLARITY_NONINVERTED, LL_TIM_ETR_PRESCALER_DIV1, LL_TIM_ETR_FILTER_FDIV1);
@ -121,15 +121,15 @@ void MX_TIM3_Init(void)
/* USER CODE END TIM3_Init 2 */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE);
/**TIM3 GPIO Configuration
PE5 ------> TIM3_CH3
PE4 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = PWM_OUT_Pin;
GPIO_InitStruct.Pin = LL_GPIO_PIN_4;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_2;
LL_GPIO_Init(PWM_OUT_GPIO_Port, &GPIO_InitStruct);
LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
/* TIM6 init function */
@ -152,7 +152,7 @@ void MX_TIM6_Init(void)
/* USER CODE BEGIN TIM6_Init 1 */
/* USER CODE END TIM6_Init 1 */
TIM_InitStruct.Prescaler = 399;
TIM_InitStruct.Prescaler = 552;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 99;
LL_TIM_Init(TIM6, &TIM_InitStruct);
@ -184,9 +184,9 @@ void MX_TIM7_Init(void)
/* USER CODE BEGIN TIM7_Init 1 */
/* USER CODE END TIM7_Init 1 */
TIM_InitStruct.Prescaler = 399;
TIM_InitStruct.Prescaler = 552;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 499;
TIM_InitStruct.Autoreload = 249;
LL_TIM_Init(TIM7, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM7);
LL_TIM_SetTriggerOutput(TIM7, LL_TIM_TRGO_RESET);
@ -195,6 +195,70 @@ void MX_TIM7_Init(void)
/* USER CODE END TIM7_Init 2 */
}
/* TIM16 init function */
void MX_TIM16_Init(void)
{
/* USER CODE BEGIN TIM16_Init 0 */
/* USER CODE END TIM16_Init 0 */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
/* Peripheral clock enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM16);
/* TIM16 interrupt Init */
NVIC_SetPriority(TIM1_UP_TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
/* USER CODE BEGIN TIM16_Init 1 */
/* USER CODE END TIM16_Init 1 */
TIM_InitStruct.Prescaler = 552;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 24;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
TIM_InitStruct.RepetitionCounter = 0;
LL_TIM_Init(TIM16, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM16);
/* USER CODE BEGIN TIM16_Init 2 */
/* USER CODE END TIM16_Init 2 */
}
/* TIM17 init function */
void MX_TIM17_Init(void)
{
/* USER CODE BEGIN TIM17_Init 0 */
/* USER CODE END TIM17_Init 0 */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
/* Peripheral clock enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM17);
/* TIM17 interrupt Init */
NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn);
/* USER CODE BEGIN TIM17_Init 1 */
/* USER CODE END TIM17_Init 1 */
TIM_InitStruct.Prescaler = 552;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 999;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
TIM_InitStruct.RepetitionCounter = 0;
LL_TIM_Init(TIM17, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM17);
/* USER CODE BEGIN TIM17_Init 2 */
/* USER CODE END TIM17_Init 2 */
}
/* USER CODE BEGIN 1 */

View File

@ -100,13 +100,13 @@ void MX_UART5_Init(void)
LL_DMA_SetMemorySize(DMA2, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_BYTE);
/* UART5 interrupt Init */
NVIC_SetPriority(UART5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_SetPriority(UART5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),3, 0));
NVIC_EnableIRQ(UART5_IRQn);
/* USER CODE BEGIN UART5_Init 1 */
/* USER CODE END UART5_Init 1 */
UART_InitStruct.BaudRate = 9600;
UART_InitStruct.BaudRate = 115200;
UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
UART_InitStruct.StopBits = LL_USART_STOPBITS_1;
UART_InitStruct.Parity = LL_USART_PARITY_NONE;

File diff suppressed because it is too large Load Diff

View File

@ -1,244 +0,0 @@
/**
******************************************************************************
* @file stm32l4xx_ll_i2c.c
* @author MCD Application Team
* @brief I2C LL module driver.
******************************************************************************
* @attention
*
* Copyright (c) 2017 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.
*
******************************************************************************
*/
#if defined(USE_FULL_LL_DRIVER)
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_ll_i2c.h"
#include "stm32l4xx_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "stm32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
/** @addtogroup STM32L4xx_LL_Driver
* @{
*/
#if defined (I2C1) || defined (I2C2) || defined (I2C3) || defined (I2C4)
/** @defgroup I2C_LL I2C
* @{
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/** @addtogroup I2C_LL_Private_Macros
* @{
*/
#define IS_LL_I2C_PERIPHERAL_MODE(__VALUE__) (((__VALUE__) == LL_I2C_MODE_I2C) || \
((__VALUE__) == LL_I2C_MODE_SMBUS_HOST) || \
((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE) || \
((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE_ARP))
#define IS_LL_I2C_ANALOG_FILTER(__VALUE__) (((__VALUE__) == LL_I2C_ANALOGFILTER_ENABLE) || \
((__VALUE__) == LL_I2C_ANALOGFILTER_DISABLE))
#define IS_LL_I2C_DIGITAL_FILTER(__VALUE__) ((__VALUE__) <= 0x0000000FU)
#define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= 0x000003FFU)
#define IS_LL_I2C_TYPE_ACKNOWLEDGE(__VALUE__) (((__VALUE__) == LL_I2C_ACK) || \
((__VALUE__) == LL_I2C_NACK))
#define IS_LL_I2C_OWN_ADDRSIZE(__VALUE__) (((__VALUE__) == LL_I2C_OWNADDRESS1_7BIT) || \
((__VALUE__) == LL_I2C_OWNADDRESS1_10BIT))
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup I2C_LL_Exported_Functions
* @{
*/
/** @addtogroup I2C_LL_EF_Init
* @{
*/
/**
* @brief De-initialize the I2C registers to their default reset values.
* @param I2Cx I2C Instance.
* @retval An ErrorStatus enumeration value:
* - SUCCESS: I2C registers are de-initialized
* - ERROR: I2C registers are not de-initialized
*/
ErrorStatus LL_I2C_DeInit(const I2C_TypeDef *I2Cx)
{
ErrorStatus status = SUCCESS;
/* Check the I2C Instance I2Cx */
assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
if (I2Cx == I2C1)
{
/* Force reset of I2C clock */
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
/* Release reset of I2C clock */
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
}
#if defined(I2C2)
else if (I2Cx == I2C2)
{
/* Force reset of I2C clock */
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C2);
/* Release reset of I2C clock */
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C2);
}
#endif /* I2C2 */
else if (I2Cx == I2C3)
{
/* Force reset of I2C clock */
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3);
/* Release reset of I2C clock */
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3);
}
#if defined(I2C4)
else if (I2Cx == I2C4)
{
/* Force reset of I2C clock */
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_I2C4);
/* Release reset of I2C clock */
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_I2C4);
}
#endif /* I2C4 */
else
{
status = ERROR;
}
return status;
}
/**
* @brief Initialize the I2C registers according to the specified parameters in I2C_InitStruct.
* @param I2Cx I2C Instance.
* @param I2C_InitStruct pointer to a @ref LL_I2C_InitTypeDef structure.
* @retval An ErrorStatus enumeration value:
* - SUCCESS: I2C registers are initialized
* - ERROR: Not applicable
*/
ErrorStatus LL_I2C_Init(I2C_TypeDef *I2Cx, const LL_I2C_InitTypeDef *I2C_InitStruct)
{
/* Check the I2C Instance I2Cx */
assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
/* Check the I2C parameters from I2C_InitStruct */
assert_param(IS_LL_I2C_PERIPHERAL_MODE(I2C_InitStruct->PeripheralMode));
assert_param(IS_LL_I2C_ANALOG_FILTER(I2C_InitStruct->AnalogFilter));
assert_param(IS_LL_I2C_DIGITAL_FILTER(I2C_InitStruct->DigitalFilter));
assert_param(IS_LL_I2C_OWN_ADDRESS1(I2C_InitStruct->OwnAddress1));
assert_param(IS_LL_I2C_TYPE_ACKNOWLEDGE(I2C_InitStruct->TypeAcknowledge));
assert_param(IS_LL_I2C_OWN_ADDRSIZE(I2C_InitStruct->OwnAddrSize));
/* Disable the selected I2Cx Peripheral */
LL_I2C_Disable(I2Cx);
/*---------------------------- I2Cx CR1 Configuration ------------------------
* Configure the analog and digital noise filters with parameters :
* - AnalogFilter: I2C_CR1_ANFOFF bit
* - DigitalFilter: I2C_CR1_DNF[3:0] bits
*/
LL_I2C_ConfigFilters(I2Cx, I2C_InitStruct->AnalogFilter, I2C_InitStruct->DigitalFilter);
/*---------------------------- I2Cx TIMINGR Configuration --------------------
* Configure the SDA setup, hold time and the SCL high, low period with parameter :
* - Timing: I2C_TIMINGR_PRESC[3:0], I2C_TIMINGR_SCLDEL[3:0], I2C_TIMINGR_SDADEL[3:0],
* I2C_TIMINGR_SCLH[7:0] and I2C_TIMINGR_SCLL[7:0] bits
*/
LL_I2C_SetTiming(I2Cx, I2C_InitStruct->Timing);
/* Enable the selected I2Cx Peripheral */
LL_I2C_Enable(I2Cx);
/*---------------------------- I2Cx OAR1 Configuration -----------------------
* Disable, Configure and Enable I2Cx device own address 1 with parameters :
* - OwnAddress1: I2C_OAR1_OA1[9:0] bits
* - OwnAddrSize: I2C_OAR1_OA1MODE bit
*/
LL_I2C_DisableOwnAddress1(I2Cx);
LL_I2C_SetOwnAddress1(I2Cx, I2C_InitStruct->OwnAddress1, I2C_InitStruct->OwnAddrSize);
/* OwnAdress1 == 0 is reserved for General Call address */
if (I2C_InitStruct->OwnAddress1 != 0U)
{
LL_I2C_EnableOwnAddress1(I2Cx);
}
/*---------------------------- I2Cx MODE Configuration -----------------------
* Configure I2Cx peripheral mode with parameter :
* - PeripheralMode: I2C_CR1_SMBDEN and I2C_CR1_SMBHEN bits
*/
LL_I2C_SetMode(I2Cx, I2C_InitStruct->PeripheralMode);
/*---------------------------- I2Cx CR2 Configuration ------------------------
* Configure the ACKnowledge or Non ACKnowledge condition
* after the address receive match code or next received byte with parameter :
* - TypeAcknowledge: I2C_CR2_NACK bit
*/
LL_I2C_AcknowledgeNextData(I2Cx, I2C_InitStruct->TypeAcknowledge);
return SUCCESS;
}
/**
* @brief Set each @ref LL_I2C_InitTypeDef field to default value.
* @param I2C_InitStruct Pointer to a @ref LL_I2C_InitTypeDef structure.
* @retval None
*/
void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct)
{
/* Set I2C_InitStruct fields to default values */
I2C_InitStruct->PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct->Timing = 0U;
I2C_InitStruct->AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
I2C_InitStruct->DigitalFilter = 0U;
I2C_InitStruct->OwnAddress1 = 0U;
I2C_InitStruct->TypeAcknowledge = LL_I2C_NACK;
I2C_InitStruct->OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* I2C1 || I2C2 || I2C3 || I2C4 */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */

View File

@ -0,0 +1,21 @@
/*
* Auto generated Run-Time-Environment Configuration File
* *** Do not modify ! ***
*
* Project: 'controller'
* Target: 'controller-stlink'
*/
#ifndef RTE_COMPONENTS_H
#define RTE_COMPONENTS_H
/*
* Define the Device Header File:
*/
#define CMSIS_device_header "stm32l4xx.h"
#endif /* RTE_COMPONENTS_H */

View File

@ -0,0 +1,21 @@
/*
* Auto generated Run-Time-Environment Configuration File
* *** Do not modify ! ***
*
* Project: 'controller'
* Target: 'controller'
*/
#ifndef RTE_COMPONENTS_H
#define RTE_COMPONENTS_H
/*
* Define the Device Header File:
*/
#define CMSIS_device_header "stm32l4xx.h"
#endif /* RTE_COMPONENTS_H */

8
MDK-ARM/RTE_Components.h Normal file
View File

@ -0,0 +1,8 @@
/*-----------------------------------------------------------------------------------*/
/* Auto generate by EIDE, don't modify this file, any changes will be overwritten ! */
/*-----------------------------------------------------------------------------------*/
#ifndef RTE_COMPONENTS_H
#define RTE_COMPONENTS_H
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2716
MDK-ARM/controller.uvprojx Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x1000
Stack_Size EQU 0x1200
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
@ -39,7 +39,7 @@ __initial_sp
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x800
Heap_Size EQU 0x200
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base

25
MDK-ARM/stm32l476xx.sct Normal file
View File

@ -0,0 +1,25 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x0006E000 { ; load region size_region
ER_IROM1 0x08000000 0x0006E000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_RAM1 0x10007FF0 UNINIT 0x00000010 { ; RW data
.ANY (+RW +ZI)
}
RW_RAM2 0x10007000 UNINIT 0x00000FF0 { ; No init data
.ANY(NOINIT)
}
RW_IRAM1 0x20000000 0x00018000 {
.ANY (+RW +ZI)
}
RW_IRAM2 0x10000000 0x00007000 {
.ANY (+RW +ZI)
}
}

View File

@ -16,7 +16,7 @@ SRC = \
EXAMPLE = \
./test_hart.c
CPLUS_INCLUDE_PATH= -I ../User/lib/inc
CPLUS_INCLUDE_PATH= -I ../User/lib/inc -I ../User/lib/uthash
# 变量CC给定编译器名gcc
# 变量CFLAGS传给编译器的某些编译参数看需求添加

62
Tests/convert.c Normal file
View File

@ -0,0 +1,62 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define EQUAL_ALPHA 50.0f // 等百分比范围比
#define LOG_ALPHA log(EQUAL_ALPHA)
static inline float32 logarithmic_conversion(float32 setpoint)
{
static const float32 b = 13.24f;
static const float32 linear_coefficient = 0.123f;
static const float32 base_log = 0.6931471805599453f; // 直接使用log(2)的预计算值
float32 res = 0.0f;
if (setpoint <= 0)
{
return 0;
}
else if (setpoint >= 100)
{
return 100;
}
else
{
res = b * log(setpoint) / base_log + linear_coefficient * setpoint;
if (res < 0)
{
res = 0.0f;
}
else if (res > 100)
{
res = 100.0f;
}
return res;
}
}
void quick_open(void)
{
printf("quick_open:\n");
for (uint8_t i = 0; i < 20; i++)
{
printf("x = %d, y = %f\n", 5 + i * 5, logarithmic_conversion(5 + i * 5));
}
printf("\n");
}
void equal_proportion(void)
{
uint8_t x = 0; // 指定的x值
printf("equal_proportion:\n");
for (uint8_t i = 0; i <= 20; i++)
{
x = i * 5;
printf("x = %d, y = %f\n", x, (exp(x * 0.01f * LOG_ALPHA) - 1) * 100 / (EQUAL_ALPHA - 1));
}
printf("\n");
}
int main()
{
equal_proportion();
quick_open();
}

51
Tests/epm.py Normal file
View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# 设置中文字体
font = FontProperties(fname='C:/Windows/Fonts/simsun.ttc') # 你可以根据需要更改字体路径
# 定义温度和对应的平衡值数据
USE_EPM = False # 是否使用EPM数据True为EPM数据False为SMASON数据
if USE_EPM:
#-----------------改EPM-----------------
temperatures = [-16,-6,0,7,15,17,21,25,28,35,45,51]
balance_values_0 = [1188,1222,1223,1233,1225,1255,1247,1268,1253,1230,1206,1175]
balance_values_50 = [1450,1465,1464,1469,1473,1480,1470,1470,1472,1460,1418,1365]
balance_values_100 = [1720,1781,1745,1776,1721,1742,1768,1774,1723,1724,1606,1529]
else:
#-----------------SMASON-----------------
temperatures = [16,20,25,29,35,39,45,50,55,60,65,70,77,80,85]
balance_values_0 = [1732,1673,1700,1734,1701,1728,1721,1706,1705,1733,1693,1676,1720,1712,1670]
balance_values_50 = [1948,1958,1953,1985,1955,1949,1966,1935,1974,1966,1954,1961,1955,1967,1909]
balance_values_100 = [2237,2214,2281,2266,2279,2268,2276,2268,2263,2285,2266,2276,2232,2245,2241]
# 创建一个图形对象
plt.figure()
# 绘制数据
plt.plot(temperatures, balance_values_0, marker='o', label='0% 平衡值',color='green')
plt.plot(temperatures, balance_values_100, marker='o', label='100% 平衡值',color='blue')
plt.plot(temperatures, balance_values_50, marker='o', label='50% 平衡值',color='red')
# 在坐标点上绘制温度值
for i in range(len(temperatures)):
plt.text(temperatures[i], balance_values_0[i], f'{temperatures[i]}°C', fontproperties=font)
plt.text(temperatures[i], balance_values_100[i], f'{temperatures[i]}°C', fontproperties=font)
plt.text(temperatures[i], balance_values_50[i], f'{temperatures[i]}°C', fontproperties=font)
# 添加标题和标签
if USE_EPM:
plt.title('[自研EPM]温度变化对0%、100% 平衡值驱动的影响', fontproperties=font)
else:
plt.title('[SAMSON的EPM]温度变化对0%、100% 平衡值驱动的影响', fontproperties=font)
plt.xlabel('温度 (°C)', fontproperties=font)
plt.ylabel('平衡值', fontproperties=font)
plt.legend(prop=font)
# 显示图形
plt.show()

View File

@ -1,19 +1,169 @@
#include "test.h"
#include "test_bsp.h"
// #include "test.h"
// #include "test_bsp.h"
void test(uint8_t flag)
{
switch (flag)
{
case TEST_DISABLE:
return;
case TEST_BSP:
bsp_test();
break;
case TEST_POWER:
power_test();
break;
default:
break;
}
}
// #include <stdlib.h>
// #include <string.h>
// #include "uthash.h" // 确保包含 uthash 头文件
// struct my_struct
// {
// int id; // 键
// char name[50]; // 假设名字长度不超过 50
// UT_hash_handle hh; // uthash 句柄
// };
// struct my_struct *users = NULL; // 初始化哈希表
// // 定义空的 exit 函数
// void exit(int status)
// {
// // 在嵌入式系统中,通常不需要执行任何操作
// // 你可以在这里添加任何需要的清理代码
// while (1)
// {
// // 无限循环,确保函数不会返回
// }
// }
// void add_user(int user_id, const char *name)
// {
// struct my_struct *s;
// HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */
// if (s == NULL)
// {
// s = (struct my_struct *)malloc(sizeof *s);
// if (s == NULL)
// {
// // 处理内存分配失败
// return;
// }
// s->id = user_id;
// HASH_ADD_INT(users, id, s); /* id is the key field */
// }
// strncpy(s->name, name, sizeof(s->name) - 1);
// s->name[sizeof(s->name) - 1] = '\0'; // 确保字符串以 null 结尾
// }
// struct my_struct *find_user(int user_id)
// {
// struct my_struct *s;
// HASH_FIND_INT(users, &user_id, s); /* s: output pointer */
// return s;
// }
// void delete_user(struct my_struct *user)
// {
// HASH_DEL(users, user); /* user: pointer to deletee */
// free(user);
// }
// static void test_uthash(void)
// {
// add_user(1, "Alice");
// add_user(2, "Bob");
// struct my_struct *user = find_user(1);
// if (user)
// {
// LOG_PRINT("Found user: %s\n", user->name);
// }
// user = find_user(2);
// if (user)
// {
// LOG_PRINT("Found user: %s\n", user->name);
// }
// delete_user(find_user(1));
// delete_user(find_user(2));
// }
// static void test_fpu_float(void)
// {
// ENABLE_TIM(TASK_TIM);
// static uint32_t use_time1 = 0, use_time2 = 0;
// uint16_t count = 30000;
// float32 x1 = 1.0f;
// float32 y1 = 2.1314f;
// float32 x2 = 1.0;
// float32 y2 = 2.1314;
// use_time1 = sys_millis();
// for (uint16_t i = 0; i < count; i++)
// {
// x1 *= y1;
// }
// use_time1 = sys_millis() - use_time1;
// use_time2 = sys_millis();
// for (uint16_t i = 0; i < count; i++)
// {
// x2 *= y2;
// }
// use_time2 = sys_millis() - use_time2;
// __NOP();
// }
// static void test_wl_flash(void)
// {
// uint32_t address = 0;
// wl_flash_t wf = {
// .wl_flag = TRUE,
// .addr = PVD_RESET_STORAGE_START_ADDRESS,
// .len = 2 * LL_FLASH_PAGE_SIZE,
// .page_size = LL_FLASH_PAGE_SIZE,
// .data_size = sizeof(device_reset_t),
// .write_gran = 8,
// .ops.srand = board_srand,
// .ops.read = flash_read,
// .ops.write = flash_write,
// .ops.erase_page = flash_erase_page,
// };
// wl_flash_init(&wf);
// wl_flash_erase(&wf);
// address = wl_flash_get_current_address(&wf);
// device_reset_t power_on;
// power_on.flag = PVD_RESET_FLAG;
// // 一页2048/16 = 128个数据,2页 = 256个数据i=255时数据从头开始
// for (uint16_t i = 0; i < 1000; i++)
// {
// wl_flash_write(&wf, (uint8_t *)&power_on, sizeof(device_reset_t));
// wl_flash_set_next_address(&wf);
// address = wl_flash_get_current_address(&wf);
// if (address == wf.addr)
// {
// __NOP();
// }
// }
// }
// void test(uint8_t flag)
// {
// switch (flag)
// {
// case TEST_DISABLE:
// return;
// case TEST_BSP:
// bsp_test();
// break;
// case TEST_POWER:
// power_test();
// break;
// case TEST_FPU_FLOAT:
// test_fpu_float();
// break;
// case TEST_WL_FLASH:
// test_wl_flash();
// break;
// case TEST_UTHASH:
// test_uthash();
// break;
// default:
// break;
// }
// }

View File

@ -10,7 +10,10 @@ typedef enum
TEST_DISABLE,
TEST_BSP,
TEST_POWER,
}test_e;
TEST_FPU_FLOAT,
TEST_WL_FLASH,
TEST_UTHASH,
} test_e;
extern void test(uint8_t flag);
#endif // __TEST_H__

View File

@ -1,3 +1,51 @@
hex_value = "0x65EADA6E"
dec_value = int(hex_value, 16)
print(dec_value)
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# 设置中文字体
font = FontProperties(fname='C:/Windows/Fonts/simsun.ttc') # 你可以根据需要更改字体路径
# 定义温度和对应的平衡值数据
USE_EPM = False # 是否使用EPM数据True为EPM数据False为SMASON数据
if USE_EPM:
#-----------------改EPM-----------------
temperatures = [-16,-6,0,7,15,17,21,25,28,35,45,51]
balance_values_0 = [1188,1222,1223,1233,1225,1255,1247,1268,1253,1230,1206,1175]
balance_values_50 = [1450,1465,1464,1469,1473,1480,1470,1470,1472,1460,1418,1365]
balance_values_100 = [1720,1781,1745,1776,1721,1742,1768,1774,1723,1724,1606,1529]
else:
#-----------------SMASON-----------------
temperatures = [16,20,25,29,35,39,45,50,55,60,65,70,77,80,85]
balance_values_0 = [1732,1673,1700,1734,1701,1728,1721,1706,1705,1733,1693,1676,1720,1712,1670]
balance_values_50 = [1948,1958,1953,1985,1955,1949,1966,1935,1974,1966,1954,1961,1955,1967,1909]
balance_values_100 = [2237,2214,2281,2266,2279,2268,2276,2268,2263,2285,2266,2276,2232,2245,2241]
# 创建一个图形对象
plt.figure()
# 绘制数据
plt.plot(temperatures, balance_values_0, marker='o', label='0% 平衡值',color='green')
plt.plot(temperatures, balance_values_100, marker='o', label='100% 平衡值',color='blue')
plt.plot(temperatures, balance_values_50, marker='o', label='50% 平衡值',color='red')
# 在坐标点上绘制温度值
for i in range(len(temperatures)):
plt.text(temperatures[i], balance_values_0[i], f'{temperatures[i]}°C', fontproperties=font)
plt.text(temperatures[i], balance_values_100[i], f'{temperatures[i]}°C', fontproperties=font)
plt.text(temperatures[i], balance_values_50[i], f'{temperatures[i]}°C', fontproperties=font)
# 添加标题和标签
if USE_EPM:
plt.title('[自研EPM]温度变化对0%、100% 平衡值驱动的影响', fontproperties=font)
else:
plt.title('[SAMSON的EPM]温度变化对0%、100% 平衡值驱动的影响', fontproperties=font)
plt.xlabel('温度 (°C)', fontproperties=font)
plt.ylabel('平衡值', fontproperties=font)
plt.legend(prop=font)
# 显示图形
plt.show()

View File

@ -11,6 +11,7 @@
#include "test_bsp.h"
#include "entity.h"
#include "board.h"
#include "hart.h"
#include "rtc_rx8010.h"
#include "eeprom_m95.h"
#include "eeprom_fm24.h"
@ -238,9 +239,9 @@ BOOL test_eeprom_lc02b(uint16_t addr, uint8_t *buf, uint16_t len)
uint8_t i = 0;
osel_memset((uint8_t *)test_buf, 0, 10);
eeprom_lc02b_write(addr, buf, len); // 向EEPROM写入数据
delay_ms(10); // 芯片要求必须等待10ms
eeprom_lc02b_read(addr, test_buf, len); // 从EEPROM读取数据到tmp数组中
// eeprom_lc02b_write(addr, buf, len); // 向EEPROM写入数据
delay_ms(10); // 芯片要求必须等待10ms
// eeprom_lc02b_read(addr, test_buf, len); // 从EEPROM读取数据到tmp数组中
for (i = 0; i < len; i++)
{
@ -320,8 +321,8 @@ static BOOL test_flashdb_kv(void)
default_kv.kvs = default_kv_table;
default_kv.num = sizeof(default_kv_table) / sizeof(default_kv_table[0]);
/* set the lock and unlock function if you want */
fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_LOCK, (void *)fdb_lock);
fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_UNLOCK, (void *)fdb_unlock);
// fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_LOCK, (void *)fdb_lock);
// fdb_kvdb_control(&kvdb, FDB_KVDB_CTRL_SET_UNLOCK, (void *)fdb_unlock);
/* Key-Value database initialization
*
* &kvdb: database object
@ -406,8 +407,8 @@ static BOOL test_flashdb_ts(void)
/* TSDB object */
static struct fdb_tsdb tsdb = {0};
/* set the lock and unlock function if you want */
fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_LOCK, (void *)fdb_lock);
fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_UNLOCK, (void *)fdb_unlock);
// fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_LOCK, (void *)fdb_lock);
// fdb_tsdb_control(&tsdb, FDB_TSDB_CTRL_SET_UNLOCK, (void *)fdb_unlock);
/* Time series database initialization
*
* &tsdb: database object
@ -533,19 +534,19 @@ BOOL test_led(void)
delay_tick(10); // 等待10个时钟周期
switch (i)
{
case LEDS_1_RED:
case LEDS_RED:
ret = GPIO_READ(LED1_GPIO_Port, LED1_Pin);
break;
case LEDS_1_GREEN:
case LEDS_GREEN:
ret = GPIO_READ(LED2_GPIO_Port, LED2_Pin);
break;
case LEDS_1_YELLOW:
case LEDS_YELLOW:
ret = GPIO_READ(LED3_GPIO_Port, LED3_Pin);
break;
case LEDS_2_ORANGE:
case LEDS_ORANGE:
ret = GPIO_READ(LED4_GPIO_Port, LED4_Pin);
break;
case LEDS_2_BLUE:
case LEDS_BLUE:
ret = GPIO_READ(LED5_GPIO_Port, LED5_Pin);
break;
default:
@ -561,27 +562,27 @@ BOOL test_led(void)
{
switch (i)
{
case LEDS_1_RED:
case LEDS_RED:
GPIO_SET(LED1_GPIO_Port, LED1_Pin);
delay_tick(10);
ret = GPIO_READ(LED1_GPIO_Port, LED1_Pin);
break;
case LEDS_1_GREEN:
case LEDS_GREEN:
GPIO_SET(LED2_GPIO_Port, LED2_Pin);
delay_tick(10);
ret = GPIO_READ(LED2_GPIO_Port, LED2_Pin);
break;
case LEDS_1_YELLOW:
case LEDS_YELLOW:
GPIO_SET(LED3_GPIO_Port, LED3_Pin);
delay_tick(10);
ret = GPIO_READ(LED3_GPIO_Port, LED3_Pin);
break;
case LEDS_2_ORANGE:
case LEDS_ORANGE:
GPIO_SET(LED4_GPIO_Port, LED4_Pin);
delay_tick(10);
ret = GPIO_READ(LED4_GPIO_Port, LED4_Pin);
break;
case LEDS_2_BLUE:
case LEDS_BLUE:
GPIO_SET(LED5_GPIO_Port, LED5_Pin);
delay_tick(10);
ret = GPIO_READ(LED5_GPIO_Port, LED5_Pin);
@ -749,11 +750,11 @@ static void power_test_open_pressure(void)
static void power_test_open_led(void)
{
leds_on(LEDS_1_GREEN);
// leds_on(LEDS_1_RED);
// leds_on(LEDS_2_ORANGE);
// leds_on(LEDS_2_BLUE);
// leds_on(LEDS_1_YELLOW);
leds_on(LEDS_GREEN);
// leds_on(LEDS_RED);
// leds_on(LEDS_ORANGE);
// leds_on(LEDS_BLUE);
// leds_on(LEDS_YELLOW);
}
static void power_test_output_swo(void)
{

View File

@ -5,6 +5,7 @@
#include "lib.h"
#include "entity.h"
#include "board.h"
#include "hart.h"
#include "rtc_rx8010.h"
#include "eeprom_m95.h"
#include "eeprom_fm24.h"

View File

@ -1,43 +1,97 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "uthash.h"
#define N 1000
const int RUN_MAX = 100000;
#define NUM_TO_ASCII(num) ((num) + '0')
void dev_serial_number_to_string(char *s, uint8_t *sn, uint8_t len)
struct int_hash
{
uint8_t interval = 0; // 间隔x位插入'-'
uint8_t count = 0;
for (uint8_t i = 0; i < len; i++)
{
s[count] = NUM_TO_ASCII(*(sn + i));
count++;
if (interval != 0)
{
if ((i + 1) % interval == 0 && count < count + len / interval)
{
s[count] = '-';
count++;
}
}
}
int id;
UT_hash_handle hh;
};
if (interval != 0)
struct int_hash *hash_table = NULL;
int array[N + 1] = {0}; // 假设数组足够大可以存储0-1000的标记
void add_to_hash(int id)
{
struct int_hash *s;
HASH_FIND_INT(hash_table, &id, s);
if (!s)
{
s[len + len / interval - 1] = '\0'; // 添加字符串结束符
s = (struct int_hash *)malloc(sizeof *s);
s->id = id;
HASH_ADD_INT(hash_table, id, s);
}
else
}
void add_to_array(int id)
{
array[id] = id; // 标记该数字已存在
}
struct int_hash *find_in_hash(int id)
{
struct int_hash *s;
HASH_FIND_INT(hash_table, &id, s);
return s;
}
int find_in_array(int id)
{
for (size_t i = 0; i < N; i++)
{
s[len] = '\0'; // 添加字符串结束符
if (array[i] == id)
{
return array[i];
}
}
}
int main()
{
uint8_t sn[16] = {0}; // 16个0
char s[19]; // 16 digits + 3 dashes + 1 null terminator
dev_serial_number_to_string(s, sn, 16);
srand(time(NULL));
printf("Formatted serial number: %s\n", s);
// 填充哈希表和数组
for (int i = 0; i < N; i++)
{
int num = rand() % (N + 1); // 生成0-1000的随机数
add_to_hash(num);
add_to_array(num);
}
// 查找数字100模拟查找200个数的场景但这里只查找100
clock_t start_hash, end_hash;
clock_t start_array, end_array;
// 查找哈希表
start_hash = clock();
for (int i = 0; i < RUN_MAX; i++)
{
find_in_hash(N - 1);
}
end_hash = clock();
// 查找数组
start_array = clock();
for (int i = 0; i < RUN_MAX; i++)
{
find_in_array(N - 1);
}
end_array = clock();
printf("Hash table lookup time: %ld\n", end_hash - start_hash);
printf("Array lookup time: %ld\n", end_array - start_array);
// 清理哈希表
struct int_hash *current, *tmp;
HASH_ITER(hh, hash_table, current, tmp)
{
HASH_DEL(hash_table, current);
free(current);
}
return 0;
}

16
Tests/version.bat Normal file
View File

@ -0,0 +1,16 @@
@echo off
setlocal enabledelayedexpansion
set "version="
set "debug_enable="
for /f "tokens=1,2 delims==" %%i in (version.txt) do (
if "%%i"=="VERSION" set "version=%%j"
if "%%i"=="DEBUG_ENABLE" set "debug_enable=%%j"
)
echo VERSION: %version%
echo DEBUG_ENABLE: %debug_enable%
endlocal
pause

41
Tests/version.py Normal file
View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
import re
import os
import sys
# 设置控制台编码为 UTF-8
sys.stdout.reconfigure(encoding='utf-8')
# 获取当前脚本所在目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构建entity.h文件的绝对路径
file_path = os.path.join(current_dir, '../User/entity.h')
# 打开并读取文件内容
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
# 读取调试模式
debug_enable_match = re.search(r'#define DEBUG_ENABLE (TRUE|FALSE)', content)
# 使用正则表达式匹配并提取版本号
dw_ver_match = re.search(r'#define DW_VER (\d+)', content)
hw_ver_match = re.search(r'#define HW_VER (\d+)', content)
sw_ver_match = re.search(r'#define SW_VER (\d+)', content)
# 提取调试模式
debug_enable = debug_enable_match.group(1) if debug_enable_match else 'N/A'
# 提取版本号
dw_ver = dw_ver_match.group(1) if dw_ver_match else 'N/A'
hw_ver = hw_ver_match.group(1) if hw_ver_match else 'N/A'
sw_ver = sw_ver_match.group(1) if sw_ver_match else 'N/A'
version_info_path = os.path.join(current_dir, 'version.txt')
# 将版本号写入文件
with open(version_info_path, 'w', encoding='utf-8') as version_file:
version_file.write(f'VERSION=v{dw_ver}.{hw_ver}.{sw_ver}\n')
version_file.write(f'DEBUG_ENABLE={debug_enable}\n')
print(f"version: {dw_ver}.{hw_ver}.{sw_ver}")
print(f"debug: {debug_enable}")
except FileNotFoundError:
print(f"file not find: {file_path}")

2
Tests/version.txt Normal file
View File

@ -0,0 +1,2 @@
VERSION=v2.5.22
DEBUG_ENABLE=TRUE

View File

@ -8,44 +8,295 @@
#include "app.h"
#include "adcs.h"
#include "menus.h"
#include "test_bsp.h"
#include "bootload.h"
#include "wl_flash.h"
#include "fal_execution.h"
noinit_data_t noinit_data __attribute__((section("NOINIT"), zero_init)); // 非初始化数据 https://blog.51cto.com/u_15427821/4586693
__IO udevice_t udevice __attribute__((section("NOINIT"), zero_init)); // 设备参数
__IO rt_save_param_t rt_save __attribute__((section("NOINIT"), zero_init)); // 实时参数
__IO calib_param_t calib_param[CALIBPARA_MAX] __attribute__((section("NOINIT"), zero_init)); // 校准参数
pressure_calib_param_t pressure_calib_param[PRESSURE_PARAM_MAX] __attribute__((section("NOINIT"), zero_init)); // 压力校准参数
__IO real_time_data_t rt_data; // 实时参数
pid_t _pid; // pid参数
driver_icon_enable_u driver_icon_enable; // 驱动使能图标
__IO calib_param_t calib_param[CALIBPARA_NUM]; // 校准参数
device_typedef udevice; // 设备参数
real_time_data_t rt_data; // 实时参数
pid_t _pid; // pid参数
driver_icon_enable_u driver_icon_enable; // 驱动使能图标
uint32_t mode_default_autoload; // 默认自动加载
// 模拟量
__IO uint16_t adc_raw[ADC1_MAX]; // ADC原始值
// 数字量
__IO float32 pid_target = 0; // pid控制目标
__IO float32 pid_actual = 0; // pid控制实际
__IO float32 show_loop = 0; // 显示电流
__IO float32 show_target = 0; // 显示目标
__IO float32 show_actual = 0; // 显示实际
__IO float32 range_percentage; // 量程百分比
__IO const static uint32_t cupid_encrypt = 0xFFFFFFFF;
#ifndef BOOTLOAD // 非bootload模式
static void app_preload(void)
{
mode_default_autoload = LL_TIM_GetAutoReload(TIM7);
if (app_preload_flag != 0xa5)
__IO const static uint32_t cupid_encrypt = 0xFFFFFFFF;
/**
* @brief
*
* NOINIT_NORESET_FLAG
* NOINIT_NORESET_FLAGNOINIT_NORESET_FLAG
*/
static BOOL noinit_data_reload(void)
{
uint32_t crc = 0;
if (noinit_data.rest_flag == NOINIT_NORESET_FLAG)
{
app_preload_flag = 0xa5;
udevice.display_language = CHINESE;
app_preload_language_flag = udevice.display_language;
app_preload_cupid_encrypt = 0xFFFFFFFF;
crc = crc32_compute((uint8_t *)&noinit_data, sizeof(noinit_data_t) - sizeof(uint32_t));
if (crc != noinit_data.crc)
{
osel_memset((uint8_t *)&noinit_data, 0, sizeof(noinit_data_t));
return FALSE;
}
crc = crc32_compute((uint8_t *)&udevice, sizeof(udevice_t) - sizeof(uint32_t));
if (crc != udevice.crc || udevice.dev_version != CURRENT_VERSION)
{
return FALSE;
}
// 如果是上电重启需要将数据复制到相关参数中
if (noinit_data.flag.bits.reset_or_power_on == TRUE)
{
osel_memset((uint8_t *)&calib_param, 0, (CALIBPARA_MAX * sizeof(calib_param_t)));
osel_memset((uint8_t *)&udevice, 0, sizeof(udevice_t));
osel_memset((uint8_t *)&rt_data, 0, sizeof(real_time_data_t));
osel_memset((uint8_t *)&mode_params, 0, sizeof(mode_params_u));
udevice.display_language = noinit_data.language;
udevice.inst_mode = noinit_data.inst_mode;
udevice.control_mode = noinit_data.control_mode;
udevice.dev_algorithm_mode = noinit_data.dev_algorithm_mode;
if (udevice.control_mode == DIGITAL_CTRL_MODE)
{
rt_save.travel_set_pt = ((float32)(noinit_data.travel_set_pt)) * 0.1f;
}
if (noinit_data.dev_model != 0)
{
udevice.dev_model = noinit_data.dev_model;
}
else
{
return FALSE;
}
if (noinit_data.dead_zone != 0)
{
udevice.integral_db = noinit_data.dead_zone;
}
else
{
return FALSE;
}
if (noinit_data.loop.is_calibration == TRUE)
{
osel_memcpy((uint8_t *)&calib_param[CALIBPARA_LOOP], (uint8_t *)&noinit_data.loop, sizeof(calib_param_t));
}
else
{
return FALSE;
}
if (noinit_data.loop_output.is_calibration == TRUE)
{
osel_memcpy((uint8_t *)&calib_param[CALIBPARA_VIP], (uint8_t *)&noinit_data.loop_output, sizeof(calib_param_t));
}
if (noinit_data.pressure_s.is_calibration == TRUE)
{
osel_memcpy((uint8_t *)&calib_param[CALIBPARA_PS], (uint8_t *)&noinit_data.pressure_s, sizeof(calib_param_t));
}
switch (udevice.dev_algorithm_mode)
{
case MODE_VARIABLE_FREQUENCY_CONTROL_ALGORITHM:
osel_memcpy((uint8_t *)&mode_params.control, noinit_data.mode_params, sizeof(mode_control_storage_t));
break;
case MODE_SPEED_CONTROL_ALGORITHM:
osel_memcpy((uint8_t *)&mode_params.pwmp, noinit_data.mode_params, sizeof(pwmp_storage_pars_t));
break;
default:
return FALSE;
}
}
mode_init(); // 工作模式初始化
mode_master_detection(); // 工作模式控制管理
ENABLE_TIM(MODE_GATHE_TIM); // Enable MODE_GATHE_TIM
ENABLE_TIM(MODE_TIM); // MODE_TIM用于算法控制
return TRUE;
}
else
{
udevice.display_language = app_preload_language_flag;
return FALSE;
}
}
/**
* @brief
*
*
*
* @note
*/
void noinit_data_set(void)
{
noinit_data.language = udevice.display_language;
noinit_data.inst_mode = udevice.inst_mode;
noinit_data.control_mode = udevice.control_mode;
noinit_data.dev_algorithm_mode = udevice.dev_algorithm_mode;
if (noinit_data.control_mode == DIGITAL_CTRL_MODE)
{
noinit_data.travel_set_pt = (int16_t)(rt_save.travel_set_pt * 10);
}
else
{
noinit_data.travel_set_pt = 0;
}
set_app_preload_bootload_flag(FALSE);
if (udevice.dev_model != 0)
{
noinit_data.dev_model = udevice.dev_model;
}
if (udevice.integral_db != 0)
{
noinit_data.dead_zone = udevice.integral_db;
}
if (calib_param[CALIBPARA_LOOP].is_calibration == TRUE)
{
osel_memcpy((uint8_t *)&noinit_data.loop, (uint8_t *)&calib_param[CALIBPARA_LOOP], sizeof(calib_param_t));
}
if (calib_param[CALIBPARA_VIP].is_calibration == TRUE)
{
osel_memcpy((uint8_t *)&noinit_data.loop_output, (uint8_t *)&calib_param[CALIBPARA_VIP], sizeof(calib_param_t));
}
if (calib_param[CALIBPARA_PS].is_calibration == TRUE)
{
osel_memcpy((uint8_t *)&noinit_data.pressure_s, (uint8_t *)&calib_param[CALIBPARA_PS], sizeof(calib_param_t));
}
// 如果模式正在调整,则不保存参数
if (mode_get()->interface_req.mode_is_adjusting() == FALSE)
{
switch (udevice.dev_algorithm_mode)
{
case MODE_VARIABLE_FREQUENCY_CONTROL_ALGORITHM:
if (mode_params.control.tuned_flag == TUNED_SUCCESS)
{
osel_memcpy(noinit_data.mode_params, (uint8_t *)&mode_params.control, sizeof(mode_control_storage_t));
}
break;
case MODE_SPEED_CONTROL_ALGORITHM:
if (mode_params.pwmp.tuned_flag == TUNED_SUCCESS)
{
osel_memcpy(noinit_data.mode_params, (uint8_t *)&mode_params.pwmp, sizeof(pwmp_storage_pars_t));
}
break;
default:
break;
}
}
}
/**
* @brief EEPROM中读取未初始化的数据
*
* EEPROM中读取未初始化的数据noinit_data_reload函数处理这些数据
*
* @return TRUEFALSE
*/
static BOOL noinit_data_read_epprom(void)
{
// 从EPPROM中读取
if (fal_execution_kv_read(KEY_NOINIT_DATA, (uint8_t *)&noinit_data, sizeof(noinit_data_t)) == FALSE)
{
return FALSE;
}
return noinit_data_reload();
}
/**
* @brief Flash
*
* Flash区域
*
*/
void board_data_save(void)
{
wl_flash_erase(&wl_flash_board_data);
wl_flash_write(&wl_flash_board_data, (uint8_t *)&board_data, sizeof(board_data_t));
}
#ifndef BOOTLOAD // 非bootload模式
static void bootload_preload(void)
{
set_app_preload_bootload_flag(BOOTLOAD_UNSET_FLAG);
if (get_app_preload_bootload_jump_flag() == APP_PRELOAD_BOOTLOAD_JUMP_IMMEDIATELY) // 通过标志位判断是否跳转到BOOTLOAD
{
DBG_ASSERT(FALSE __DBG_LINE);
set_app_preload_bootload_jump_flag(APP_PRELOAD_BOOTLOAD_JUMP_NONE);
// 反初始化所有硬件
board_dinit();
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_PWR);
bootload_jump(BOOTLOAD_START_ADDRESS);
}
}
static void app_preload_logo(BOOL is_first)
{
if (is_first)
{
menus_init(udevice.display_language);
}
else
{
menus_set_work_index(get_work_page_index());
menus_set_language(get_language());
}
if (is_lcd_ext_board() == TRUE)
{
get_menus()->accelerate = TRUE;
#if LCD_DESIGN == FALSE
menus_loading_draw(is_first);
#else
menus_jump(MENUS_MAIN, TRUE);
#endif
gui_flush();
}
}
static void app_preload(void)
{
get_cpu_id((uint32_t *)rt_data.cpuid);
#if CPU_ENCRYPT_ENABLE == TRUE
if (cpu_judge_encrypt(board_data.app_preload_cupid_encrypt) == FALSE)
{
// 加密错误
while (1)
{
__NOP(); // 程序被拷贝才会运行到这里
}
}
#endif
bootload_preload();
if (is_lcd_ext_board() == TRUE)
{
#if LCD_DESIGN == FALSE
app_preload_logo(FALSE);
#endif
}
}
/**
* @brief BOOTLOAD传输数据
* @param {uint8_t} *data
@ -66,7 +317,7 @@ static void bootload_transmit(const uint8_t data_src, const uint8_t *data, const
*/
static void bootload_end(BOOL bootload_write_flag)
{
set_app_preload_bootload_flag(FALSE); // 更新完成恢复业务流程
set_app_preload_bootload_flag(BOOTLOAD_UNSET_FLAG); // 更新完成恢复业务流程
if (bootload_write_flag == TRUE)
{
set_app_preload_bootload_jump_flag(APP_PRELOAD_BOOTLOAD_JUMP_WAIT); // 更新完成等待用户通知跳转到bootload
@ -79,6 +330,65 @@ static void bootload_end(BOOL bootload_write_flag)
}
#endif
// 启动电压电量检查
static void startup_power_on_diagnosis(void)
{
BOOL is_low_battery = FALSE;
float32 voltage = 0.0f;
float32 current = 0.0f;
static float32 voltage_last = 0.0f;
static float32 current_last = 0.0f;
BOOL voltage_right = FALSE;
BOOL current_right = FALSE;
for (;;)
{
LL_mDelay(200);
voltage = get_cpu_volt();
current = get_current_by_resistance();
if (IS_BETWEEN(voltage, CPU_VREF_RUN_MIN, CPU_VREF_RUN_MAX) && current >= INPUT_CURRENT_RUN)
{
break;
}
// 这里需要在LCD上显示电量不足的LOG
if (is_low_battery == FALSE || (voltage_last != voltage || current_last != current))
{
voltage_right = IS_BETWEEN(voltage, CPU_VREF_RUN_MIN, CPU_VREF_RUN_MAX);
current_right = current >= INPUT_CURRENT_RUN;
voltage_last = voltage;
current_last = current;
menus_init(CHINESE);
if (is_lcd_ext_board() == TRUE)
{
menus_low_battery_draw(voltage, voltage_right, current, current_right);
gui_flush();
}
is_low_battery = TRUE;
}
}
}
// 考虑到主频加速除非PVD中断响应不一定成功
/**
* @brief PVD掉电检测功能回调处理
*
*
*
* @return
*/
// static void pvd_low(void)
// {
// // 设置掉电标志位
// {
// power_on.flag = PVD_RESET_FLAG;
// osel_memcpy(power_on.time.data, (uint8_t *)rt_save.real_time.data, ARRAY_LEN(rt_save.real_time.data));
// wl_flash_write(&wl_flash_power_on, (uint8_t *)&power_on, sizeof(device_reset_t));
// }
// }
/**
* @brief app初始化
* @return {*}
@ -86,34 +396,117 @@ static void bootload_end(BOOL bootload_write_flag)
*/
void app_init(void)
{
leds_on_all(); // 打开所有LED
#ifndef BOOTLOAD // 非bootload模式
app_preload(); // 预加载
{
system_clock_config_set_flag(TRUE);
system_clock_config_hight(); // 切换高频
fal_execution_init(); // fal初始化
params_init(); // 参数初始化
system_clock_config_low(); // 切换低频
app_hart_init(); // HART初始化
mode_init(); // 工作模式初始化
flow_init(); // 流程初始化
#if DEBUG_ENABLE == TRUE
#endif
rt_data.flag.bits.app_init_over = FALSE;
uint16_t size = 0;
#ifndef BOOTLOAD // 非bootload模式
{
LCD_POWER_ON(); // 打开LCD,3000的LED电源来自LCD供电
leds_on(LEDS_RED);
startup_power_on_diagnosis(); // 启动电源检查,内部电压>=CPU_VREF,且输入电流>=INPUT_CURRENT_RUN
leds_off_all();
wl_flash_init(&wl_flash_board_data);
// 第一次上电如果noinit_data.rest_flag!=NOINIT_NORESET_FLAG 那么是断电重启
if (noinit_data.rest_flag != NOINIT_NORESET_FLAG)
{
noinit_data.flag.bits.reset_or_power_on = TRUE;
}
else
{
noinit_data.flag.bits.reset_or_power_on = FALSE;
}
// 如果是程序复位优先启动控制模块:<=200ms
if (!noinit_data_reload())
{
noinit_data.rest_flag = 0xFFFF;
udevice.display_language = ENGLISH;
}
app_preload_logo(TRUE);
system_clock_config_high(); // 切换高频
// fal初始化
{
size = 0;
size += sizeof(calib_param_t) * CALIBPARA_MAX;
size += sizeof(mode_params_u);
size += sizeof(specification_table_data_t);
fal_execution_init(FAL_EXECUTION_EEPROM_M95_1, size);
fal_execution_set_enable(FAL_EXECUTION_EEPROM_M95_1, TRUE);
size = 0;
fal_execution_init(FAL_EXECUTION_EEPROM_M95_2, size);
fal_execution_set_enable(FAL_EXECUTION_EEPROM_M95_2, TRUE);
size = 0;
size += sizeof(udevice_t);
size += sizeof(noinit_data_t);
size += sizeof(diag_result_t);
size += sizeof(rt_save_param_t);
fal_execution_init(FAL_EXECUTION_EEPROM_FM24, size);
fal_execution_set_enable(FAL_EXECUTION_EEPROM_FM24, TRUE);
fal_execution_status_set(FAL_EXECUTION_EEPROM_M95_1, TRUE);
fal_execution_status_set(FAL_EXECUTION_EEPROM_M95_2, TRUE);
fal_execution_status_set(FAL_EXECUTION_EEPROM_FM24, TRUE);
}
system_clock_config_low();
leds_on(LEDS_GREEN);
// 断电重启:优先启动控制模块 <=2000ms
if (noinit_data.rest_flag == 0)
{
if (!noinit_data_read_epprom())
{
noinit_data.rest_flag = 0xFFFF;
}
}
key_init(); // 按键初始化
diagnosis_init(); // 诊断模块初始化
params_init(); // 参数初始化
if (noinit_data.rest_flag != NOINIT_NORESET_FLAG)
{
noinit_data.rest_flag = NOINIT_NORESET_FLAG; // 复位标志位
mode_init(); // 工作模式初始化
ENABLE_TIM(MODE_GATHE_TIM); // Enable MODE_GATHE_TIM
ENABLE_TIM(MODE_TIM); // MODE_TIM用于算法控制
}
app_preload(); // 预加载
app_hart_init(); // HART初始化,mode中的模拟诊断需要用到HART变量
flow_init(); // 流程初始化
power_on_diagnosis(); // 自检
bootload_init(bootload_transmit, bootload_end); // 在用户代码中接受更新文件需要初始化bootload
}
// TIM6 is placed after app_init to wait for the completion of fal_execution initialization.
ENABLE_TIM(TIM6); // Enable TIM6
#if LCD_DESIGN == TRUE
ENABLE_TIM(TIM7); // Enable TIM7
#endif
#else // bootload模式
// 在BOOTLOAD模式下需要关闭所有外设且不需要接受用户代码所以不需要初始化
board_dinit();
leds_off_all(); // 关闭所有LED
#endif
leds_off_all(); // 关闭所有LED
rt_data.flag.bits.app_init_over = TRUE;
ENABLE_TIM(TASK_TIM); // Enable TASK_TIM
ENABLE_TIM(HART_TIM);
#if HART_SOFTWARE_TEST_ENABLE == TRUE
// HART测试不允许有中断否则串口异常会丢失导致测试失败
DISABLE_TIM(MODE_TIM);
DISABLE_TIM(MODE_GATHE_TIM);
fal_execution_inspection_sem();
#endif
#if DEBUG_ENABLE == TRUE
#endif
}
/**
@ -123,6 +516,8 @@ void app_init(void)
*/
void app_dinit(void)
{
hart_uart_dinit();
hart_ble_dinit();
}
/**
@ -132,5 +527,16 @@ void app_dinit(void)
*/
void app_start(void)
{
flow_start();
// 板卡工作停止或运行
board_work_stop_or_run();
// BOOTLOAD标志位,执行业务流程
if (get_app_preload_bootload_flag() == BOOTLOAD_UNSET_FLAG)
{
flow_start();
}
else
{
bootload_flow_start();
}
}

View File

@ -8,19 +8,20 @@
#ifndef __APP_H__
#define __APP_H__
#include "main.h"
#include "lib.h"
#include "board.h"
#include "delay.h"
#include "pid.h"
#include "entity.h"
#include "hart_frame.h"
#include "hart_frame_user.h"
#include "fal_execution.h" // fal
#include "key.h" // 按键
#include "params.h" // 参数
#include "convert.h" // 转换
#include "diagnosis.h" // 诊断
#include "mode.h" // 工作模式
typedef enum
{
APP_UART_1,
@ -28,43 +29,6 @@ typedef enum
APP_UART_MAX,
} app_uart_e;
// 这里的结构体不能使用1字节对齐让其自动对齐
typedef struct
{
float32 input_current; // 输入电流
uint16_t valve_feedback; // 阀位反馈
uint16_t atmospheric_pressure_source; // 气压源压力
uint16_t pressure_at_port_a; // A口压力
uint16_t pressure_at_port_b; // B口压力
uint16_t amplifier_circuit; // 放大器回路
float32 built_in_temperature; // 内置温度
uint16_t ip_output_detection; // IP输出检测
float32 valve_percentage; // 阀位百分比
} app_analog_quantity_t; // 模拟量
typedef struct
{
float32 input_current; // 输入电流
uint16_t valve_feedback; // 阀位反馈
uint16_t atmospheric_pressure_source; // 气压源压力
uint16_t pressure_at_port_a; // A口压力
uint16_t pressure_at_port_b; // B口压力
uint16_t amplifier_circuit; // 放大器回路
float32 built_in_temperature; // 内置温度
uint16_t ip_output_detection; // IP输出检测
float32 target_row; // 目标行程
float32 current_row; // 当前行程
float32 friction; // 摩擦力
float32 spring_force; // 弹簧力
} app_digital_quantity_t; // 数字量
typedef struct
{
app_analog_quantity_t analog_quantity;
app_digital_quantity_t digital_quantity;
} app_dynamics_t;
extern void app_init(void);
extern void app_dinit(void);
extern void app_start(void);
@ -75,12 +39,12 @@ extern void bootload_flow_start(void);
extern BOOL app_hart_init(void);
extern void app_hart_inspection(void);
extern BOOL app_hart_is_idle(void);
extern void hart_uart_init(void);
extern void hart_uart_dinit(void);
extern void hart_ble_init(void);
extern void hart_ble_dinit(void);
extern void hart_rx_process(void);
extern void h24_bluetooth_work(uint8_t index);
extern void bluetooth_work(uint8_t index);
extern void menu_inspection(void);
extern void scheduler_time_1s_irqhandler(uint8_t cycle);
#endif // __APP_H__

View File

@ -12,24 +12,140 @@
#include "flow.h"
#include "tim.h"
#include "filter.h"
#include "lcds.h"
#include "menus.h"
#include "mode.h"
#include "at_hc24.h"
#include "mode_diagnosis.h"
#include "at_bluetooth.h"
#include "bootload.h"
__IO flow_event_e flow_event = FLOW_EVENT_NORMAL; // 流程事件
static struct flow business_fw; // 业务流程
static struct flow system_fw; // 系统检测
static struct flow btn_fw; // 按键检测
static struct flow idle_fw; // 空闲任务
#include "app_hart.h"
// bootloader
static struct flow bootload_system_fw; // BOOTLOAD系统流程
// 子任务
static struct flow current_fw; // 电流检测
uint16_t scheduler_use_time = 0;
/**
* @brief 100
*
* 100
*
* @param cycle
*/
void scheduler_time_1s_irqhandler(uint8_t cycle)
{
DBG_ASSERT(cycle > 0 __DBG_LINE);
static uint32_t cnt = 0;
uint32_t time_ms = ++cnt * cycle;
// 考虑是否要控制器工作的时候才计时
if (rt_save.dev_run_time_h < WORK_HOURS_MAX)
{
if (time_ms % 1000 == 0)
{
rt_save.dev_run_time_s++; // 工作时长
}
if (rt_save.dev_run_time_s >= 3600)
{
rt_save.dev_run_time_h++;
rt_save.dev_run_time_s = 0;
}
}
// 控制过程中快速闪灯
if (mode_get()->interface_req.mode_control_idle() == FALSE)
{
if (time_ms % 200 == 0)
{
diagnosis_fault_indicate((diag_class_e)get_diagnosis_result()->priority);
}
}
else
{
if (time_ms % 1000 == 0)
{
diagnosis_fault_indicate((diag_class_e)get_diagnosis_result()->priority);
}
}
}
/**
* @brief bootload系统检测
* @param {struct flow *} fl
* @return {*}
*/
static uint8_t bootload_systom_inspection(struct flow *fl)
{
FL_HEAD(fl);
for (;;)
{
if (TRUE == BLE_IS_ENABLE())
{
leds_off(LEDS_RED);
leds_toggle(LEDS_GREEN);
}
else
{
leds_off(LEDS_GREEN);
leds_toggle(LEDS_RED);
}
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
}
FL_TAIL(fl);
}
#if HART_SOFTWARE_TEST_ENABLE == FALSE
static struct flow sensor_fw; // 传感器检测
static struct flow business_fw; // 业务流程
static struct flow system_fw; // 系统检测
static struct flow idle_fw; // 空闲任务
// 时间戳更新
static void timestamp_update(uint8_t cycle)
{
BOOL ret = FALSE;
rtc_date_t date;
rtc_time_t time;
uint32_t timestamp = 0;
static uint8_t count = 0;
if (count++ >= cycle)
{
count = 0;
ret = rtc_get_datetime(&date, &time);
if (ret == TRUE)
{
timestamp = time2stamp(&date, &time);
if (timestamp > rt_data.seconds)
{
rt_save.real_time.date.year = date.year;
rt_save.real_time.date.month = date.month;
rt_save.real_time.date.day = date.day;
rt_save.real_time.date.hour = time.hour;
rt_save.real_time.date.minute = time.minute;
rt_save.real_time.date.second = time.second;
rt_data.seconds = timestamp;
}
// 如果rtc_get_datetime失败则不需要额外操作但可以在调试时记录
// else
// {
// // 记录错误或进行其他处理
// }
}
}
}
// 实时数据部分更新
static void rt_data_update(void)
{
rt_data.board_current = get_board_current();
rt_data.cpu_percent = scheduler_time_occupancy_get(1000);
rt_data.cpu_temperature = get_cpu_temperature();
rt_data.cpu_volt = get_cpu_volt();
rt_data.mem_percent = my_mem_perused(SRAMIN);
rt_data.dc = CPU_VREF * adc_raw[ADC_DCDC_CHANNEL] * 4 / ADC_MAX;
rt_data.vdd = CPU_VREF * adc_raw[ADC_VDD_CHANNEL] * 4 / ADC_MAX;
timestamp_update(3); // 这个周期数量根据外面的任务时间来定
}
/**
* @brief
* @return {*}
@ -37,7 +153,12 @@ uint16_t scheduler_use_time = 0;
*/
void menu_inspection(void)
{
if (lcd->info.need_build == TRUE)
{
lcd->info.need_build = FALSE; // need_build 在menu_build中被置位
menus_rebuild();
}
menu_task();
}
/**
@ -49,23 +170,23 @@ static void icon_inspection(void)
{
if (FALSE == HART_IS_ENABLE())
{
driver_icon_enable.Bits.hart = 0; // 禁用HART
driver_icon_enable.bits.hart = 0; // 禁用HART
}
else
{
driver_icon_enable.Bits.hart = 1; // 使能HART
driver_icon_enable.bits.hart = 1; // 使能HART
}
if (FALSE == BLE_IS_ENABLE()) // 检查蓝牙是否已启用
{
driver_icon_enable.Bits.bluetooth = 0; // 禁用蓝牙
driver_icon_enable.bits.bluetooth = 0; // 禁用蓝牙
}
else
{
driver_icon_enable.Bits.bluetooth = 1; // 使能蓝牙
driver_icon_enable.bits.bluetooth = 1; // 使能蓝牙
}
driver_icon_enable.Bits.work_mode = (uint8_t)udevice.dev_work_mode; // 工作模式
driver_icon_enable.bits.work_mode = (uint8_t)udevice.control_mode; // 工作模式
// TODO 设备是否锁定检查
}
@ -74,63 +195,110 @@ static void bootload_start_inspection(void)
{
}
/**
* @brief
* @return {*}
* @note
* 1. LCD的开启和关闭
*/
static void temperature_inspection(void)
// LCD 、LED检测
static void lcd_detection(float32 loop_current, float32 temperature)
{
// 定义一个布尔变量lcd_close用于标记LCD是否已关闭
static BOOL lcd_close = FALSE;
// 获取当前温度
rt_data.temperature = get_temperature();
// 判断温度是否大于等于LCD工作温度最小值如果是则启动LCD
if (rt_data.temperature >= LCD_WORK_TEMP_MIN)
BOOL lcd_close = FALSE, led_close = FALSE;
// LCD扩展板必须接入
if (is_lcd_ext_board() == FALSE)
{
lcd_init(); // 初始化LCD
if (lcd_close == TRUE) // 检查LCD是否已关闭如果是则打开LCD
{
lcd_close = FALSE;
}
gui_set_scandir(udevice.display_direction); // 更新扫描方向
gui_open(); // 打开LCD
lcd_close = TRUE;
rt_data.flag.bits.lcd_detect = FALSE;
// GPS2000的LED在板子上简单处理LED不要反初始化了
// led_close = TRUE;
}
// 否则关闭LCD
else
{
lcd_dinit();
rt_data.flag.bits.lcd_detect = TRUE;
}
if (gui_can_work() == FALSE)
{
lcd_close = TRUE;
}
if (*mode_get()->ctrl.mode == STOP_MODE)
{
lcd_close = TRUE;
}
/**
* LCD的有效工作范围内
* LCD
*
* @param rt_data
*/
if (temperature < temperature_c2unit(LCD_WORK_TEMP_MIN, udevice.temp_unit) || temperature > temperature_c2unit(LCD_WORK_TEMP_MAX, udevice.temp_unit))
{
lcd_close = TRUE;
}
// 如果工作模式为停止模式则关闭LCD
if (*mode_get()->ctrl.mode == STOP_MODE)
{
lcd_close = TRUE;
}
if (lcd_close == TRUE)
{
gui_clr(); // 清除LCD
lcd_dinit();
get_menus()->run_enable = FALSE;
}
else
{
lcd_init(); // 初始化LCD
if (rt_data.flag.bits.lcd_detect == TRUE) // 检查LCD是否已关闭如果是则打开LCD
{
if (get_menus()->run_enable == FALSE)
{
#if LCD_DESIGN == FALSE
menus_jump(MENUS_WORK, FALSE); // 跳转到工作界面
#endif
}
get_menus()->run_enable = TRUE;
}
else
{
get_menus()->run_enable = FALSE;
}
gui_set_scandir(udevice.display_direction); // 更新扫描方向
menus_set_scandir(udevice.display_direction); // 设置菜单显示方向
gui_open(); // 打开LCD
}
if (led_close == TRUE)
{
leds_dinit();
}
else
{
leds_init(); // 初始化LED
}
}
/************************************************ 以下为应用线程 ************************************************/
/**
* @brief
* @return {*}
* @note
* 1. HART的启动和关闭
* 2.
*/
static uint8_t current_inspection(struct flow *fl)
static void ble_detection(float32 loop_current, float32 temperature)
{
FL_HEAD(fl);
// 定义一个浮点数变量loop_current用于存储当前电流
static float32 current = 0.0;
// 计算当前电流方法为读取ADC通道ADC_LOOP_CHANNEL的平均值并转换为浮点数
current = loop_current_convert(adc_result_average(ADCS_1, ADC_LOOP_CHANNEL));
float32 ble_close = FALSE;
// 判断当前电流是否大于等于3.8mA如果是则启动UART
if (current >= INPUT_CURRENT_MIN)
if (loop_current >= INPUT_CURRENT_MIN_UART)
{
driver_init(); // 初始化驱动
if (FALSE == HART_IS_ENABLE()) // 检查HART是否已启用如果否则初始化HART UART
{
hart_uart_init();
}
else
{
// #if DEBUG_ENABLE == TRUE
// static uint8_t hart_send_test_cnt = 0;
// if (hart_send_test_cnt++ <= 2)
// {
// hart_write_test();
// }
// #endif
}
}
// 否则关闭UART
else
@ -139,66 +307,133 @@ static uint8_t current_inspection(struct flow *fl)
hart_uart_dinit(); // 关闭HART UART
}
// 判断当前电流是否大于等于xx mA且工作模式在离线模式下如果是则启动蓝牙
if ((current >= BLE_CURRENT_WORK && udevice.dev_work_mode == OFF_LINE_MODE) ||
(current >= BLE_CURRENT_WORK && H24_BLE_OUTPUT_DBG == TRUE))
if (temperature < BLE_WORK_TEMP_MIN || temperature > BLE_WORK_TEMP_MAX)
{
if (FALSE == BLE_IS_ENABLE()) // 检查蓝牙是否已启用,如果否,则初始化蓝牙
ble_close = TRUE;
}
// 蓝牙
// 判断当前电流是否大于等于xx mA且工作模式在离线模式下如果是则启动蓝牙
if (udevice.wireless_enable == TRUE)
{
if ((loop_current >= BLE_CURRENT_WORK && udevice.control_mode == DIGITAL_CTRL_MODE) ||
(loop_current >= BLE_CURRENT_WORK && DEBUG_ENABLE == TRUE))
{
hart_ble_init();
}
else
{
// 检查蓝牙是否正常工作
if (BIT_IS_CLR(hc_24_state, BIT2))
if (FALSE == BLE_IS_ENABLE()) // 检查蓝牙是否已启用,如果否,则初始化蓝牙
{
h24_bluetooth_work(1);
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
if (BIT_IS_SET(hc_24_state, BIT0))
{
// 检查蓝牙名称
h24_bluetooth_work(2);
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
if (BIT_IS_CLR(hc_24_state, BIT1))
{
// 设置蓝牙名称
h24_bluetooth_work(3);
}
BIT_SET(hc_24_state, BIT2);
}
else
{
BIT_SET(hc_24_state, BIT2); // 如果蓝牙被主动连接的话上面的AT指令不会有响应
}
hart_ble_init();
delay_ms(500);
}
else
{
// h24_bluetooth_work(100);
// 检查蓝牙是否正常工作
if (BIT_IS_CLR(bluetooth_state, BIT2))
{
delay_ms(500);
if (BIT_IS_CLR(bluetooth_state, BIT0))
{
bluetooth_work(AT_CMD_TEST);
delay_ms(500);
}
if (BIT_IS_SET(bluetooth_state, BIT0))
{
// 检查蓝牙名称
bluetooth_work(AT_CMD_NAME_REQ);
delay_ms(500);
if (BIT_IS_CLR(bluetooth_state, BIT1))
{
// 设置蓝牙名称
bluetooth_work(AT_CMD_NAME);
}
#if BLE_TYPE == BLE_TYPE_MX02
delay_ms(100);
bluetooth_work(AT_CMD_TX_POWER);
#endif
BIT_SET(bluetooth_state, BIT2);
}
else
{
BIT_SET(bluetooth_state, BIT2); // 如果蓝牙被主动连接的话上面的AT指令不会有响应
}
}
else
{
// bluetooth_work(100);
}
}
}
else
{
ble_close = TRUE;
}
}
// 否则,关闭蓝牙
else
{
ble_close = TRUE;
}
if (ble_close == TRUE)
{
if (TRUE == BLE_IS_ENABLE())
{
hart_ble_dinit(); // 关闭蓝牙
}
bluetooth_state = BIT0;
}
FL_TAIL(fl);
}
/**
* @brief
* @return {*}
*/
static uint8_t btn_inspection(struct flow *fl)
/************************************************ 以下为应用线程 ************************************************/
static uint8_t sensor_detection(struct flow *fl)
{
FL_HEAD(fl);
static float32 current = 0.0f;
static float32 temperature = 0.0f, humidity = 0.0f;
for (;;)
{
scheduler_time_start();
// 按键检测和处理
button_ticks();
// 计算当前电流方法为读取ADC通道ADC_LOOP_CHANNEL的平均值并转换为浮点数
current = get_current_by_resistance();
// 获取当前温度
rt_data.temperature = get_temperature();
// 获取当前湿度
if (sht40_read(&temperature, &humidity) == TRUE)
{
rt_data.humidity = (uint16_t)humidity;
}
if (current < INPUT_CURRENT_RUN) // 待机状态是如果电流小于INPUT_CURRENT_MIN_MCU则进行系统复位
{
sys_soft_reset();
}
else
{
if (current < SYSTEM_CLOCK_HIGHT_CURRENT_MIN)
{
rt_data.flag.bits.current_low = TRUE;
}
else
{
if (rt_data.flag.bits.current_low == TRUE)
{
#if LCD_DESIGN == FALSE
menus_jump(MENUS_WORK, FALSE); // 跳转到工作界面
#endif
}
rt_data.flag.bits.current_low = FALSE;
}
// 蓝牙
ble_detection(current, rt_data.temperature);
// LCD 、LED
lcd_detection(current, rt_data.temperature);
}
scheduler_use_time = scheduler_time_stop();
FL_LOCK_DELAY(fl, FL_CLOCK_10MSEC);
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
}
FL_TAIL(fl);
}
@ -214,32 +449,32 @@ static uint8_t systom_inspection(struct flow *fl)
for (;;)
{
scheduler_time_start();
// 当前电流检测
current_inspection(&current_fw);
// 温度检测
temperature_inspection();
scheduler_use_time = scheduler_time_stop();
// 图标检测
icon_inspection();
scheduler_use_time = scheduler_time_stop();
if (run_first == TRUE)
{
run_first = FALSE;
#if LCD_DESIGN == FALSE
ENABLE_TIM(TIM7); // TIM7用于算法控制
#endif
if (run_first == FALSE)
{
menus_set_language(udevice.display_language);
// 参数复位检测
params_restart_inspection();
set_app_preload_language_flag(udevice.display_language); // 缓存语言实时更新,用于重启是第一时间判断语言
// 在停机模式下,不进行诊断
if (*mode_get()->ctrl.mode != STOP_MODE)
{
// 过程报警 1s一次时间可以改
diagnosis_inspection(); // 第一次不做诊断,防止报错
// 故障处理
diagnosis_fault_deal();
}
}
else
{
scheduler_use_time = scheduler_time_stop();
fal_execution_inspection(1000);
scheduler_use_time = scheduler_time_stop();
set_app_preload_language_flag(udevice.display_language);
scheduler_use_time = scheduler_time_stop();
run_first = FALSE;
}
scheduler_use_time = scheduler_time_stop();
@ -262,11 +497,28 @@ static uint8_t business_inspection(struct flow *fl)
for (;;)
{
scheduler_time_start();
// 实时数据更新
rt_data_update();
// 工作模式检测
mode_detection();
mode_master_detection();
// HART检测
app_hart_inspection();
// KEIL窗口强制跳转到自整定流程需要在这里做判断
if (mode_get()->interface_req.mode_is_adjusting() == TRUE && is_selftune_menu() == FALSE)
{
// 跳转到自动整定界面
menus_jump(MENUS_SELFTUNE, TRUE);
}
uart1_set_idel_handle_1_sec(); // 设置UART1空闲处理函数
noinit_data_set(); // 设置未初始化的数据
scheduler_use_time = scheduler_time_stop();
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC);
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
}
FL_TAIL(fl);
}
@ -282,73 +534,103 @@ static uint8_t idle_inspection(struct flow *fl)
FL_HEAD(fl);
for (;;)
{
rt_data.cpu_percent = scheduler_time_occupancy_get(1000);
rt_data.cpu_temperature = adc_result_temperature(adc_result_average(ADCS_1, ADC_TEMP_CHANNEL));
rt_data.mem_percent = my_mem_perused(SRAMIN);
leds_toggle(LEDS_2_BLUE);
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
scheduler_time_start();
scheduler_use_time = scheduler_time_stop();
FL_LOCK_DELAY(fl, FL_CLOCK_SEC * 1);
}
FL_TAIL(fl);
}
/**
* @brief bootload系统检测
* @param {struct flow *} fl
* @return {*}
*/
static uint8_t bootload_systom_inspection(struct flow *fl)
#endif
#if HART_SOFTWARE_TEST_ENABLE == TRUE
static struct flow hart_soft_test; // HART软件测试
static uint8_t hart_soft_test_inspection(struct flow *fl)
{
FL_HEAD(fl);
for (;;)
{
// 电流检测
current_inspection(&current_fw);
if (TRUE == BLE_IS_ENABLE())
{
leds_off(LEDS_1_RED);
leds_toggle(LEDS_1_GREEN);
}
else
{
leds_off(LEDS_1_GREEN);
leds_toggle(LEDS_1_RED);
}
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
// 模拟传感器数据
rt_data.loop_current = 5;
rt_data.temperature = 20;
rt_data.pressure_a = 210;
rt_data.actual_travel = i2psb(rt_data.loop_current);
rt_data.driver_signal = 50;
rt_data.pressure_b = 210;
rt_save.travel_set_pt = i2psb(rt_data.loop_current);
rt_data.pressure_cross_point = 60;
rt_data.pressure_s = 210;
rt_data.target_travel = i2psb(rt_data.loop_current);
rt_data.servo_feedback = 50;
leds_toggle(LEDS_GREEN);
FL_LOCK_DELAY(fl, FL_CLOCK_SEC * 1);
}
FL_TAIL(fl);
}
#endif
#if HART_HARDWARE_TEST_ENABLE == TRUE
static struct flow hart_hardware_test; // HART硬件测试
static uint8_t hart_hardware_test_inspection(struct flow *fl)
{
FL_HEAD(fl);
static uint8_t data[64];
for (;;)
{
if (rt_data.flag.bits.hart_rts_on == TRUE)
{
if (rt_data.flag.bits.hart_send_test != 0)
{
if (rt_data.flag.bits.hart_send_test == 1)
{
osel_memset(data, 0x00, ARRAY_LEN(data));
}
else
{
osel_memset(data, 0xff, ARRAY_LEN(data));
}
HART_RTS_OFF();
hart_get_handle()->interface.response(APP_UART_1, data, ARRAY_LEN(data));
}
}
FL_LOCK_DELAY(fl, FL_CLOCK_10MSEC);
}
FL_TAIL(fl);
}
#endif
/**
* @brief:
* @return {*}
*/
void flow_start(void)
{
if (TRUE == app_hart_is_idle())
{
switch (flow_event)
{
case FLOW_EVENT_NORMAL:
{
systom_inspection(&system_fw); // 系统检测
business_inspection(&business_fw); // 业务流程检测
btn_inspection(&btn_fw); // 按键检测
idle_inspection(&idle_fw); // 空闲任务用来计算CPU占用率
break;
}
case FLOW_EVENT_DIAGNOSIS:
{
systom_inspection(&system_fw); // 系统检测
current_inspection(&current_fw); // 当前电流检测
break;
}
default:
break;
}
#if HART_HARDWARE_TEST_ENABLE == TRUE
hart_hardware_test_inspection(&hart_hardware_test); // HART硬件测试流程
#elif HART_SOFTWARE_TEST_ENABLE == TRUE
hart_soft_test_inspection(&hart_soft_test); // HART软件测试流程
hart_rx_process(); // HART接收处理
// 参数复位检测
params_restart_inspection();
if (get_current_by_resistance() >= FAL_WRITE_CURRENT)
{
fal_execution_process(); // fal执行
}
#else
sensor_detection(&sensor_fw);
systom_inspection(&system_fw); // 系统检测
business_inspection(&business_fw); // 业务流程检测
menus_process(); // 菜单处理
if (get_current_by_resistance() >= FAL_WRITE_CURRENT)
{
fal_execution_process(); // fal执行
}
idle_inspection(&idle_fw); // 空闲任务用来计算CPU占用率
#endif
}
/**
@ -358,13 +640,13 @@ void flow_start(void)
void bootload_flow_start(void)
{
bootload_systom_inspection(&bootload_system_fw); // BOOTLOAD系统流程
if (BIT_IS_CLR(hc_24_state, BIT2) == FALSE)
if (BIT_IS_CLR(bluetooth_state, BIT2) == FALSE)
{
bootload_inspection(); // BOOTLOAD检测
if (bootload_timeout() == TRUE)
{
// 如果超时退出bootload模式
set_app_preload_bootload_flag(FALSE);
set_app_preload_bootload_flag(BOOTLOAD_UNSET_FLAG);
leds_off_all();
}
}
@ -376,11 +658,18 @@ void bootload_flow_start(void)
*/
void flow_init(void)
{
FL_INIT(&current_fw); // 电流检测
#if HART_HARDWARE_TEST_ENABLE == TRUE
hart_uart_init();
FL_INIT(&hart_hardware_test); // HART硬件测试流程
#elif HART_SOFTWARE_TEST_ENABLE == TRUE
hart_uart_init();
FL_INIT(&hart_soft_test);
#else
rt_data.flag.bits.current_low == TRUE;
FL_INIT(&sensor_fw); // 电流检测
FL_INIT(&system_fw); // 系统检测
FL_INIT(&business_fw); // 业务流程
FL_INIT(&btn_fw); // 按键检测
FL_INIT(&idle_fw); // 空闲任务
FL_INIT(&bootload_system_fw); // bootload系统流程
FL_INIT(&current_fw); // 电流检测
#endif
}

View File

@ -7,15 +7,18 @@
*/
#include "app.h"
#include "hart.h"
#include "hart_frame.h"
#include "uarts.h"
#include "test_bsp.h"
#include "at_hc24.h"
#include "at_bluetooth.h"
#include "menus.h"
#include "bootload.h"
#include "ymodem.h"
#include "flow.h"
#define HART_UART1 USART1
#define HART_UART2 UART5
#include "app_hart.h"
#include <stdlib.h>
#include "app_hart_user.h"
#define HART_UART_RXSIZE (240u)
#define BLE_UART_RXSIZE (1100u) // 接收1100个字节,考虑到BOOTLOAD需要接收大量数据在RAM允许的情况下可以适当增大
@ -23,14 +26,302 @@
uart_t *uarts[APP_UART_MAX];
static struct flow hart_handle_fw; // HART处理流程
static struct flow_sem hart_msg_sem; // 消息信号量,用于同步
int8_t hart_msg_uart_index; // 消息来源的串口索引,会有并发问题不能蓝牙和HART同时来数据
static uint8_t hart_recv_msg[HART_UART_RXSIZE]; // HART接收数据缓存
static uint16_t hart_recv_msg_len; // HART接收数据长度
static void _get_real_time_clock(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec);
static void update_device_status(void); // 更新其他设备状态
app_dynamics_t app_dynamics;
static __IO BOOL hart_idle = TRUE;
/**
* @brief
*
* @param event
* @param data
*
* @return
*/
static BOOL _user_common_event(hart_interface_user_event_e event, const void *const data)
{
return hart_user_handle(event, data);
}
/**
* @brief (hart协议数据帧)
* @param {uint8_t} *txBuf
* @param {uint16_t} len
* @return {*}
*/
static void _response(uint8_t uart_index, uint8_t *data, uint16_t len)
{
#ifdef STM32
rt_data.flag.bits.hart_rts_on = FALSE;
uart_send_data(uarts[uart_index], data, len);
uart_data_storage_reset(uarts[uart_index]);
#else
LOG_HEX(data, len);
#endif
}
/**
* @brief UART的错误计数
*
* UART索引获取指定UART的错误计数
*
* @param uart_index UART索引
*
* @return STM32宏UART的错误计数0
*/
static uint16_t _uart_error_count(uint8_t uart_index)
{
#ifdef STM32
return uart_get_error_count(uarts[uart_index]);
#else
return 0;
#endif
}
static void _uart_errors(uint8_t uart_index, hart_uart_error_t *errors)
{
uint16_t count = uart_get_error_count(uarts[uart_index]);
if (count > 0)
{
uarts_interupt_error_t *uart_errors = uart_get_error(uarts[uart_index]);
if (uart_errors != NULL)
{
for (uint16_t i = 0; i < count; i++)
{
errors[i].uart_error = (hart_uarts_interupt_error_e)uart_errors[i].err;
errors[i].rx_index = uart_errors[i].index;
}
}
}
}
static void _frame_data_parse_time_start(uint16_t timer_period)
{
ENABLE_TIM(HART_TIM);
hart_timer_start(timer_period);
}
/**
* @brief
* @return {*}
*/
static uint32_t _get_timestamp(void)
{
uint8_t year, month, day, hour, min, sec;
uint32_t stamp;
rtc_date_t date;
rtc_time_t time;
_get_real_time_clock(&year, &month, &day, &hour, &min, &sec);
date.year = year;
date.month = month;
date.day = day;
time.hour = hour;
time.minute = min;
time.second = sec;
stamp = time2stamp(&date, &time);
return stamp;
}
/**
* @brief flash读取接口
* @param {uint32_t} addr
* @param {uint8_t} *data
* @param {uint16_t} len
* @return {*}
*/
static BOOL _flash_read(hart_storage_e index, uint8_t *data)
{
BOOL res = FALSE;
switch (index)
{
case HART_STORAGE_PARAMS:
res = storage_read_all(hart_attribute_storage, data);
break;
case HART_STORAGE_VARIABLE:
res = storage_read_all(hart_variable_storage, data);
break;
case HART_STORAGE_CONSTANT:
res = storage_read_all(hart_constant_storage, data);
break;
case HART_STORAGE_STANDARD_VARIABLE:
res = storage_read_all(hart_standard_variable_storage, data);
break;
default:
break;
}
return res;
}
/**
* @brief flash写入接口
* @param {uint32_t} addr
* @param {uint8_t} *data
* @param {uint16_t} len
* @return {*}
*/
static BOOL _flash_write(hart_storage_e index, uint8_t *data)
{
BOOL res = FALSE;
switch (index)
{
case HART_STORAGE_PARAMS:
res = storage_write_all(hart_attribute_storage, data);
if (storage_check_all(hart_attribute_storage, data) == FALSE)
{
rt_data.flag.bits.hart_attribute_storage = FALSE;
}
break;
case HART_STORAGE_VARIABLE:
res = storage_write_all(hart_variable_storage, data);
if (storage_check_all(hart_variable_storage, data) == FALSE)
{
rt_data.flag.bits.hart_variable_storage = FALSE;
}
break;
case HART_STORAGE_CONSTANT:
res = storage_write_all(hart_constant_storage, data);
if (storage_check_all(hart_constant_storage, data) == FALSE)
{
rt_data.flag.bits.hart_constant_storage = FALSE;
}
break;
case HART_STORAGE_STANDARD_VARIABLE:
res = storage_write_all(hart_standard_variable_storage, data);
if (storage_check_all(hart_standard_variable_storage, data) == FALSE)
{
rt_data.flag.bits.hart_standard_variable_storage = FALSE;
}
break;
default:
break;
}
return res;
}
static BOOL _flash_read_item(hart_storage_e index, uint8_t item, uint8_t *data)
{
BOOL res = FALSE;
switch (index)
{
case HART_STORAGE_PARAMS:
res = storage_read(hart_attribute_storage, item, data);
break;
case HART_STORAGE_VARIABLE:
res = storage_read(hart_variable_storage, item, data);
break;
case HART_STORAGE_CONSTANT:
res = storage_read(hart_constant_storage, item, data);
break;
case HART_STORAGE_STANDARD_VARIABLE:
res = storage_read(hart_standard_variable_storage, item, data);
break;
default:
break;
}
return res;
}
static BOOL _flash_write_item(hart_storage_e index, uint8_t item, uint8_t *data)
{
BOOL res = FALSE;
switch (index)
{
case HART_STORAGE_PARAMS:
res = storage_write(hart_attribute_storage, item, data);
if (storage_check(hart_attribute_storage, item, data) == FALSE)
{
rt_data.flag.bits.hart_attribute_storage = FALSE;
}
break;
case HART_STORAGE_VARIABLE:
res = storage_write(hart_variable_storage, item, data);
if (storage_check(hart_variable_storage, item, data) == FALSE)
{
rt_data.flag.bits.hart_variable_storage = FALSE;
}
break;
case HART_STORAGE_CONSTANT:
res = storage_write(hart_constant_storage, item, data);
if (storage_check(hart_constant_storage, item, data) == FALSE)
{
rt_data.flag.bits.hart_constant_storage = FALSE;
}
break;
case HART_STORAGE_STANDARD_VARIABLE:
res = storage_write(hart_standard_variable_storage, item, data);
if (storage_check(hart_standard_variable_storage, item, data) == FALSE)
{
rt_data.flag.bits.hart_standard_variable_storage = FALSE;
}
break;
default:
break;
}
return res;
}
/**
* @brief
* @param {*}
* @return {*}
*/
static void _perform_self_test(void)
{
// power_on_diagnosis(); // 是否需要延时回复
menus_show_custom_window(SET_CUSTOM_SELF_TEST);
}
/**
* @brief
* @param {*}
* @return {*}
*/
static void _device_reset(void)
{
get_menus()->accelerate = TRUE;
menus_show_custom_window(SET_CUSTOM_RESET);
}
/**
* @brief ,01-255
* @param {*}
* @return {*}
*/
static void _squawk_control(BOOL open, uint8_t second)
{
}
/**
* @brief command74
* @param {*}
* @return {*}
*/
static BOOL _armed(void)
{
return TRUE;
}
static void _set_real_time_clock(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
{
set_real_time(year, month, day, hour, min, sec);
}
static void _get_real_time_clock(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec)
{
get_real_time(year, month, day, hour, min, sec);
}
/**
* @brief
* @return {*}
*/
static BOOL _set_dynamics(device_variable_dynamics_t *const dynamics)
{
// HART自带部分
// 下面是用户自定义部分
return TRUE;
}
/**
* @brief
@ -39,7 +330,7 @@ static __IO BOOL hart_idle = TRUE;
* @return {*}
* @note
*/
void h24_bluetooth_output(uint8_t *data, uint16_t len)
void bluetooth_output(uint8_t *data, uint16_t len)
{
DBG_ASSERT(data != NULL __DBG_LINE);
if (len == 0)
@ -48,7 +339,11 @@ void h24_bluetooth_output(uint8_t *data, uint16_t len)
}
else
{
if (uarts[APP_UART_2] != NULL)
if (SystemCoreClock == SYSTEM_CLOCK_HIGHT)
{
return;
}
if (uarts[APP_UART_2] != NULL && BLE_IS_ENABLE() == TRUE)
{
uart_send_data(uarts[APP_UART_2], data, len);
}
@ -64,81 +359,121 @@ void h24_bluetooth_output_dbg(uint8_t *data, uint16_t len)
}
else
{
#if H24_BLE_OUTPUT_DBG == TRUE
if (BIT_IS_SET(hc_24_state, BIT2))
#if DEBUG_ENABLE == TRUE
if (BIT_IS_SET(bluetooth_state, BIT2))
{
h24_bluetooth_output(data, len);
bluetooth_output(data, len);
}
#endif
}
}
void hart_write_test(void)
{
#define TEST_LEN 10
uint8_t buf[TEST_LEN];
osel_memset(buf, 0, ARRAY_LEN(buf));
buf[0] = 0xFF;
buf[1] = 0xFF;
buf[2] = 0xFF;
buf[3] = 0xFF;
buf[4] = 0xFF;
buf[5] = 0xaa;
buf[6] = 0xbb;
buf[7] = 0xD5;
buf[8] = 0xC8;
buf[TEST_LEN - 1] = 0xce;
_response(APP_UART_1, buf, TEST_LEN);
}
/**
* @brief H24模块配置工作
* @return {*}
* @note
*/
void h24_bluetooth_work(uint8_t index)
void bluetooth_work(uint8_t index)
{
uint8_t len = 0;
char data[128];
osel_memset((uint8_t *)data, 0, 128);
#ifdef V4
char device_id[] = "LP4-???";
#elif V5
char device_id[] = "LP5-???";
#elif BOOTLOAD
// HC42蓝牙模块设置名称总长度不超过 12 字节 MX02蓝牙模块设置名称总长度不超过 20 字节
#if BOOTLOAD
char device_id[] = "BOOTLOAD";
#else
char device_id[] = "LP3-???";
char device_id[HART_PACKED12_LEN + 1];
osel_memset((uint8_t *)device_id, 0, HART_PACKED12_LEN);
sprintf(device_id, "%s", DESCRIPTOR);
uint8_t use_offset = osel_mstrlen(DESCRIPTOR);
assic_to_str((uint8_t *)&udevice.dev_serial_num[INST_SERIAL_NUM_LEN - (HART_PACKED12_LEN - use_offset)],
HART_PACKED12_LEN - use_offset, (uint8_t *)&device_id[use_offset]);
device_id[HART_PACKED12_LEN] = 0;
#endif
#if BLE_TYPE == BLE_TYPE_HC42
char *test_cmd[AT_END] = {
"AT",
"AT+NAME",
"AT+NAME=%s",
"AT+RESET",
};
#elif BLE_TYPE == BLE_TYPE_MX02
char *test_cmd[AT_END] = {
"AT+VER?\r\n",
"AT+NAME?\r\n",
"AT+NAME=%s\r\n",
"AT+TXPOWER=0\r\n",
};
#else
// 编译时输出错误提示
#error "BLE_TYPE 类型错误"
#endif
switch (index)
{
case 1: // 测试指令
case AT_CMD_TEST: // 测试指令
{
hc_24_state = 0;
bluetooth_state = 0;
sprintf(data, test_cmd[AT_CMD_TEST]);
len = osel_mstrlen((unsigned char *)data);
h24_bluetooth_output((uint8_t *)data, len);
bluetooth_output((uint8_t *)data, len);
break;
}
case 2: // 获取设备名称
case AT_CMD_NAME_REQ: // 获取设备名称
{
at_set_memcmp_cache((unsigned char *)device_id, osel_mstrlen((unsigned char *)device_id));
sprintf(data, "%s", device_id);
at_set_memcmp_cache((unsigned char *)data, osel_mstrlen((unsigned char *)data));
osel_memset((uint8_t *)data, 0, 128);
sprintf(data, test_cmd[AT_CMD_NAME_REQ]);
len = osel_mstrlen((unsigned char *)data);
h24_bluetooth_output((uint8_t *)data, len);
bluetooth_output((uint8_t *)data, len);
break;
}
case 3: // 设置设备名称
case AT_CMD_NAME: // 设置设备名称
{
at_set_memcmp_cache((unsigned char *)device_id, osel_mstrlen((unsigned char *)device_id));
sprintf(data, "%s", device_id);
at_set_memcmp_cache((unsigned char *)data, osel_mstrlen((unsigned char *)data));
osel_memset((uint8_t *)data, 0, 128);
sprintf(data, test_cmd[AT_CMD_NAME], device_id);
len = osel_mstrlen((unsigned char *)data);
h24_bluetooth_output((uint8_t *)data, len);
bluetooth_output((uint8_t *)data, len);
break;
}
case 4: // 复位
case AT_CMD_TX_POWER: // 设置发射功率
{
hc_24_state = 0;
sprintf(data, test_cmd[AT_CMD_DISA]);
bluetooth_state = 0;
sprintf(data, test_cmd[AT_CMD_TX_POWER]);
len = osel_mstrlen((unsigned char *)data);
h24_bluetooth_output((uint8_t *)data, len);
bluetooth_output((uint8_t *)data, len);
break;
}
case 100:
{
sprintf(data, "%f,%f,%f\r\n", 1.1, 2.2, 3.3);
len = osel_mstrlen((unsigned char *)data);
h24_bluetooth_output((uint8_t *)data, len);
bluetooth_output((uint8_t *)data, len);
break;
}
default:
@ -146,75 +481,76 @@ void h24_bluetooth_work(uint8_t index)
}
}
// HART处理流程
static uint8_t hart_handle_inspection(struct flow *fl)
{
FL_HEAD(fl);
for (;;)
{
FL_LOCK_WAIT_SEM_OR_TIMEOUT(fl, &hart_msg_sem, FL_CLOCK_SEC * 3600);
if (FL_SEM_IS_RELEASE(fl, &hart_msg_sem) && hart_recv_msg_len != 0)
{
// hart_handle(hart_msg_uart_index, hart_recv_msg, hart_recv_msg_len);
hart_recv_msg_len = 0;
}
}
FL_TAIL(fl);
}
// HART接收处理
void hart_rx_process(void)
{
hart_handle_inspection(&hart_handle_fw);
}
// 串口1、5接收中断回调函数
static void hart_rx_cb(uint8_t uart_index, uint8_t *data, uint16_t len)
static void hart_rx1_cb(uint8_t uart_index, uint8_t *data, uint16_t len)
{
DBG_ASSERT(uart_index < APP_UART_MAX __DBG_LINE);
hart_idle = FALSE;
if (data[0] == 'O' && data[1] == 'K') // 蓝牙协议
#ifndef BOOTLOAD
HART_RTS_OFF(); // RTS需要提前
uart1_set_idel_status(FALSE);
if (hart_handle(uart_index, data, len) == FALSE)
{
HART_RTS_ON();
}
#else
rym_receive(uart_index, data, len);
#endif
}
static void hart_rx5_cb(uint8_t uart_index, uint8_t *data, uint16_t len)
{
DBG_ASSERT(uart_index < APP_UART_MAX __DBG_LINE);
if (data[0] == 'O' && data[1] == 'K') // HC42蓝牙协议
{
data[0] = 'A';
data[1] = 'T';
at_cmd_parse(data, len);
}
else if (data[0] == '+' && data[len - 1] == '\n' && data[len - 2] == '\r') // MX02蓝牙协议
{
uint8_t mx02_data[32];
mx02_data[0] = 'A';
mx02_data[1] = 'T';
osel_memcpy(&mx02_data[2], data, len);
at_cmd_parse((unsigned char *)mx02_data, len + 2);
}
else if (data[0] == 'B' && data[1] == 'T') // 收到BOOTLOAD启动命令
{
if (osel_memcmp(data, "BT RUN", 6) == 0)
{
if (get_app_preload_bootload_flag() == FALSE) // 如果已经在BOOTLOAD模式下不再重复启动
if (get_app_preload_bootload_flag() == BOOTLOAD_UNSET_FLAG) // 如果已经在BOOTLOAD模式下不再重复启动
{
set_app_preload_bootload_flag(TRUE); // 设置BOOTLOAD标志
bootload_transmit_from(uart_index); // 从指定位置开始发送数据
set_app_preload_bootload_flag(BOOTLOAD_SET_FLAG); // 设置BOOTLOAD标志
bootload_transmit_from(uart_index); // 从指定位置开始发送数据
}
}
else if (osel_memcmp(data, "BT STOP", 7) == 0)
{
set_app_preload_bootload_flag(FALSE); // 设置BOOTLOAD标志
set_app_preload_bootload_flag(BOOTLOAD_UNSET_FLAG); // 设置BOOTLOAD标志
}
}
else
{
// 注在BOOTLOAD模式下不接收HART数据
#ifndef BOOTLOAD
// 通过消息的方式存在蓝牙和HART模块并发冲突实际情况不会发生HART协议传输速度慢存储的数据可以使用全局的方式
hart_msg_uart_index = uart_index;
osel_memcpy(hart_recv_msg, data, len);
hart_recv_msg_len = len;
FLOW_SEM_RELEASE(&hart_msg_sem);
uart1_set_idel_status(FALSE);
if (hart_handle(uart_index, data, len) == FALSE)
{
__NOP();
}
#else
rym_receive(uart_index, data, len);
#endif
}
hart_idle = TRUE;
}
static void hart_tx_complete_cb(void)
{
// 串口1发送完成回调函数
HART_RTS_ON();
rt_data.flag.bits.hart_rts_on = TRUE;
}
// HART协议的使用的串口 --- 串口1
@ -238,14 +574,19 @@ void hart_uart_init(void)
if (uarts[APP_UART_1] == NULL)
{
LL_mDelay(100);
uarts[APP_UART_1] = uart_create(HART_UART1, TRUE, HART_UART_RXSIZE, hart_rx_cb, TRUE, HART_UART_TXSIZE, hart_tx_complete_cb);
uarts[APP_UART_1] = uart_create(HART_UART1, FALSE, HART_UART_RXSIZE, hart_rx1_cb, FALSE, HART_UART_TXSIZE, hart_tx_complete_cb);
uarts[APP_UART_1]->rx_cd_en = TRUE;
uarts[APP_UART_1]->uart_index = APP_UART_1;
uarts[APP_UART_1]->dma = DMA2;
uarts[APP_UART_1]->dma_rx_channel = LL_DMA_CHANNEL_7;
uarts[APP_UART_1]->dma_tx_channel = LL_DMA_CHANNEL_6;
uart_recv_en(uarts[APP_UART_1]);
uart_recv_en(uarts[APP_UART_1], TRUE);
rt_data.flag.bits.hart_rts_on = TRUE;
}
// 串口1初始化结束
uart1_set_idel_status(TRUE);
uart_data_storage_reset(uarts[APP_UART_1]);
}
// HART协议使用的串口为模拟IO口
@ -256,7 +597,7 @@ void hart_uart_dinit(void)
LL_USART_Disable(USART1);
GPIO_SET_ANALOG(HART_PWR_GPIO_Port, HART_PWR_Pin);
GPIO_SET_ANALOG(HART_RST_GPIO_Port, HART_RST_Pin);
GPIO_SET_ANALOG(HART_CD_GPIO_Port, HART_CD_Pin);
// GPIO_SET_ANALOG(HART_CD_GPIO_Port, HART_CD_Pin); // CD作为外部输入中断不需要设置为模拟IO口
GPIO_SET_ANALOG(HART_TX_GPIO_Port, HART_TX_Pin);
GPIO_SET_ANALOG(HART_RX_GPIO_Port, HART_RX_Pin);
}
@ -269,17 +610,17 @@ void hart_ble_init(void)
GPIO_SET_INPUT(BLE_RST_GPIO_Port, BLE_RST_Pin);
GPIO_SET_ALTERNATE(BLE_TX_GPIO_Port, BLE_TX_Pin);
GPIO_SET_ALTERNATE(BLE_RX_GPIO_Port, BLE_RX_Pin);
BLE_EN_ENABLE();
if (uarts[APP_UART_2] == NULL)
{
LL_mDelay(100);
uarts[APP_UART_2] = uart_create(HART_UART2, TRUE, BLE_UART_RXSIZE, hart_rx_cb, TRUE, HART_UART_TXSIZE, NULL);
uarts[APP_UART_2] = uart_create(HART_UART2, TRUE, BLE_UART_RXSIZE, hart_rx5_cb, TRUE, HART_UART_TXSIZE, NULL);
uarts[APP_UART_2]->uart_index = APP_UART_2;
uarts[APP_UART_2]->dma = DMA2;
uarts[APP_UART_2]->dma_rx_channel = LL_DMA_CHANNEL_2;
uarts[APP_UART_2]->dma_tx_channel = LL_DMA_CHANNEL_1;
uart_recv_en(uarts[APP_UART_2]);
uart_recv_en(uarts[APP_UART_2], FALSE);
}
BLE_EN_ENABLE();
}
// 蓝牙模块端口IO口反初始化
@ -296,22 +637,326 @@ void hart_ble_dinit(void)
GPIO_SET_ANALOG(BLE_RX_GPIO_Port, BLE_RX_Pin);
}
// 判断是否闲置的结果
BOOL app_hart_is_idle(void)
static void hart_params_init(void)
{
return hart_idle;
uint32_t stmp = _get_timestamp();
uint8_t message[HART_PACKED32_LEN];
osel_memset(message, 0, HART_PACKED32_LEN);
// hart_storage_variable_t *p = &hart_device_attribute.flash_variable;
app_hart_update_time(); // 更新时间
// 记录消息
if (dbg_assert_line != 0)
{
uint16_t line = dbg_assert_line;
sprintf((char *)message, "GSDT RESET[%d]:%d", line, stmp);
// osel_memcpy(p->message, message, sizeof(message)); // 消息
dbg_assert_line = 0;
}
hart_attribute_params_map_address_update(); // 参数变量地址映射
}
// HART初始化
BOOL app_hart_init(void)
{
hart_init_t init;
init.hart_protocol_version = HART_VERSION; // 协议版本
init.dir = MODULE_SLAVE; // 协议模式--从
init.interface.response = _response;
init.interface.uart_error_count = _uart_error_count;
init.interface.uart_errors = _uart_errors;
init.interface.frame_data_parse_time_start = _frame_data_parse_time_start;
init.interface.get_timestamp = _get_timestamp;
init.interface.flash_read = _flash_read;
init.interface.flash_write = _flash_write;
init.interface.flash_read_item = _flash_read_item;
init.interface.flash_write_item = _flash_write_item;
init.interface.perform_self_test = _perform_self_test;
init.interface.device_reset = _device_reset;
init.interface.squawk_control = _squawk_control;
init.interface.armed = _armed;
init.interface.set_dynamics = _set_dynamics;
init.interface.set_real_time_clock = _set_real_time_clock;
init.interface.get_real_time_clock = _get_real_time_clock;
init.interface.user_common_event = _user_common_event;
init.interface.attribute_init = hart_attribute_params_restart;
init.interface.variable_init = hart_attribute_params_map_restart;
init.hart_timer.timer_cycle = (LL_TIM_GetAutoReload(HART_TIM) + 1) * 0.1; // 定时器周期
hart_device_attribute.last_device_variable = (uint8_t *)&rt_save.last_dev_variable;
uarts[APP_UART_1] = NULL;
uarts[APP_UART_2] = NULL;
FL_INIT(&hart_handle_fw); // 系统检测
// 判断当前电流 >=8mA启动蓝牙 >=3.8mA启动uart
// 注串口初始化移动到all_flow
// hart_uart_init();
// hart_ble_init();
hart_init(&init);
hart_params_init();
ENABLE_TIM(HART_OUT_TIM);
PWM_START(HART_OUT_TIM, LL_TIM_CHANNEL_CH2);
return TRUE;
}
/**
* @brief HART检测任务
* @return {*}
* @note
*/
void app_hart_inspection(void)
{
hart_device_attribute.internal++;
app_hart_update_time(); // 更新时间
hart_cache_detection(); // HART缓存区探测如果缓存区过期则回收
rt_save.hart_run_time_h = rt_save.dev_run_time_h / 18; // 1:18运行时间 详见参数读取-129 RUN_TIME_18HR
// 是否写保护
driver_icon_enable.bits.write_protect = hart_device_attribute.flash_variable.write_protect_code == WRITE_PROTECT_CODE_WRITE_PROTECT ? 1 : 0;
// 是否锁定
driver_icon_enable.bits.lock = hart_device_attribute.flash_variable.lock_code == LOCK_DEVICE_CODE_0 ? 0 : 1;
// 扩展设备类型
if (hart_device_attribute.flash_variable.extended_device_type != udevice.dev_model)
{
hart_device_attribute.flash_variable.extended_device_type = udevice.dev_model;
hart_long_addr_set();
hart_storage_write_item(HART_STORAGE_PARAMS, HPB_EXTENDED_DEVICE_TYPE,
(uint8_t *)&hart_device_attribute.flash_variable.extended_device_type);
hart_storage_write_item(HART_STORAGE_PARAMS, HPB_LONG_ADDRESS,
hart_device_attribute.flash_variable.long_address);
}
if (hart_device_attribute.internal % HART_INTERNAL == 0) // 需要延时判断的
{
if (hart_device_attribute.device_status.reset == TRUE)
{
LL_mDelay(200);
sys_soft_reset();
}
else if (hart_device_attribute.device_status.busy == TRUE)
{
perform_self_test_finish();
menus_rebuild();
}
}
update_device_status(); // 扩展现场设备状态 48号指令
spec_table_data_mapping(TRUE); // udevice中数据映射到规格表
// // 每60次进入执行一次检查ram和存储中数据是否一致
// if (hart_device_attribute.internal % (HART_INTERNAL * 20) == 0)
// {
// hart_storage_variable_t *p1 = &hart_device_attribute.flash_variable;
// if (storage_check_all(hart_attribute_storage, (uint8_t *)p1) == FALSE)
// {
// rt_data.flag.bits.hart_attribute_storage = FALSE;
// }
// hart_device_variable_t *p2 = hart_device_attribute.device_variable;
// if (storage_check_all(hart_variable_storage, (uint8_t *)p2) == FALSE)
// {
// rt_data.flag.bits.hart_variable_storage = FALSE;
// }
// hart_device_constant_t *p3 = hart_device_attribute.device_constant;
// if (storage_check_all(hart_constant_storage, (uint8_t *)p3) == FALSE)
// {
// rt_data.flag.bits.hart_constant_storage = FALSE;
// }
// hart_device_standard_variable_t *p4 = hart_device_attribute.device_standard_variable;
// if (storage_check_all(hart_standard_variable_storage, (uint8_t *)p4) == FALSE)
// {
// rt_data.flag.bits.hart_standard_variable_storage = FALSE;
// }
// }
}
// 更新实时时间
void app_hart_update_time(void)
{
BOOL change = FALSE;
uint8_t y, h, m, s;
real_time_clock_t *p = &hart_device_attribute.real_time_clock;
uint8_t *date = hart_device_attribute.flash_variable.date;
y = rt_save.real_time.date.year;
covert_rtc_year(&y);
if (date[2] != y || date[1] != rt_save.real_time.date.month || date[0] != rt_save.real_time.date.day)
{
change = TRUE;
}
date[2] = y;
date[1] = rt_save.real_time.date.month;
date[0] = rt_save.real_time.date.day;
p->date[0] = hart_device_attribute.flash_variable.date[0];
p->date[1] = hart_device_attribute.flash_variable.date[1];
p->date[2] = hart_device_attribute.flash_variable.date[2];
h = rt_save.real_time.date.hour;
m = rt_save.real_time.date.minute;
s = rt_save.real_time.date.second;
convert_timestrap(&p->time, h, m, s, 0);
p->rtc_flags = REAL_TIME_CLOCK_FLAGS_1;
if (change == TRUE)
{
hart_storage_write_item(HART_STORAGE_PARAMS, HPB_DATE,
hart_device_attribute.flash_variable.date);
}
}
// 判断下一篇存储数据是否已经写过数据
BOOL app_hart_storage_is_written(uint32_t address, uint16_t length)
{
uint8_t *data;
uint16_t count = 0;
ErrorStatus rst = ERROR;
BOOL res = FALSE;
count = length / LL_FLASH_PAGE_SIZE;
data = osel_mem_alloc(LL_FLASH_PAGE_SIZE);
DBG_ASSERT(data != NULL __DBG_LINE);
for (uint16_t i = 0; i < count; i++)
{
rst = LL_FLASH_Read(address + i * LL_FLASH_PAGE_SIZE, data, LL_FLASH_PAGE_SIZE);
if (rst == SUCCESS)
{
for (uint16_t j = 0; j < LL_FLASH_PAGE_SIZE; j++)
{
if (data[j] != 0xff)
{
res = TRUE;
break;
}
}
}
else
{
res = TRUE;
}
if (res == TRUE)
{
break;
}
res = FALSE;
}
osel_mem_free(data);
return res;
}
/**
* @brief
* @param {uint8_t} *rev_buf
* @return {*}
* @note
*/
static void hart_get_device_specific_status(uint8_t *rev_buf)
{
hart_device_specific_status_u st;
st.bits.u1.travel_sensor_failure = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_MAGNET);
st.bits.u1.pressure_sensor_failure = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_PRESS_SENSOR);
st.bits.u1.temperature_sensor_failure = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_TEMPERATURE_SENSOR);
st.bits.u1.critical_nvm_failure = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_CRITICAL_NVM);
st.bits.u1.drive_current_failure = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_IP_DRIVER);
st.bits.u1.reference_voltage_failure = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_VREF);
st.bits.u1.mlfb_sensor_alarm = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_MICRO_LOOP);
st.bits.u1.flash_integrity_failure = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_FLASH_INTEGRITY);
st.bits.u2.auto_cal_in_progress_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_AUTO_CALIBRATION);
st.bits.u2.nvm_protective_mode = get_diagnosis_fault_result_of_enable_state(INDICATE_NVM_PROTECT_MODE);
st.bits.u2.pressure_fallback_active_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_PRESS_ACTIVE);
st.bits.u2.diagnostics_in_progress_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_TEST_PROGRESS);
st.bits.u2.calibration_in_progress_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_CALIBRATION);
st.bits.u2.alert_record_not_empty_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_ALERT_RECORD_NOT_EMPTY);
st.bits.u3.alert_record_full_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_ALERT_RECORD_FULL);
st.bits.u3.cycle_counter_high_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_ACT_SUM);
st.bits.u3.instrument_time_is_approximate_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_DEV_REALTIME);
st.bits.u3.non_critical_nvm_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_NON_CRITICAL_NVM);
st.bits.u3.offline_failed_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_OFFLINE);
st.bits.u3.travel_accumulator_high_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_TRAVEL_SUM);
st.bits.u4.diagnostic_data_available_alert = get_diagnosis_fault_result_of_enable_state(INDICATE_DIAG_DATA_AVAILABLE);
st.bits.u4.end_point_pressure_deviation_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_PRESS_ERROR);
st.bits.u4.integrator_saturated_high_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_UI_SATURATED_HIGH);
st.bits.u4.integrator_saturated_low_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_UI_SATURATED_LOW);
st.bits.u4.supply_pressure_high_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_SUPPLY_UPPER);
st.bits.u4.supply_pressure_low_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_SUPPLY_LOWER);
st.bits.u5.drive_signal_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_DRIVE_SIGNAL);
st.bits.u5.travel_alert_hi = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_TRAVEL_HI);
st.bits.u5.travel_alert_hi_hi = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_TRAVEL_HI_HI);
st.bits.u5.travel_alert_lo = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_TRAVEL_LO);
st.bits.u5.travel_alert_lo_lo = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_TRAVEL_LO_LO);
st.bits.u5.travel_deviation_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_TRAVEL_ERROR);
st.bits.u5.travel_limit_cutoff_hi_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_LIMIT_CUTOFF_HI);
st.bits.u5.travel_limit_cutoff_lo_alert = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_LIMIT_CUTOFF_LO);
st.bits.u6.output_circuit_error = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_OUTPUT_CIRCUIT_ERROR);
st.bits.u6.output_pressure_limiting = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_OUTPUT_PRESS_LIMIT);
osel_memcpy(rev_buf, (uint8_t *)&st, ARRAY_LEN(st.data));
}
/**
* @brief
* @return {*}
* @note
*/
static void update_device_status(void)
{
additional_device_status_t *p = &hart_device_attribute.device_status.additional_device_status;
// 设备特定状态 - 48号指令
{
hart_get_device_specific_status(p->device_specific_status);
}
// 扩展设备状态
{
diag_class_e status = get_diagnosis_fault_priority();
switch (status)
{
case DIAGNOSIS_CLASS_FAIL:
p->extended_device_status = EXTENDED_DEVICE_STATUS_4; // 设备故障
break;
case DIAGNOSIS_CLASS_SPEC:
p->extended_device_status = EXTENDED_DEVICE_STATUS_5; // 超出规格
break;
case DIAGNOSIS_CLASS_CHECK:
p->extended_device_status = EXTENDED_DEVICE_STATUS_6; // 功能检查
break;
case DIAGNOSIS_CLASS_MAINT:
p->extended_device_status = EXTENDED_DEVICE_STATUS_1; // 需要维护
break;
default:
p->extended_device_status = EXTENDED_DEVICE_STATUS_0; // 正常
break;
}
}
// 标准化状态0
{
p->standardized_status0 = STANDARDIZED_STATUS0_0;
// 非易失性存储器缺陷
BOOL eeprom_status = FALSE;
eeprom_status = fal_execution_status_get(FAL_EXECUTION_EEPROM_M95_1);
if (eeprom_status == TRUE)
{
eeprom_status = fal_execution_status_get(FAL_EXECUTION_EEPROM_M95_2);
if (eeprom_status == TRUE)
{
eeprom_status = fal_execution_status_get(FAL_EXECUTION_EEPROM_FM24);
if (eeprom_status == TRUE)
{
// TODO: eeprom_lc02b
}
}
}
if (eeprom_status == FALSE)
{
p->standardized_status0 = STANDARDIZED_STATUS0_2; // 非易失性存储器缺陷
}
// 电源条件超出范围
if (rt_data.loop_current < LOOP_CURRENT_MIN || rt_data.loop_current > LOOP_CURRENT_MAX)
{
p->standardized_status0 = STANDARDIZED_STATUS0_5; // 电源条件超出范围
}
if (hart_device_attribute.flash_variable.write_protect_code == WRITE_PROTECT_CODE_WRITE_PROTECT ||
hart_device_attribute.flash_variable.lock_code != LOCK_DEVICE_CODE_0)
{
p->standardized_status0 = STANDARDIZED_STATUS0_8; // 设备配置已锁定。设备处于写保护状态或已锁定
}
}
}

View File

@ -1,16 +1,14 @@
#ifndef __APP_HART_H__
#define __APP_HART_H__
#include "lib.h"
#include "wl_flash.h"
#include "hart.h"
#include "app_hart_user.h"
#include "app_hart_user_standard.h"
typedef enum
{
HART_FILE_MODE_DIAGNOSIS = 3, // 模式诊断
} hart_file_read_e;
#define HART_BASE_SECS (315532800U) // 1980-01-01 0:0:0
typedef enum
{
HART_TUNING_STOP = 1, // 退出
HART_TUNING_START = 3, // 开始
} hart_tuning_e;
#endif // __APP_HART_H__
extern void app_hart_update_time(void); // 更新时间
extern BOOL app_hart_storage_is_written(uint32_t address, uint16_t length); // 是否已经写入过数据只检查前200个字节
extern void hart_write_test(void); // 测试写入
#endif // __APP_HART_H__

1066
User/app_hart_user.c Normal file

File diff suppressed because it is too large Load Diff

665
User/app_hart_user.h Normal file
View File

@ -0,0 +1,665 @@
/**
* @file app_hart_user.h
* @author xxx
* @date 2024-08-06 08:17:13
* @brief HART扩展协议
* @copyright Copyright (c) 2024 by xxx, All Rights Reserved.
*/
#ifndef __APP_HART_USER_H
#define __APP_HART_USER_H
#include "lib.h"
#include "hart.h"
#include "hart_frame.h"
#include "hart_frame_user.h"
typedef enum
{
HART_STATE_COMMAND_31_FAILURE = 3, // 故障
HART_STATE_COMMAND_31_FUNCTION_CHECK = 5, // 功能检查
HART_STATE_COMMAND_31_OUT_OF_SPECIFICATION = 4, // 超出规格
HART_STATE_COMMAND_31_MAINTENANCE_REQUIRED = 1, // 需要维护
} hart_state_command_31_e;
typedef enum
{
HART_TUNING_ENTER = 0, // 校准进入
HART_TUNING_EXIT, // 校准退出
HART_RESTORE_FACTORY, // 恢复出厂
HART_TUNING_AUTO, // 自动校准
HART_TUNING_AUTO_MIN, // 小回路校准
} hart_tuning_e;
// 文件状态代码
typedef enum
{
FILE_STATUS_NOT_READ_WRITE = 1, // 不可读
FILE_STATUS_READ_ONLY = 2, // 只读
FILE_STATUS_WRITE_ONLY = 3, // 只写
FILE_STATUS_READ_WRITE = 4, // 可读可写
} file_status_e;
// 制造信息
typedef enum
{
HART_MAN_INFO = 0, // 制造信息
HART_MAN_SCHEME = 1, // 制造方案
} hart_man_info_e;
// 诊断类型
typedef enum
{
DIAG_TYPE_OFFLINE_COMMANDED = 0, // 离线命令:表示诊断是在设备离线状态下由用户或系统命令触发的
DIAG_TYPE_OFFLINE_PTCWITH_CUTOFFS, // 离线PTC带截止表示诊断是在离线状态下进行并且带有特定的截止条件
DIAG_TYPE_OFFLINE_PTCWITHOUT_CUTOFFS, // 离线PTC无截止表示诊断是在离线状态下进行但不包含特定的截止条件
DIAG_TYPE_PROCESS, // 过程诊断:表示诊断是在设备的正常运行过程中进行的
DIAG_TYPE_OFFLINE_SCRIPTED, // 离线脚本:表示诊断是通过执行预定的脚本在离线状态下触发的
DIAG_TYPE_ONLINE_COMMANDED = 5, // 在线命令:表示诊断是在设备在线状态下由用户或系统命令触发的
DIAG_TYPE_ONLINE_TRAVEL_TRIGGERED, // 在线行程触发:表示诊断是在设备在线状态下,由设备的某种行程(如移动距离)触发的
DIAG_TYPE_ONLINE_AUX_TRIGGERED, // 在线辅助触发:表示诊断是在设备在线状态下,由某种辅助设备或信号触发的
DIAG_TYPE_SOVTEST = 13 // SOV测试可能表示对某种安全输出阀Safety Output Valve的测试
} diag_type_e;
#pragma pack(1)
// 133-读取文件信息
typedef struct
{
uint16_t readwrite_bytes; // 读写字节个数
uint16_t max_bytes; // 最大字节数
uint8_t write_access_control; // 写访问控制
} hart_read_file_information_t; // 命令133响应数据
// 138-读取其他状态
typedef union
{
uint8_t data[7];
struct
{
struct
{
uint8_t stem_position_sensor_fail : 1; // 行程传感器故障
uint8_t pressure_sensor_fail : 1; // 压力传感器故障
uint8_t temp_sensor_fail : 1; // 温度传感器故障
uint8_t nvm_alert : 1; // NVM警报
uint8_t drive_current_fail : 1; // 驱动电流故障
uint8_t ref_voltage_fail_and_ram_fail : 1; // 参考电压故障和RAM故障 2个变量共用一个bit
uint8_t mlfb_sensor_fail_and_no_free_time : 1; // 小回路传感器故障和无空闲时间 2个变量共用一个bit
uint8_t flash_crc_error : 1; // 闪存CRC错误
} hard_failures;
struct
{
uint8_t auto_cal_in_progress6k_and_auto_tune_in_progress6k : 1; // 自动校准进行中和自动整定进行中 2个变量共用一个bit
uint8_t nvm_protective_mode_and_input_char_selected : 1; // NVM保护模式和输入特性选择 2个变量共用一个bit
uint8_t program_flow_and_set_point_char_selected : 1; // 程序流程和设定点特性选择 2个变量共用一个bit
uint8_t press_fallback_and_alternate_servo_range : 1; // 压力回退和备用伺服范围 2个变量共用一个bit
uint8_t diag_in_progress : 1; // 诊断进行中
uint8_t cal_in_progress : 1; // 校准进行中
uint8_t lcpdemand_and_auto_tune_in_progress2k_and_servo_dynamic_bypass : 1; // LCP本地控制面板需求、自动调谐进行中、伺服动态旁路 3个变量共用一个bit
uint8_t aernot_empty_and_auto_cal_in_progress : 1; // 报警记录不为空和自动校准进行中 2个变量共用一个bit
} status_integ_1;
struct
{
uint8_t aux_alarm_alert : 1; // 辅助报警警报
uint8_t offline_or_failed : 1; // 离线或失败
uint8_t aeris_full_and_burst_comm_timeout : 1; // 报警记录满和突发通信超时 2个变量共用一个bit
uint8_t time_invalid_and_friction_alert : 1; // 时间无效和摩擦警报 2个变量共用一个bit
uint8_t accumulator_alert : 1; // 累加器警报
uint8_t cycle_counter_alert : 1; // 周期计数器警报
uint8_t non_critical_nvm_alert : 1; // 非关键NVM警报
uint8_t multidrop_and_sisoverride_fail_and_pid_auto_tune_in_progress : 1; // 多点通信、SIS安全仪表系统覆盖失败、PID 自动调谐进行中 3个变量共用一个bit
} status_integ_2;
struct
{
uint8_t integrator_saturated_lo_and_loop_arwlo : 1; // 积分饱和低和回路低 2个变量共用一个bit
uint8_t integrator_saturated_hi_and_loop_arwhi : 1; // 积分饱和高和回路高 2个变量共用一个bit
uint8_t low_power : 1; // 低功耗
uint8_t locked_in_safety : 1; // 安全锁定
uint8_t press_dev : 1; // 压力偏差
uint8_t supply_pressure : 1; // 供应压力
uint8_t valve_stuck : 1; // 阀门卡住
uint8_t is_diag_data_in_diag_buffer : 1; // 诊断数据在诊断缓冲区
} alarm_1;
struct
{
uint8_t output_bad : 1; // 输出故障
uint8_t loop_set_point_lo : 1; // 回路设定点低
uint8_t loop_set_point_hi : 1; // 回路设定点高
uint8_t loop_deviation : 1; // 回路偏差
uint8_t loop_feedback_hi_hi : 1; // 回路反馈高点高
uint8_t loop_feedback_hi : 1; // 回路反馈高
uint8_t loop_feedback_lo_lo : 1; // 回路反馈低点低
uint8_t loop_feedback_lo : 1; // 回路反馈低
} alarm_2;
struct
{
uint8_t limit_switch1closed : 1; // 限位开关1关闭
uint8_t limit_switch2closed : 1; // 限位开关2关闭
uint8_t option_module_error : 1; // 选项模块错误
uint8_t lcpcomm : 1; // LCP通信
} status;
struct
{
uint8_t maint_required : 1; // 需要维护
uint8_t dev_var_out_of_range : 1; // 设备变量超出范围
uint8_t power_critically_low : 1; // 电源严重不足
uint8_t ne107failure : 1; // NE107故障
uint8_t ne107out_of_spec : 1; // NE107超出规格
uint8_t ne107function_check : 1; // NE107功能检查
} extended_status;
} bits;
} hart_other_status_u;
// 140-读取触发器定义的内容
typedef struct
{
uint16_t start_addr; // 触发器起始地址
uint8_t trigger_type; // 诊断类型类型
uint8_t variable_1; // 变量1
uint8_t variable_2; // 变量2
uint8_t variable_3; // 变量3
uint8_t variable_4; // 变量4
uint8_t acquisition_time; // 采集时间
uint16_t data_points; // 数据点数
uint8_t trigger_enable; // 触发器事件
uint32_t unknow; // 未知
} hart_read_trigger_definition_t;
// 146-读取标准跨度信息
typedef struct
{
uint16_t upper_limit_of_span; // 标准跨度上限
uint16_t lower_limit_of_span; // 标准跨度下限
uint16_t flash_address; // 非易失性存储器地址
uint16_t download_address; // 下载状态地址
} hart_standard_span_information_t;
// 155-执行诊断
typedef struct
{
uint8_t diag_type; // 诊断类型 见diag_type_e
uint8_t undefine[HART_PACKED4_LEN]; // 不处理
uint8_t variable_code[HART_PACKED4_LEN]; // 设备变量和HART中的设备变量有关系
uint8_t sampling_time; // 采样时间 sampling_time*12.5ms
uint16_t target; // 目标行程 (target-2048)/8192
uint16_t ramp; // 斜率
uint16_t points; // 总数据点
} hart_diagnosis_t;
// 158-在线诊断测试
typedef struct
{
uint8_t diag_type; // 诊断类型 diag_type_e
uint8_t v1; // 变量1
uint8_t v2; // 变量2
uint8_t v3; // 变量3
uint8_t v4; // 变量4
uint8_t collection_time; // 采集时间
uint16_t total_data_points; // 总数据点
} mode_diagnosis_test_t;
#pragma pack(1)
// 规格表数据
typedef struct
{
uint8_t ss2_ver; // 版本
uint8_t ss2_u_travel; // 行程
uint8_t ss2_u_length; // 长度单位
uint8_t ss2_u_area; // 区域单位
uint8_t ss2_u_torque; // 扭矩单位
uint8_t ss2_u_springrate; // 弹簧力
uint32_t ss2_v_manuf; // 制造商
uint16_t ss2_v_model; // 型号
uint16_t ss2_v_size; // 阀门尺寸
uint8_t ss2_v_class; // 阀门类型
float32_t ss2_v_rated_travel; // 阀门额定行程
float32_t ss2_v_actual_travel; // 阀门实际行程
float32_t ss2_v_stem_size; // 阀杆直径
uint8_t ss2_v_packing; // 阀门填料类型
float32_t ss2_v_inlet_press; // 阀门入口压力
float32_t ss2_v_outlet_press; // 阀门出口压力
float32_t ss2_v_dyn_torque; // 阀门动态扭矩
float32_t ss2_v_breakout_torque; // 阀门突破扭矩
uint8_t ss2_t_seat_type; // 修整座类型
uint8_t ss2_t_class; // 修整泄漏等级
float32_t ss2_t_port_diam; // 修整端口直径
uint8_t ss2_t_port_type_ss2_t_flow_dir_ss2_t_pdt_ss2_t_ftt; // 修整端口类型
float32_t ss2_t_unbal_area; // 修整不平衡面积
uint32_t ss2_a_manuf; // 执行器制造商
uint16_t ss2_a_model; // 执行器型号
uint16_t ss2_a_size; // 执行器尺寸
float32_t ss2_a_eff_area; // 执行器有效面积
uint8_t ss2_a_air; // 执行器空气
uint8_t ss2_a_lever_style; // 执行器杠杆样式
float32_t ss2_a_bench_lo; // 执行器下限设置
float32_t ss2_a_bench_hi; // 执行器上限设置
float32_t ss2_a_nom_press; // 执行器额定供应压力
float32_t ss2_a_springrate; // 执行器弹簧率
float32_t ss2_a_lever_arm_length; // 执行器杠杆臂长度
uint8_t ss2_acc_vol_booster_ss2_acc_quick_rel; // 执行器体积助推器快速释放
uint8_t ss2_acc_sol_valve; // 执行器电磁阀
uint8_t ss2_acc_pos_xmtr; // 执行器位置发射器
uint8_t ss2_acc_lim_sw_open_ss2_acc_lim_sw_closed; // 执行器限位开关,阀门打开限位开关,阀门关闭
uint8_t ss2_t_trim1; // 修整样式
uint8_t reserve_1[26]; // 保留
uint8_t ss2_t_trim1_str[20]; // 其他修整样式
uint8_t ss2_v_manuf_str[20]; // 其他阀门制造商
uint8_t ss2_v_model_str[20]; // 其他阀门型号
uint8_t ss2_v_size_str[20]; // 其他阀门尺寸
uint8_t ss2_v_class_str[20]; // 其他阀门等级
uint8_t ss2_v_packing_str[20]; // 其他阀门填料
uint8_t ss2_t_seat_type_str[20]; // 其他座类型
uint8_t ss2_a_manuf_str[20]; // 其他执行器制造商
uint8_t ss2_a_model_str[20]; // 其他执行器型号
uint8_t ss2_a_size_str[20]; // 其他执行器尺寸
uint8_t ss2_a_lever_style_str[20]; // 其他杠杆样式
uint8_t ss2_acc_vol_booster_str[20]; // 其他体积助推器
uint8_t ss2_acc_quick_rel_str[20]; // 其他快速释放
uint8_t ss2_acc_sol_valve_str[20]; // 其他电磁阀
uint8_t ss2_acc_pos_xmtr_str[20]; // 其他位置发射器
uint8_t ss2_acc_lim_sw_open_str[20]; // 其他限位开关 - 阀门打开
uint8_t ss2_acc_lim_sw_closed_str[20]; // 其他限位开关 - 阀门关闭
uint8_t reserve_2[40]; // 保留
float32_t ss2_v_rated_pressure; // 阀门公称压力
float32_t ss2_a_rangemax_spring; // 执行机构-弹簧最大值
float32_t ss2_a_rangemin_spring; // 执行机构-弹簧最小值
float32_t ss2_v_nominal_diameter; // 阀门公称通径
} specification_table_data_t;
#pragma pack()
// D-31 扩展指令(压缩状态映射)
typedef union
{
uint8_t data[27];
struct
{
union
{
uint8_t csm_loop_current : 4; // 回路电流校准警报
uint8_t reserved : 4; // 保留
} u1;
uint8_t csm_reserved_2; // 保留
uint8_t csm_reserved_3; // 保留
union
{
uint8_t csm_travel_sensor : 4; // 行程传感器故障
uint8_t reserved : 4; // 保留
} u4;
union
{
uint8_t csm_temp_sensor : 4; // 温度传感器故障
uint8_t csm_critical_nvm : 4; // 关键NVM故障
} u5;
union
{
uint8_t csm_drive_current : 4; // 驱动电流故障
uint8_t csm_refvolt_fail : 4; // 参考电压故障
} u6;
union
{
uint8_t csm_mlfb_fail : 4; // 小回路传感器故障
uint8_t csm_flash_fail : 4; // Flash完整性故障
} u7;
union
{
uint8_t csm_autocal_in_prog : 4; // 正在自动行程校准
uint8_t reserved : 4; // 保留
} u8;
union
{
uint8_t csm_program_flow_fail : 4; // 程序流程故障
uint8_t csm_press_fallback : 4; // 压力回退激活
} u9;
union
{
uint8_t csm_diag_in_prog : 4; // 诊断正在进行
uint8_t csm_cal_in_prog : 4; // 校准正在进行
} u10;
union
{
uint8_t csm_lcp_trip : 4; // 未知
uint8_t csm_aer_not_empty : 4; // 报警记录不为空
} u11;
union
{
uint8_t csm_sis_stroke : 4; // 未知
uint8_t csm_offline_fail : 4; // 停机激活
} u12;
union
{
uint8_t csm_aer_full : 4; // 报警记录满
uint8_t csm_time_inval : 4; // 未知
} u13;
union
{
uint8_t csm_travel_accum : 4; // 行程累计上限
uint8_t csm_cycle_counter : 4; // 周期计数上限
} u14;
union
{
uint8_t csm_noncritical_nvm : 4; // 非关键NVM故障
uint8_t csm_hardware_shutdown_fail : 4; // 未知
} u15;
union
{
uint8_t csm_integ_low : 4; // 积分饱和低
uint8_t csm_integ_high : 4; // 积分饱和高
} u16;
union
{
uint8_t csm_supply_press_hi : 4; // 供应压力高
uint8_t csm_locked_in_safety : 4; // 未知
} u17;
union
{
uint8_t csm_press_dev : 4; // 压力偏差
uint8_t csm_supply_press_lo : 4; // 供应压力低
} u18;
union
{
uint8_t csm_pst_abnormal : 4; // 未知
uint8_t csm_diag_data_avail : 4; // 诊断数据可用
} u19;
union
{
uint8_t csm_drive_signal : 4; // 驱动信号
uint8_t csm_lo_limit : 4; // 行程低切割点
} u20;
union
{
uint8_t csm_hi_limit : 4; // 行程高切割点
uint8_t csm_travel_dev : 4; // 行程偏差
} u21;
union
{
uint8_t csm_travel_hihi : 4; // 行程上限高
uint8_t csm_travel_hi : 4; // 行程上限
} u22;
union
{
uint8_t csm_travel_lolo : 4; // 行程下限低
uint8_t csm_travel_lo : 4; // 行程下限
} u23;
union
{
uint8_t reserved : 4; // 保留
uint8_t csm_porta : 4; // 未知
} u24;
union
{
uint8_t csm_output_circuit : 4; // 未知
uint8_t csm_lcp_comm : 4; // 未知
} u25;
union
{
uint8_t csm_lcp_stuck : 4; // 未知
uint8_t reserved : 4; // 保留
} u26;
union
{
uint8_t csm_pst_prohibit : 4; // 未知
uint8_t csm_pst_pass : 4; // 未知
} u27;
} bits;
} hart_condensed_status_map_u;
// 48-设备特定状态
typedef union
{
uint8_t data[HART_PACKED6_LEN];
struct
{
struct
{
/**
25.0%125.0%
*/
uint8_t travel_sensor_failure : 1; // 行程传感器故障
/**
24.0%125.0%60
*/
uint8_t pressure_sensor_failure : 1; // 压力传感器故障
/**
60°100°C76°212°F
*/
uint8_t temperature_sensor_failure : 1; // 温度传感器故障
/**
*/
uint8_t critical_nvm_failure : 1; // 临界NVM故障
/**
*/
uint8_t drive_current_failure : 1; // 驱动器电流故障
/**
*/
uint8_t reference_voltage_failure : 1; // 参考电压故障
/**
*/
uint8_t mlfb_sensor_alarm : 1; // 小回路传感器警报
/**
ROM
*/
uint8_t flash_integrity_failure : 1; // 闪存完整性失故障
} u1;
struct
{
/**
*/
uint8_t auto_cal_in_progress_alert : 1; // 自动校准正在进行警报
/**
NVM写入NVM被拒绝NVM磨损
*/
uint8_t nvm_protective_mode : 1; // NVM保护模式
uint8_t reserved_1 : 1; // 保留
/**
I/P变换器一样控制输出时激活
*/
uint8_t pressure_fallback_active_alert : 1; // 压力回退激活警报
/**
*/
uint8_t diagnostics_in_progress_alert : 1; // 诊断正在进行警报
/**
*/
uint8_t calibration_in_progress_alert : 1; // 校准正在进行警报
uint8_t reserved_2 : 1; // 保留
/**
1
*/
uint8_t alert_record_not_empty_alert : 1; // 警报记录不为空警报
} u2;
struct
{
uint8_t reserved_1 : 1; // 保留
/**
使DVC6200处于失败状态
*/
uint8_t offline_failed_alert : 1; // 设备处于离线状态警报
/**
20
*/
uint8_t alert_record_full_alert : 1; // 警报记录满警报
/**
*/
uint8_t instrument_time_is_approximate_alert : 1; // 仪器时间不准确警报
/**
*/
uint8_t travel_accumulator_high_alert : 1; // 行程累计器高警报
/**
*/
uint8_t cycle_counter_high_alert : 1; // 周期计数器高警报
/**
*/
uint8_t non_critical_nvm_alert : 1; // 非关键NVM警报
uint8_t reserved_2 : 1; // 保留
} u3;
struct
{
/**
*/
uint8_t integrator_saturated_low_alert : 1; // 积分饱和低警报
/**
*/
uint8_t integrator_saturated_high_alert : 1; // 积分饱和高警报
/**
*/
uint8_t supply_pressure_high_alert : 1; // 供应压力高警报
uint8_t reserved_1 : 1; // 保留
/**
*/
uint8_t end_point_pressure_deviation_alert : 1; // 压力偏差警报
/**
*/
uint8_t supply_pressure_low_alert : 1; // 供应压力低警报
uint8_t reserved_2 : 1; // 保留
/**
*/
uint8_t diagnostic_data_available_alert : 1; // 诊断数据可用警报
} u4;
struct
{
/**
<10%>90%20
*/
uint8_t drive_signal_alert : 1; // 驱动信号警报
/**
Lo Limit/Cutoff Point时激活
*/
uint8_t travel_limit_cutoff_lo_alert : 1; // 行程低切割点警报
/**
Hi Limit/Cutoff Point时激活
*/
uint8_t travel_limit_cutoff_hi_alert : 1; // 行程高切割点警报
/**
*/
uint8_t travel_deviation_alert : 1; // 行程偏差警报
/**
Hi Hi Point时激活
*/
uint8_t travel_alert_hi_hi : 1; // 行程上限高警报
/**
Hi Point时激活
*/
uint8_t travel_alert_hi : 1; // 行程上限警报
/**
Lo Lo Point时激活
*/
uint8_t travel_alert_lo_lo : 1; // 行程下限低警报
/**
Lo Point时激活
*/
uint8_t travel_alert_lo : 1; // 行程下限警报
} u5;
struct
{
uint8_t reserved_1 : 1; // 保留
/**
A超过配置的限制
*/
uint8_t output_pressure_limiting : 1; // 输出压力限制
/**
*/
uint8_t output_circuit_error : 1; // 输出电路错误
uint8_t reserved : 5; // 保留
} u6;
} bits;
} hart_device_specific_status_u;
// 156
typedef union
{
uint8_t data;
union
{
uint8_t is_in_diagnosis : 1; // 是否在诊断中
uint8_t trigger_status : 1; // 触发器状态
uint8_t data_compression_enabled : 1; // 数据压缩开启
uint8_t diag_type : 5; // 诊断类型
} bits;
} diagnosis_state_u;
#pragma pack()
extern specification_table_data_t spec_table_data;
extern BOOL hart_user_handle(hart_interface_user_event_e event, const void *const data); ///< HART user event handler
#endif // __APP_HART_USER_H

View File

@ -0,0 +1,5 @@
#include "app_hart_user_standard.h"
BOOL hart_user_standard_handle(hart_interface_user_event_e event, const void *const data)
{
return TRUE;
}

View File

@ -0,0 +1,15 @@
/**
* @file app_hart_user_standard.h
* @author xxx
* @date 2024-08-06 08:22:30
* @brief HART扩展协议()
* @copyright Copyright (c) 2024 by xxx, All Rights Reserved.
*/
#ifndef __APP_HART_USER_STANDARD_H
#define __APP_HART_USER_STANDARD_H
#include "lib.h"
#include "hart.h"
#include "hart_frame.h"
#include "hart_frame_user.h"
extern BOOL hart_user_standard_handle(hart_interface_user_event_e event, const void *const data); ///< HART user standard event handler
#endif // __APP_HART_USER_STANDARD_H

View File

@ -0,0 +1,57 @@
#ifndef __ATBLUETOOTH_H__
#define __ATBLUETOOTH_H__
#include "stdio.h"
#include "string.h"
#include "data_type_def.h"
#include "osel_arch.h"
#define BLE_TYPE_HC42 0 ///< HC42蓝牙模块
#define BLE_TYPE_MX02 1 ///< MX02蓝牙模块
#define BLE_TYPE BLE_TYPE_MX02 // 蓝牙模块类型
#define AT_SUCCESS (0) /* 指令正常 */
#define AT_ERR (1) /* 指令异常 */
#define AT_ERR_UNINVAIL (2) /* 没有对应指令 */
#define AT_ERR_FUN_UNUSED (3) /* 没有可执行函数 */
#define ROBOT_DEBUG
#ifdef ROBOT_DEBUG
#define AT_DEBUG_INFO(format, ...) printf(format, ##__VA_ARGS__)
#else
#define AT_DEBUG_INFO(format, ...)
#endif
typedef unsigned char (*pFunc)(unsigned char *ptr, unsigned char len);
typedef enum
{
AT_CMD_TEST = 0, /* 测试指令 */
AT_CMD_NAME_REQ, /* 查询名称 */
AT_CMD_NAME, /* 设置名称 */
AT_CMD_DISA, /* 断开当前连接 */
AT_CMD_TX_POWER, /* 设置发送功率 */
AT_CMD_ADV_INTERVAL, /* 设置广播间隔 */
AT_CMD_CON_INTERVAL, /* 设置连接间隔 */
AT_CMD_ADV_ONOFF, /* 设置打开、关闭广播 */
AT_GET_VER, /* 获取版本号 */
AT_GET_CON_STATE, /* 获取连接状态 */
AT_CMD_UART_CFG, /* 配置UART参数 */
AT_CMD_READY, /* 模块准备就绪 */
AT_END
} at_cmd_e;
typedef struct
{
at_cmd_e cmd; /* 指令序号 */
char *str; /* 指令内容 */
pFunc cb; /* 指令执行 */
} at_cmd_func_t;
/* 返回值参数内容如上, p-指向解析的指令len-解析指令长度 */
unsigned char at_cmd_parse(unsigned char *p, unsigned char len);
void at_set_memcmp_cache(unsigned char *p, unsigned char len);
extern unsigned char bluetooth_state;
#endif // __ATBLUETOOTH_H__

View File

@ -12,21 +12,33 @@
#include "main.h"
#include "entity.h"
extern void dev_serial_number_to_string(char *s, uint8_t *sn, uint8_t len, uint8_t interval, char *fix); // 16进制转ASCII字符串
extern void hart_long_address_to_string(char *s, uint8_t *sn, uint8_t len); // HART长地址转字符串
extern float32 i2psb(float32 in); // 输入电流转换成需要控制的阀门开度
extern float32 temperature_c2f(float32 celsius); // 温度值转换:摄氏度转华氏度
extern float32 pressure_kpa2unit(float32 kpa, uint16_t unit); // 压力值转换
#define CURRENT_PERCENT(x) ((x - LOOP_CURRENT_MIN) / (LOOP_CURRENT_MAX - LOOP_CURRENT_MIN)) ///> 电流百分比
extern float32 small_signal_deal(float32 in); // 小信号切除处理
extern float32 dead_zone_deal(float32 in); // 死区处理
extern float32 part_travel_deal(float32 in); // 分程处理
extern void pwm_output_deal(float32 in); // PWM输出处理
extern void swo_output_deal(float32 in); // SWO输出处理
extern float32 target_travel_deal(float32 in); // 目标行程处理
extern float32 actual_travel_deal(float32 in); // 实际行程处理
extern float32 get_show_travel(float32 in); // 获取显示行程
extern float32 get_pid_travel(float32 in); // 获取PID控制行程
extern void get_pressure_unit(char *s, uint16_t unit); // 获取压力单位
extern float32 pressure_adc_to_percent(uint16_t psi_adc); // 压力转百分比
#endif // __CONVERT_H__
extern void calib_param_calculate(calibration_e index, int16_t offset, int16_t span, float32 min, float32 max); // 校准参数计算
extern float32 adc_linear_conversion(calibration_e index, uint16_t adc); // AD值线性转换
extern void dev_serial_number_to_string(char *s, uint8_t *sn, uint8_t len, uint8_t interval, char *fix); // 16进制转ASCII字符串
extern void hart_long_address_to_string(char *s, uint8_t *sn, uint8_t len); // HART长地址转字符串
extern float32 i2psb(float32 in); // 输入电流转换成需要控制的阀门开度
extern float32 temperature_c2unit(float32 in, uint16_t unit); // 温度值转换:摄氏度转华氏度
extern float32 pressure_unit2kpa(float32 in, uint16_t unit); // 压力单位转换,单位转kPa
extern float32 pressure_kpa2unit(float32 kpa, uint16_t unit); // 压力值转换, kPa转单位
extern uint32_t dev_serial_num_deal(void); // 设备序列号处理
extern float32 small_signal_deal(float32 in); // 小信号切除处理
extern float32 dead_zone_deal(float32 in); // 死区处理
extern float32 part_travel_deal(float32 in); // 分程处理
extern void pwm_output_deal(float32 in); // PWM输出处理
extern void swo_output_deal(float32 in); // SWO输出处理
extern float32 target_travel_deal(float32 in); // 目标行程处理
extern void actual_travel_deal(float32 in); // 实际行程处理
extern float32 get_show_actual_travel(float32 tag, float32 cur, float32 err); // 获取显示实际行程
extern float32 get_show_travel(float32 in); // 获取显示行程
extern float32 get_pid_travel(float32 in); // 获取PID控制行程
extern void get_pressure_unit(char *s, uint16_t unit); // 获取压力单位
extern BOOL pressure_unit_need_decimal_display(uint16_t unit); // 压力单位是否需要小数显示
extern float32 voltage2pressure(float32 voltage_ad); // 电压转压力
extern float32 get_pressure_limit_deal(float32 in, uint16_t unit); // 获取压力限制处理
extern float32 pressure_to_percent(float32 pressure); // 压力转百分比
extern BOOL is_double_acting(void); // 是否双作用
extern void last_tuned_state_update(void); // 上次整定状态更新
#endif // __CONVERT_H__

View File

@ -9,118 +9,143 @@
#define __DIAGNOSIS_H__
#include "lib.h"
#include "entity.h"
#define DIAGNOSIS_ALARM_TIME_SEC 5U // 防误判秒数
// 诊断等级
typedef enum
{
DIAGNOSIS_CLASS_FAIL = 0, // 设备故障
DIAGNOSIS_CLASS_SPEC, // 超出规格
DIAGNOSIS_CLASS_CHECK, // 功能检查
DIAGNOSIS_CLASS_MAINT, // 请求维护
DIAGNOSIS_CLASS_CHECK, // 功能检查
DIAGNOSIS_CLASS_NONE, // 未使用的
DIAGNOSIS_CLASS_OK, // 诊断正常
} diag_class_e;
#define DIAG_FAULT_CLASS_NUM DIAGNOSIS_CLASS_OK
#define DIAG_CLASS_NUM DIAGNOSIS_CLASS_OK
// 设备故障诊断
/* 注意:新增某个级别的诊断项目时,必须在该级别的后面添加,不能在前面添加 */
typedef enum
{
DIAGNOSIS_VREF = 0, ///< 基准电压诊断 => 供电系统故障
DIAGNOSIS_INPUT_UPPER, ///< 输入电流上限诊断 => 驱动电流报警
DIAGNOSIS_INPUT_LOWER, ///< 输入电流下限诊断
DIAGNOSIS_IP_DRIVER, ///< I/P驱动诊断
DIAGNOSIS_EEPROM_M95_1, ///< 存储器诊断 M95_1
DIAGNOSIS_EEPROM_M95_2, ///< 存储器诊断 M95_1
DIAGNOSIS_EEPROM_FM24, ///< 存储器诊断 FM24
DIAGNOSIS_EEPROM_LC02, ///< 存储器诊断 LC02
DIAGNOSIS_RTC, ///< RTC诊断
DIAGNOSIS_MAGNET, ///< 磁条诊断
DIAGNOSIS_MICRO_LOOP, ///< 小回路诊断
DIAGNOSIS_PRESS_SENSOR_S, ///< 压力传感器S诊断 => 气源压力传感器故障
DIAGNOSIS_PRESS_SENSOR_A, ///< 压力传感器A诊断 => 阀口A压力传感器故障
DIAGNOSIS_PRESS_SENSOR_B, ///< 压力传感器B诊断 => 阀口B压力传感器故障
DIAGNOSIS_FAIL_MAX,
} diag_fail_e;
/****************************************** DIAGNOSIS_CLASS_FAIL *********************************************/
DIAGNOSIS_VREF = 0, ///< 基准电压诊断 => reference_voltage_failure
DIAGNOSIS_INPUT, ///< 输入电流诊断
DIAGNOSIS_IP_DRIVER, ///< I/P驱动诊断 => drive_current_failure
DIAGNOSIS_EEPROM_M95_1, ///< 存储器诊断 critical_nvm_failure
DIAGNOSIS_EEPROM_M95_2, ///< 存储器诊断 non_critical_nvm_alert
DIAGNOSIS_EEPROM_FM24, ///< 存储器诊断 critical_nvm_failure
DIAGNOSIS_EEPROM_LC02, ///< 存储器诊断 critical_nvm_failure
DIAGNOSIS_CRITICAL_NVM, ///< 主要存储器诊断 => critical_nvm_failure
DIAGNOSIS_NON_CRITICAL_NVM, ///< 次要存储器诊断 => non_critical_nvm_alert
DIAGNOSIS_RTC, ///< RTC诊断
DIAGNOSIS_MAGNET, ///< 磁条诊断 => travel_sensor_failure
DIAGNOSIS_MICRO_LOOP, ///< 小回路诊断 => mlfb_sensor_alarm
DIAGNOSIS_PRESS_SENSOR_S, ///< 压力传感器S诊断
DIAGNOSIS_PRESS_SENSOR_A, ///< 压力传感器A诊断
DIAGNOSIS_PRESS_SENSOR_B, ///< 压力传感器B诊断
DIAGNOSIS_PRESS_SENSOR, ///< 压力传感器诊断 => pressure_sensor_failure
DIAGNOSIS_TEMPERATURE_SENSOR, ///< 温度传感器诊断 => temperature_sensor_failure
DIAGNOSIS_FLASH_INTEGRITY, ///< FLASH相关诊断 => flash_integrity_failure
DIAGNOSIS_DRIVE_SIGNAL, ///< 驱动信号诊断 => drive_signal_alert
DIAGNOSIS_OUTPUT_CIRCUIT_ERROR, ///< 输出电路诊断 => output_circuit_error
// 超出规格诊断
typedef enum
{
DIAGNOSIS_TEMPERATURE_UPPER = 0, ///< 温度上限诊断
DIAGNOSIS_TEMPERATURE_LOWER, ///< 温度下限诊断
DIAGNOSIS_SUPPLY_UPPER, ///< 气源压力上限诊断
DIAGNOSIS_SUPPLY_LOWER, ///< 气源压力下限诊断
DIAGNOSIS_SUPPLY_ERROR, ///< 气源压力偏差诊断
DIAGNOSIS_FRICTION_UPPER, ///< 摩擦力上限诊断
DIAGNOSIS_FRICTION_LOWER, ///< 摩擦力下限诊断
DIAGNOSIS_ELASTICITY_UPPER, ///< 弹簧力上限诊断
DIAGNOSIS_ELASTICITY_LOWER, ///< 弹簧力下限诊断
DIAGNOSIS_TRAVEL_UPPER, ///< 行程上限诊断
DIAGNOSIS_TRAVEL_LOWER, ///< 行程下限诊断
DIAGNOSIS_TRAVEL_ERROR, ///< 行程偏差诊断
DIAGNOSIS_SPEC_MAX,
} diag_spec_e;
/****************************************** DIAGNOSIS_CLASS_SPEC *********************************************/
DIAGNOSIS_TEMPERATURE_UPPER, ///< 温度上限诊断
DIAGNOSIS_TEMPERATURE_LOWER, ///< 温度下限诊断
DIAGNOSIS_SUPPLY_UPPER, ///< 气源压力上限诊断 => supply_pressure_high_alert
DIAGNOSIS_SUPPLY_LOWER, ///< 气源压力下限诊断 => supply_pressure_low_alert
DIAGNOSIS_FRICTION_UPPER, ///< 摩擦力上限诊断
DIAGNOSIS_FRICTION_LOWER, ///< 摩擦力下限诊断
DIAGNOSIS_ELASTICITY_UPPER, ///< 弹簧力上限诊断
DIAGNOSIS_ELASTICITY_LOWER, ///< 弹簧力下限诊断
DIAGNOSIS_TRAVEL_HI, ///< 行程上限诊断 => travel_alert_hi
DIAGNOSIS_TRAVEL_LO, ///< 行程下限诊断 => travel_alert_lo
DIAGNOSIS_TRAVEL_HI_HI, ///< 行程上限过高诊断 => travel_alert_hi_hi
DIAGNOSIS_TRAVEL_LO_LO, ///< 行程下限过低诊断 => travel_alert_lo_lo
DIAGNOSIS_TRAVEL_ERROR, ///< 行程偏差诊断 => travel_deviation_alert
DIAGNOSIS_OUTPUT_PRESS_LIMIT, ///< 输出压力限制诊断 => output_pressure_limiting
DIAGNOSIS_PRESS_ERROR, ///< 压力偏差诊断 => end_point_pressure_deviation_alert
DIAGNOSIS_UI_SATURATED_LOW, ///< 积分饱和下限诊断 => integrator_saturated_low_alert
DIAGNOSIS_UI_SATURATED_HIGH, ///< 积分饱和上限诊断 => integrator_saturated_high_alert
DIAGNOSIS_LIMIT_CUTOFF_LO, ///< 切割点下限诊断 => travel_limit_cutoff_lo_alert
DIAGNOSIS_LIMIT_CUTOFF_HI, ///< 切割点上限诊断 => travel_limit_cutoff_hi_alert
// 功能检查诊断
typedef enum
{
DIAGNOSIS_DRIVER_SWO1 = 0, ///< SWO1诊断
DIAGNOSIS_DRIVER_SWO2, ///< SW O2诊断
DIAGNOSIS_DRIVER_OUTPUT, ///< 4~20ma输出诊断
DIAGNOSIS_CHECK_MAX,
} diag_check_e;
/****************************************** DIAGNOSIS_CLASS_MAINT *********************************************/
INDICATE_AUTO_CALIBRATION, ///< 自动校准正在进行指示 => auto_cal_in_progress_alert
INDICATE_PRESS_ACTIVE, ///< 切换压力控制指示 => pressure_fallback_active_alert
INDICATE_TEST_PROGRESS, ///< 诊断测试正在进行指示 => diagnostics_in_progress_alert
INDICATE_CALIBRATION, ///< 校准正在进行指示 => calibration_in_progress_alert
INDICATE_ALERT_RECORD_NOT_EMPTY, ///< 报警记录不为空指示 => alert_record_not_empty_alert
INDICATE_ALERT_RECORD_FULL, ///< 报警记录已满指示 => alert_record_full_alert
INDICATE_OFFLINE, ///< 离线状态指示 => offline_failed_alert
INDICATE_NVM_PROTECT_MODE, ///< 存储器空间耗尽保护指示 => nvm_protective_mode
INDICATE_DIAG_DATA_AVAILABLE, ///< 诊断数据可用指示 => diagnostic_data_available_alert
// 请求维护诊断
typedef enum
{
DIAGNOSIS_CPU_USAGE = 0, ///< CPU使用率诊断
DIAGNOSIS_MEM_USAGE, ///< 内存使用率诊断
DIAGNOSIS_TRAVEL_SUM, ///< 行程累计诊断
DIAGNOSIS_ACT_SUM, ///< 动作次数诊断
DIAGNOSIS_DEV_REALTIME, ///< 设备时间诊断
DIAGNOSIS_MAINT_MAX,
} diag_maint_e;
/****************************************** DIAGNOSIS_CLASS_CHECK *********************************************/
DIAGNOSIS_CPU_USAGE, ///< CPU使用率诊断
DIAGNOSIS_MEM_USAGE, ///< 内存使用率诊断
DIAGNOSIS_TRAVEL_SUM, ///< 行程累计诊断 => travel_accumulator_high_alert
DIAGNOSIS_ACT_SUM, ///< 动作次数诊断 => cycle_counter_high_alert
DIAGNOSIS_DEV_REALTIME, ///< 设备时间诊断 => instrument_time_is_approximate_alert
// 诊断信息
typedef struct
{
uint8_t diag_state; // 状态
uDateTime_TypeDef last_mark_time; // 故障产生时间
uDateTime_TypeDef last_clear_time; // 故障清除时间
} diag_msg_t;
DIAGNOSIS_MENU_MAX, // 到达结尾
} diag_item_e;
// 诊断记录
typedef struct
{
uint8_t fault_cnt; // 故障数量
diag_msg_t *fault_msg; // 故障信息
} diag_class_record_t;
// 诊断结果统计
typedef struct
{
diag_class_e priority; // 故障最高等级
diag_class_record_t record[DIAG_FAULT_CLASS_NUM]; // 设备故障
alarm_handle_mode_e cmd; // 故障处理
} diag_result_t;
#define DEFALT_CLASS_FAIL_MIN_NUM 0
#define DEFALT_CLASS_FAIL_MAX_NUM DIAGNOSIS_TEMPERATURE_UPPER
#define DEFALT_CLASS_SPEC_MIN_NUM DIAGNOSIS_TEMPERATURE_UPPER
#define DEFALT_CLASS_SPEC_MAX_NUM INDICATE_AUTO_CALIBRATION
#define DEFALT_CLASS_MAINT_MIN_NUM INDICATE_AUTO_CALIBRATION
#define DEFALT_CLASS_MAINT_MAX_NUM DIAGNOSIS_CPU_USAGE
#define DEFALT_CLASS_CHECK_MIN_NUM DIAGNOSIS_CPU_USAGE
#define DEFALT_CLASS_CHECK_MAX_NUM DIAGNOSIS_MENU_MAX
// 诊断过程参数
typedef struct
{
uint8_t start_tag; // 诊断开始标志
uint32_t start_time; // 用于记录诊断起始时间
float32 start_target; // 用于记录诊断起始目标
float32 start_actual; // 用于记录诊断起始实际
uint8_t start_tag; // 诊断开始标志
uint32_t start_time; // 用于记录诊断起始时间
} diag_process_t;
extern diag_result_t diag_result;
extern void diagnosis_init(void); ///< 诊断模块初始化
extern void power_on_diagnosis(void); ///< 开机自检
extern void diagnosis_inspection(void); ///< 过程诊断
extern void diagnosis_fault_deal(void); ///< 故障处理
extern void diagnosis_driver_swo1(float32 cmd); ///< SWO1测试
extern void diagnosis_driver_swo2(float32 cmd); ///< SWO2测试
extern void diagnosis_driver_output(float32 cmd); ///< PWM输出测试
extern void diagnosis_fault_set(diag_class_e class, uint8_t code, uint8_t state); ///< 设置故障状态
extern uint8_t get_diagnosis_fault_num(diag_class_e cls); ///< 获取故障数量
extern state_e get_diagnosis_fault_result(diag_class_e cls, uint8_t code); ///< 获取故障状态
// 诊断信息
typedef struct
{
uint8_t diag_id; // ID
uint8_t diag_class; // 等级
uint8_t diag_state; // 状态
date_time_t last_mark_time; // 故障产生时间
date_time_t last_clear_time; // 故障清除时间
// 不用记录到存储中的参数
diag_process_t process; // 诊断过程参数
} diag_msg_t; // 长度 = 3+6+6 = 15
// 诊断结果统计
typedef struct
{
uint8_t priority; // 故障最高等级
uint8_t cmd; // 故障处理方式
uint8_t record[DIAG_CLASS_NUM]; // 故障数量
diag_msg_t diag_msg[DIAGNOSIS_MENU_MAX]; // 诊断信息
uint32_t crc; // CRC校验
} diag_result_t;
extern diag_result_t diag_result; ///< 诊断结果
extern void diagnosis_init(void); ///< 诊断模块初始化
extern void diagnosis_param_restart(void); ///< 诊断模块恢复出厂设置
extern void power_on_diagnosis(void); ///< 开机自检
extern void diagnosis_inspection(void); ///< 过程诊断
extern void diagnosis_fault_indicate(diag_class_e sta); ///< 故障指示
extern void diagnosis_fault_deal(void); ///< 故障处理
extern void diagnosis_driver_swo1(float32 cmd); ///< SWO1测试
extern void diagnosis_driver_swo2(float32 cmd); ///< SWO2测试
extern void diagnosis_driver_output(float32 cmd); ///< PWM输出测试
extern void diagnosis_set_status(uint8_t id, state_e state); ///< 设置故障状态
extern uint8_t get_diagnosis_items_num(diag_class_e cls); ///< 获取诊断项数量
extern uint8_t get_diagnosis_fault_num(diag_class_e cls); ///< 获取故障数量
extern state_e get_diagnosis_fault_result(uint8_t id); ///< 获取故障状态
extern diag_class_e get_diagnosis_fault_priority(void); ///< 获取故障优先级
extern diag_result_t *get_diagnosis_result(void); ///< 获取诊断结果对象
extern state_e get_diagnosis_fault_result_of_enable_state(uint8_t id); ///< 基于标志使能状态获取诊断状态
#endif

View File

@ -14,14 +14,13 @@
#include <string.h>
#include <fal.h>
#include "flashdb.h"
#include "flow.h"
typedef enum
{
KEY_CALIBPARA_PARAM,
KEY_DEVICE,
KEY_HART_DEVICE_VARIABLE_PARAM,
KEY_REAL_TIME_DATA,
KEY_MODE_PARAM, // 模式参数:控制算法自定义参数
KEY_NOINIT_DATA, // 非初始化数据
KEY_DEVICE, // 设备信息
KEY_REAL_TIME_DATA, // 实时数据
KEY_DIAGNOSIS_RESULT, // 诊断结果
KEY_MAX,
} fal_key_e;
@ -30,17 +29,40 @@ typedef enum
FAL_EXECUTION_EEPROM_M95_1,
FAL_EXECUTION_EEPROM_M95_2,
FAL_EXECUTION_EEPROM_FM24,
FAL_EXECUTION_MAX,
} fal_execution_e;
typedef struct
{
fal_execution_e eeprom_index;
BOOL enable; // 是否使能
BOOL statistics_enable; // 是否统计
fal_execution_e storage_index;
struct fdb_kvdb kvdb;
struct fdb_tsdb tsdb;
struct fdb_default_kv kv;
fal_key_e read_key; // 读取键
fal_key_e write_key; // 写入键
uint16_t init_use_time; // 初始化时间
uint16_t read_use_time; // 读取时间
uint16_t write_use_time; // 写入时间
uint16_t statistics_use_time; // 统计时间
uint16_t data_size; // 数据大小,不能超过块大小
uint16_t write_error_num; // 写入错误次数
struct
{
float32 used; // 使用率
} statistics;
struct
{
int (*read)(uint32_t read_addr, uint8_t *data, uint16_t length);
@ -56,6 +78,7 @@ typedef union
uint8_t M95_1 : 1;
uint8_t M95_2 : 1;
uint8_t FM24 : 1;
uint8_t CUP_FLASH : 1;
} bits;
} fal_execution_status_u; // eeprom状态
@ -66,10 +89,48 @@ typedef struct
fal_execution_status_u write;
} fal_execution_status_t;
extern fal_execution_t fal_executions[FAL_EXECUTION_MAX];
extern fal_execution_status_t fal_execution_status; // eeprom状态
extern struct flow_sem fal_write_sem; // 写信号量
static inline void fdb_lock(fdb_db_t db)
{
__disable_irq();
}
static inline void fdb_unlock(fdb_db_t db)
{
__enable_irq();
}
/**
* @brief Initializes the fal_execution module.
* @param index The index of the fal_execution to clear.
* @param data_size The size of the data to be stored in the fal_execution.
*/
void fal_execution_init(void);
void fal_execution_init(fal_execution_e index, uint16_t data_size);
/**
* @brief Enables or disables the fal_execution statistics.
*
* @param index The index of the fal_execution to enable or disable the statistics for.
* @param enable TRUE to enable the fal_execution statistics, FALSE to disable it.
*/
void fal_execution_statistics_enable(fal_execution_e index, BOOL enable);
/**
* @brief Gets the fal_execution statistics.
*
* @param index The index of the fal_execution to get the statistics from.
*/
void fal_execution_statistics(fal_execution_e index);
/**
* @brief Enables or disables the fal_execution module.
*
* @param enable TRUE to enable the fal_execution module, FALSE to disable it.
*/
void fal_execution_set_enable(fal_execution_e index, BOOL enable);
/**
* @brief Clears the status of a specific fal_execution.
@ -94,6 +155,25 @@ BOOL fal_execution_status_get(fal_execution_e index);
*/
void fal_execution_status_set(fal_execution_e index, BOOL status);
/**
* @brief Checks if the fal_execution data is valid.
*
* @param index The index of the fal_execution to check the data for.
* @param data The data to check.
* @param length The length of the data to check.
* @return TRUE if the data is valid, FALSE otherwise.
*/
BOOL fal_execution_data_storage_check(const uint8_t index, const uint8_t *const data, const uint16_t length);
/**
* @brief Sets the CRC of the fal_execution data.
*
* @param index The index of the fal_execution to set the CRC for.
* @param data The data to set the CRC for.
* @param length The length of the data to set the CRC for.
*/
void fal_execution_set_crc(const uint8_t index, const uint8_t *const data, const uint16_t length);
/**
* @brief Reads data from a specific fal_execution key-value pair.
*
@ -115,11 +195,19 @@ BOOL fal_execution_kv_read(const fal_key_e key, const uint8_t *data, uint16_t le
BOOL fal_execution_kv_write(const fal_key_e key, const uint8_t *const data, const uint16_t length);
/**
* @brief Performs inspection for a specific fal_execution.
* @brief Deletes the data associated with a specific fal_execution key.
*
* @param cycle The cycle number for the inspection.
* @param key The key of the fal_execution key-value pair to delete.
*/
void fal_execution_inspection(uint16_t cycle);
void fal_execution_kv_delete(const fal_key_e key);
/**
* @brief Reads and checks the data.
*
* This function reads and checks the data.
* It performs the necessary operations to read and check the data.
*/
void fal_execution_write_and_check_data(fal_key_e key, uint8_t *data, uint16_t length);
/**
* @brief Gets the current time from the flashlight module.
@ -127,4 +215,23 @@ void fal_execution_inspection(uint16_t cycle);
* @return The current time from the flashlight module.
*/
fdb_time_t fal_execution_get_time(void);
/**
* @brief Loads the execution state.
*
* This function is responsible for loading the execution state.
* It performs the necessary operations to load the saved state
* of the execution.
*/
void fal_execution_sem_update(void);
/**
* @brief Processes the execution.
*
* This function is responsible for processing the execution.
* It performs the necessary operations to process the execution.
*/
void fal_execution_process(void);
INTERNAL_EXTERN void fal_execution_inspection_sem(void); // 更新
#endif

View File

@ -2,27 +2,21 @@
#define __KEY_H__
#include "lib.h"
#include "btn.h"
#include "menus.h"
#define KEY_NONE 0x00 // 无按键
#define KEY_ESC BIT1 // 返回
#define KEY_UP BIT2 // 上
#define KEY_DOWN BIT3 // 下
#define KEY_ENT BIT4 // 确认
#define KEY_LEFT BIT5 // 左
#define KEY_RIGHT BIT6 // 右
#define KEY_AUTO BIT7 // 自动
/// 按键功能
// 按键功能
typedef enum
{
KEY0 = BIT0,
KEY1 = KEY_ESC, ///< KEY1: 退出
KEY2 = KEY_LEFT, ///< KEY2: 向左
KEY3 = KEY_UP, ///< KEY3: 向上
KEY4 = KEY_DOWN, ///< KEY4: 向下
KEY5 = KEY_RIGHT, ///< KEY5: 向右
KEY6 = KEY_ENT, ///< KEY6: 确认
KEYAUTO = KEY_AUTO, ///< KEY_AUTO: 自动
KEY0 = 1,
KEY1,
KEY2,
KEY3,
KEY4,
KEY5,
KEY6,
KEYAUTO, ///< KEY_AUTO: 自动
} button_id_e;
extern void key_botton_start(void); ///< 按键启动
extern void key_init(void); ///< 按键初始化
extern void key_dinit(void); ///< 按键反初始化

View File

@ -2,57 +2,52 @@
#define __PARAMS_H__
#include "lib.h"
#include "main.h"
#include "entity.h"
#include "hart_common_tables_specification.h"
#include "wl_flash.h"
#include "storage.h"
#define CURRENT_VERSION (DW_VER << 16 | HW_VER << 8 | SW_VER)
// 存储相关的地址定义
#define BUSINESS_ADDRESS_PAGE 1
#define CALIB_PARAM_ADDRESS_START (BUSINESS_ADDRESS_PAGE * FM24_PAGE_SIZE) // 校准参数存储的基础地址 需要1页
#define MODE_PARAMS_ADDRESS_START CALIB_PARAM_ADDRESS_START + FM24_PAGE_SIZE // 模式参数存储的基础地址 需要1页
#define SPECIFICATION_TABLE_DATA_ADDRESS_START MODE_PARAMS_ADDRESS_START + FM24_PAGE_SIZE // 规格表数据存储的基础地址 需要3页
#define HART_ADDRESS_PAGE 10 // HART 信息存储起始页
#define HART_PARAMS_ADDRESS_START (HART_ADDRESS_PAGE * FM24_PAGE_SIZE) // HART 信息存储的基础地址 需要2页
#define HART_VARIABLE_ADDRESS_START HART_PARAMS_ADDRESS_START + 2 * FM24_PAGE_SIZE // HART 变量存储的基础地址 需要4页
#define HART_CONSTANT_ADDRESS_START HART_VARIABLE_ADDRESS_START + 4 * FM24_PAGE_SIZE // HART 常量存储的基础地址 需要6页
#define HART_STANDARD_VARIABLE_ADDRESS_START HART_CONSTANT_ADDRESS_START + 6 * FM24_PAGE_SIZE // HART 标准变量存储的基础地址 需要1页
/// 气压通道
typedef enum
{
ADC_INDEX_PRESSSOURCE = 0, // 气源压力
ADC_INDEX_PRESSOUTA = 1, // 输出压力A
ADC_INDEX_PRESSOUTB = 2, // 输出压力B
ADC_INDEX_CLOSEALL = 3, // 全部关闭
} pressure_index_e;
// PARAMS_CRC_KEY_NOINIT_DATA, // 非初始化数据
// PARAMS_CRC_KEY_CALIBPARA_PARAM, // 校准参数
// PARAMS_CRC_KEY_DIAGNOSIS_RESULT, // 诊断结果
// PARAMS_CRC_KEY_SPECIFICATION_TABLE, // 规格表
PARAMS_CRC_KEY_DEVICE, // 设备信息
PARAMS_CRC_KEY_REAL_TIME_DATA, // 实时数据
PARAMS_CRC_KEY_MODE_PARAM, // 模式参数:控制算法自定义参数
PARAMS_CRC_KEY_MAX,
} params_crc_key_e;
/// 定位器型号
typedef enum
{
POSITIONER_MODEL_GPS2000 = 2000, // 自制SAMSON
POSITIONER_MODEL_GPS2001 = 2001, // SAMSON 原装
POSITIONER_MODEL_GPS3000 = 3000, // 自制SAMSON IP + FISHER 放大器
POSITIONER_MODEL_GPS3001 = 3001, // FISHER 原装
POSITIONER_MODEL_GPS5000 = 5000,
POSITIONER_MODEL_GPS2000 = EXTENDED_DEVICE_TYPE_GSDT_GPS2000,
POSITIONER_MODEL_GPS3000 = EXTENDED_DEVICE_TYPE_GSDT_GPS3000,
POSITIONER_MODEL_MAX,
} positioner_model_e;
/// 磁条规格
typedef enum
{
MAGNET_SPAC_TEST,
MAGNET_SPAC_25,
MAGNET_SPAC_50,
MAGNET_SPAC_110,
MAGNET_SPAC_210,
MAGNET_SPAC_ANGLE_90,
MAGNET_PARAM_MAX,
} magnet_spac_e;
/// 输出开关触发逻辑
typedef enum
{
TRIGGER_LOGIC_DISABLE = 0, // 禁用
TRIGGER_LOGIC_ABOVE = 1, // 高电平
TRIGGER_LOGIC_BELOW = 2, // 低电平
// TRIGGER_LOGIC_DISABLE = 0, // 禁用 无效,默认低电平
TRIGGER_LOGIC_BELOW = 0, // 低电平
TRIGGER_LOGIC_ABOVE = 1, // 高电平
} swo_logic_e;
/// 阀门类型
typedef enum
{
VALUE_TYPE_OTHER = 0, // 其它
VALUE_TYPE_SPRING_DIAPHRAGM = 1, // 弹簧膜片式
VALUE_TYPE_NO_SPRING_DOUBLE = 2, // 无弹簧双作用气缸式
VALUE_TYPE_SPRING_DOUBLE = 3, // 带弹簧双作用气缸式
VALUE_TYPE_SPRING_SINGLE = 4, // 带弹簧单作用气缸式
} value_type_e;
/// 阀门尺寸
typedef enum
{
@ -81,22 +76,17 @@ typedef enum
/// 执行机构行程类型
typedef enum
{
TRAVEL_TYPE_STRAIGHT = 0, // 直行程
TRAVEL_TYPE_ANGULAR = 1, // 角行程
TRAVEL_TYPE_STRAIGHT = 0x00, // 直行程
TRAVEL_TYPE_ANGULAR = 0x01, // 角行程
} value_travel_type_e;
/// 执行机构气动类型
typedef enum
{
ATO = 0, // 气开,充气阀门打开,放气阀门关闭
ATC = 1, // 气关,充气阀门关闭,放气阀门打开
} value_action_type_e;
/// 执行机构作用类型
typedef enum
{
VALVE_ACTING_SINGLE = 0, // 单作用
VALVE_ACTING_DOUBLE = 1, // 双作用
DOUBLE_ACTING_WITH_SPRING = 3, // 双作用带弹簧气缸
DOUBLE_ACTING_NO_SPRING = 1, // 双作用不带弹簧气缸
SINGLE_ACTING_WITH_SPRING = 2, // 单作用带弹簧气缸
SINGLE_ACTING_DIAPHRAGM = 0, // 单作用弹簧薄膜式
} value_relay_type_e;
/// 定位器作用方向
@ -113,35 +103,14 @@ typedef enum
CONTROLLER_INSTALL_NORMAL = 1, // 正向安装磁条反馈ADC值上大下小
} dev_install_dir_e;
/// 定位器工作模式
/// 设备授权等级
typedef enum
{
ON_LINE_MODE = 0, ///< 自动模式根据4~20mA控制阀位
OFF_LINE_MODE = 1, ///< 手动模式,根据设定目标值控制阀位
TEST_MODE = 2, ///< 测试模式,在测试定位器部分功能时,必须在测试模式下进行
FORBIDEN_MODE = 3, ///< 非投用模式,阀门复位,定位器禁用信号控制功能
WAIT_MODE = 4, ///< 待机模式,阀门保持,定位器禁用信号控制功能
} dev_work_mode_e;
/// 定位器控制模式
typedef enum
{
POS_CTRL_MODE = 0, ///< 位置控制模式
PRESS_CTRL_MODE = 1, ///< 压力控制模式
} dev_ctrl_mode_e;
/// 阀门特性
typedef enum
{
VALVE_CHARACT_LINEAR = 0, // 线性
VALVE_CHARACT_EQU50 = 1, // 等百1:50
VALVE_CHARACT_QOPEN50 = 2, // 快开1:50
VALVE_CHARACT_EQU25 = 3, // 等百1:25
VALVE_CHARACT_QOPEN25 = 4, // 快开1:25
VALVE_CHARACT_EQU33 = 5, // 等百1:33
VALVE_CHARACT_QOPEN33 = 6, // 快开1:33
VALVE_CHARACT_SElF = 7, // 自定义
} valve_chart_e;
DEV_USFEATURES_AC = 129,
DEV_USFEATURES_HC = 561,
DEV_USFEATURES_AD = 573,
DEV_USFEATURES_PD = 575,
} dev_usfeatures_e;
/// LCD显示方向
typedef enum
@ -155,6 +124,7 @@ typedef enum
{
CHINESE = 0,
ENGLISH = 1,
LANGUAGE_MAX,
} display_language_e;
/// 行程显示方式
@ -173,31 +143,7 @@ typedef enum
TRAVEL_UNIT_ANGLE = 3, // 角度
} travel_unit_e;
/// 压力单位
typedef enum
{
PRESSURE_UNIT_Kpa = 0,
PRESSURE_UNIT_Mpa = 1,
PRESSURE_UNIT_Psi = 2,
PRESSURE_UNIT_Bar = 3,
PRESSURE_UNIT_Kgf = 4,
} press_unit_e;
/// 温度单位
typedef enum
{
TEMPERATURE_UNIT_C = 0, // 摄氏度
TEMPERATURE_UNIT_F = 1, // 华氏度
} temperature_unit_e;
/// 电流单位
typedef enum
{
CURRENT_UNIT_MA = 0, // 毫安
CURRENT_UNIT_A = 1, // 安
} current_unit_e;
/// 电流单位
/// 力学单位
typedef enum
{
FORCE_UNIT_N = 0, // 牛
@ -209,7 +155,7 @@ typedef enum
{
ALARM_HANDLING_CONTINUE = 0, // 不影响阀门动作
ALARM_HANDLING_KEEP = 1, // 阀门位置保持
ALARM_HANDLING_RESET = 2, // 阀门复位
ALARM_HANDLING_SHUTDOWN = 2, // 停机处理,恢复零功率状态
} alarm_handle_mode_e;
/// 复位处理方式
@ -222,20 +168,21 @@ typedef enum
/// PID参数选择
typedef enum
{
Adaptive_PID = 0, // 自适应PID
Self_PID = 1, // 自定义PID
ADAPTIVE_PID = 0, // 自适应PID
SELF_PID = 1, // 自定义PID
} pid_index_e;
/// 整定结果
typedef enum
{
TUNED_NONE = 0, // 未整定
TUNED_ONGOING = 1, // 整定中
TUNED_SUCCESS = 2, // 整定成功
TUNED_FAILED = 3, // 整定失败
TUNED_NONE = 0, // 未整定
TUNED_ONGOING = 1, // 整定中
TUNED_SUCCESS = 2, // 整定成功
TUNED_FAILED = 3, // 整定失败
TUNED_OTHER = 0xff, // 其它错误
} tuned_result_e;
// TODO 气压传感规格
// 气压传感规格
typedef enum
{
PRESSURE_PARAM_S,
@ -244,17 +191,242 @@ typedef enum
PRESSURE_PARAM_MAX,
} pressure_type_e;
/********************************************** 参照Fisher陆续更新 **********************************************/
// 反馈特性
typedef enum
{
SSTEM_19_ARRAY = 0x40,
SSTEM_25_ARRAY = 0x41,
SSTEM_38_ARRAY = 0x42,
SSTEM_50_ARRAY = 0x43,
SSTEM_07_ARRAY = 0x44,
SSTEM_100_ARRAY = 0x46,
SSTEM_110_ARRAY = 0x47,
SSTEM_210_ARRAY = 0x4a,
SSTEM_1_ROLLER_ARRAY = 0x55,
RSHAFT_END_ARRAY = 0x5a,
RSHAFT_1_WINDOW_ARRAY = 0x5f,
RSHAFT_2_WINDOW_ARRAY = 0x61,
DEFAULT_ARRAY = 0x64,
} feedback_char_e;
typedef enum
{
DEFAULT_ARRAY_INDEX = 0,
MAX_ARRAY_INDEX,
} magnet_index_e;
// 电流单位与HART协议保持一致
typedef enum
{
INPUT_UNIT_MA = UNITS_CODE_CURRENT_MA, // 毫安
INPUT_UNIT_PERCENT = UNITS_CODE_ANALYSIS_PERCENT, // 百分比
} input_unit_e;
// 行程特性
typedef enum
{
TRAVEL_CHAR_LINEAR = 0, // 线性
TRAVEL_CHAR_EQUAL = 2, // 等百分比
TRAVEL_CHAR_QUICK_OPEN = 3, // 快开
TRAVEL_CHAR_CUSTOM = 4, // 自定义:两点之间默认线性
} valve_chart_e;
// 压力单位
typedef enum
{
PRESSURE_UNIT_PSI = UNITS_CODE_PRESSURE_PSI,
PRESSURE_UNIT_BAR = UNITS_CODE_PRESSURE_BAR,
PRESSURE_UNIT_KPA = UNITS_CODE_PRESSURE_KPA,
PRESSURE_UNIT_MPA = UNITS_CODE_PRESSURE_MPA,
PRESSURE_UNIT_KGF = UNITS_CODE_PRESSURE_KGCM2,
} press_unit_e;
// 温度单位与HART协议保持一致
typedef enum
{
TEMPERATURE_UNIT_C = UNITS_CODE_TEMPERATURE_CELSIUS, // 摄氏度
TEMPERATURE_UNIT_F = UNITS_CODE_TEMPERATURE_FAHRENHEIT, // 华氏度
} temp_unit_e;
// 仪器模式
typedef enum
{
INST_OS = 0, // 服务外,要修改配置参数时,需要设置为服务外
INST_IS = 1, // 服务内
} inst_mode_e;
// 行程压力选择
typedef enum
{
TRAVEL_CTRL = 0, // 行程控制
TVL_PRESS_AUTO_RST = 1, // 压力控制
SRNSOR_FAULT_BACK = 2, // 传感器故障回退
SENSOR_FAULT_OR_DEVIATED = 3, // 传感器故障或偏差
} travel_press_e;
typedef enum
{
SHUTDOWN_DISABLED,
SHUTDOWN_ENABLED,
} sis_opt_e;
// 控制模式
typedef enum
{
TEST_CTRL_MODE = 0, // 测试 正常运行模式 t
DIGITAL_CTRL_MODE = 2, // 数字 手动控制模式 m
ANALOG_CTRL_MODE = 3, // 模拟 自动控制模式 a
STOP_MODE = 4, // 停机 s
WAIT_MODE = 5, // 待机 w
} control_mode_e;
// 上次整定结果
typedef enum
{
NEVER_HAPPENED, // 未整定过
CAL_SUCCESS, // 整定成功
POWER_LOST, // 整定断电
USER_ABORT, // 用户中断
TIMEOUT, // 整定超时
} auto_cal_status_e;
// 零功率条件
typedef enum
{
VALVE_CLOSE = 0, // 阀门全关(阀门在下面)
VALVE_OPEN = 1, // 阀门全开(阀门在上面)
} zero_power_e;
// 切除/限位选择
typedef enum
{
LLIMIT_HLIMIT = 0, // 下限限位+上限限位
LHARD_HLIMIT = 1, // 下限硬切除+上限限位
LLIMIT_HHARD = 2, // 下限限位+上限硬切除
LHARD_HHARD = 3, // 下限硬切除+上限硬切除
LSOFT_HLIMIT = 5, // 下限软切除+上限限位
LSOFT_HHARD = 7, // 下限软切除+上限硬切除
LLIMIT_HSOFT = 10, // 下限限位+上限软切除
LHARD_HSOFT = 11, // 下限硬切除+上限软切除
LSOFT_HSOFT = 15, // 下限软切除+上限软切除
} cutoff_limit_e;
// 手动/伺服控制
typedef enum
{
ALLOW_SERVO_CTRL = 0, // 允许伺服控制
SUSPEND_SERVO_CTRL = 1, // 暂停伺服控制
} manual_loader_e;
typedef enum
{
TRAVEL_PRESS_DISABLE = 0,
TRAVEL_ENABLE = 1,
PRESS_ENABLE = 2,
TRAVEL_PRESS_ENABLE = 3,
} ui_enable_e;
typedef enum
{
PARAMS_RESET_CALIB_PARAM, // 校准参数
PARAMS_RESET_UDEVICE, // 设备信息
PARAMS_RESET_BOARD_DATA, // 板卡数据
PARAMS_RESET_REAL_TIME_DATA, // 实时数据
PARAMS_RESET_DIAGNOSIS_DATA, // 诊断数据
PARAMS_RESET_MODE_PARAM, // 模式参数
PARAMS_RESET_HART_DATA, // HART数据
PARAMS_RESET_HART_VARIABLE, // HART变量和常量
PARAMS_RESET_SPECIFICATION_TABLE_DATA, // 规格表数据
PARAMS_RESET_ALL, // 上面的全部复位
PARAMS_RESET_PRESSURE_SENSOR, // 压力传感器
} params_reset_e;
typedef enum
{
FORWARD_DIR = 0,
INVERT_DIR = 1,
} invert_feedback_e;
typedef enum
{
RST_DIGITAL = 0x02, // 数字模式
RST_ANALOG = 0x03, // 模拟模式
RST_STOP = 0x04, // 停机模式
RST_WAIT = 0x05, // 待机模式
RST_RESUME_CTRL = 0x06, // 恢复上一次模式
} restart_ctrl_mode_e;
typedef enum
{
RST_OUT_OF_SERVICE = 0,
RST_IN_SERVICE = 1,
RST_RESUME_INST = 2,
} restart_inst_mode_e;
typedef union
{
uint16_t data;
struct
{
uint8_t all : 1;
uint8_t calib_param : 1; // 校准参数 1
uint8_t udevice : 1; // 设备信息 1
uint8_t specification_table_data : 1; // 规格表数据
uint8_t board_data : 1; // 板卡数据
uint8_t real_time_data : 1; // 实时数据 1
uint8_t diagnosis_data : 1; // 诊断数据
uint8_t mode_param : 1; // 模式参数
uint8_t hart_data : 1; // HART数据 1
uint8_t hart_variable : 1; // HART变量 1
uint8_t pressure_sensor : 1; // 压力传感器
} bits;
} params_reset_u;
typedef union
{
uint8_t data;
struct
{
uint8_t value_relay_type : 2; // 执行机构作用类型
uint8_t dev_driver_dir : 1; // 定位器作用方向
uint8_t reserve : 4; // 保留
uint8_t value_travel_type : 1; // 阀门类型
} bits;
} act_style_u;
extern params_reset_u params_reset; ///< 参数复位标志
extern wl_flash_t wl_flash_board_data; ///< 板卡数据
/// 磁条规格 [0]:最小值 [1]:最大值
extern const uint16_t magnet_param_table[MAGNET_PARAM_MAX][2];
extern const uint16_t magnet_param_table[MAX_ARRAY_INDEX][2];
/// 气压传感规格 [0]:最小值 [1]:最大值
extern const uint16_t pressure_param_table[PRESSURE_PARAM_MAX][2];
/// 阀门流量特性表
extern const uint16_t valve_characteristics_table[][17];
extern storage_t *calib_param_storage;
extern storage_t *specification_table_data_storage;
extern storage_t *mode_params_storage;
extern storage_t *hart_attribute_storage;
extern storage_t *hart_variable_storage;
extern storage_t *hart_constant_storage;
extern storage_t *hart_standard_variable_storage;
extern void params_init(void);
extern void params_restart(void);
extern void params_factory_settings(void); // 上电第一次初始化
extern void params_restart_inspection(void);
extern void params_restart_set(params_reset_e index); // 复位设置
extern BOOL params_restart_get(params_reset_e index); // 复位获取 true:复位中 false:未复位
extern void hart_attribute_params_restart(void);
extern void hart_attribute_params_map(void);
extern void hart_attribute_params_map_restart(void);
extern void hart_attribute_params_map_address_update(void);
extern void spec_table_data_mapping(BOOL inverse);
extern void spec_table_data_reset(void);
extern void hart_attribute_storage_init(uint32_t base_addr);
extern void hart_variable_storage_init(uint32_t base_addr);
extern void hart_constant_storage_init(uint32_t base_addr);
extern void hart_standard_variable_storage_init(uint32_t base_addr);
extern void hart_long_addr_set(void); // 设置长地址
extern uint16_t get_pwm_arr_default(void);
#endif // __PARAMS_H__

View File

@ -2,8 +2,8 @@
#define _PDCTRL_H_
#include "lib.h"
#include "bsp.h"
#define PWM_WID 26 // PWM正频宽
#define SPWM_RESOLUTION 80 // 假设我们使用256个点来模拟一个正弦周期
#define PWM_WID 13 // PWM正频宽
#define PDCTRL_PWM_PRESCALER (1) // 预分频系数
#define PDCTRL_PWM_FREQUENCY (4 * 1000) // 主频KHZ
#define PDCTRL_PWM_TIM (TIM2) // 定时器
@ -48,14 +48,16 @@ typedef struct
float32 freq;
float32 arr_us;
float32 duty_percent;
uint16_t duty;
} pdctrl_t;
extern pdctrl_t pdctrl_data;
void pdctrl_init(pdctrl_mode_e mode); ///< 控制器初始化
void pdctrl_out(uint16_t out); ///< 控制器输出
void pdctrl_pwm_set_arr(uint32_t arr); ///< 动态修改频率
void pdctrl_set_pwm_wid(uint16_t wid); ///< 设置PWM正频宽
void pdctrl_init(pdctrl_mode_e mode); ///< 控制器初始化
void pdctrl_out(uint16_t out); ///< 控制器输出
void pdctrl_pwm_set_arr(uint32_t arr); ///< 动态修改频率
void pdctrl_set_pwm_wid(uint16_t wid); ///< 设置PWM正频宽
uint16_t calculate_pwm_duty(uint32_t arr); ///< 变频计算占空比
uint16_t pdctrl_pwm_duty_convert_ccr(float32 pwm_duty); ///< 占空比转换为CCR值
float32 pdctrl_pwm_get_duty_percent(uint32_t arr); ///< 获取占空比

View File

@ -0,0 +1,282 @@
#ifndef __MENUS_H__
#define __MENUS_H__
#include "sys.h"
#include "lib.h"
#include "menu.h"
#include "board.h"
#include "fal_execution.h"
#include "flow.h"
#include "menus_main.h"
#include "menus_setting.h"
#include "menus_test.h"
#include "menus_templete.h"
#define KEY_NONE BIT0 // 无按键
#define KEY_ESC BIT1 // 返回
#define KEY_UP BIT2 // 上
#define KEY_DOWN BIT3 // 下
#define KEY_ENT BIT4 // 确认
#define KEY_LEFT BIT5 // 左
#define KEY_RIGHT BIT6 // 右
#define KEY_AUTO BIT7 // 自动
#define WM_CREATE BIT8 // 创建
#define WM_DRAW BIT9 // 绘图
#define WM_LONG BIT11 // 长按
#define MENU_TICKS 100 // 菜单刷新时间 单位毫秒
#define SHOW_ACTUALS_NUM 60 // 图表用于显示的实际值个数
#define BUF_LEN 64 // 缓冲区长度
#define SHOW_MENU_ITEM_LINE 6 // 显示行数
#define SHOW_MENU_PAGE_LINE 8 // 显示页面行数
#define SHOW_CARD_PAGE_LINE 14 // 显示卡片页面行数
#define ICON_INIT_FLAG 0xFFFFFFFFFFFFFFFF
#define PASSWORD_TIME 60 * 30 // 密码访问时间 单位秒 30分钟
#define KEY_IS_LONG(st) (st & WM_LONG) // 判断是否长按
typedef enum
{
SET_CUSTOM_RESET, // 重置
SET_CUSTOM_SELF_TEST, // 自检
SET_CUSTOM_SELF_END_TEST, // 自检结束
SET_CUSTOM_SAVE_OK, // 保存完成
SET_CUSTOM_SAVE_FAIL, // 保存失败
SET_CUSTOM_LOADING, // 加载中
SET_CUSTOM_SET_OK, // 设置成功
SET_CUSTOM_SET_FAIL, // 设置失败
SET_CUSTOM_CANCEL, // 已取消
SET_CUSTOM_INPUT_ERROR, // 输入错误
SET_CUSTOM_RETURN_HOME, // 返回首页
SET_CUSTOM_RESET_DEVICE, // 重置参数,设备复位
SET_CUSTOM_RESET_PARAMS, // 重置参数
SET_CUSTOM_MAX,
} set_custom_e;
typedef enum
{
TIPS_TXT_MAIN_MENU, // 主菜单
TIPS_TXT_CHART_PAGE, // 首页:图表页面
TIPS_TXT_EDIT, // 编辑
TIPS_TXT_RESTORE, // 恢复
TIPS_TXT_CALIBRATION, // 校准
TIPS_TXT_PASSWORD, // 密码
TIPS_TXT_CURRENT_TOO_SMALL, // 电流太小
TIPS_TXT_ADJUST_RESULT_OK, // 调整结果成功
TIPS_TXT_ADJUST_RESULT_FAIL, // 调整结果失败
TIPS_TXT_UNKNOWN_ERROR, // 未知错误
TIPS_TXT_SELECT_DIAGNOSTIC_ITEMS, // 选择诊断项目
TIPS_TXT_FAULT_QUANTITY, // 故障数量
TIPS_TXT_RESTORE_ALL_PARAMETERS, // 恢复所有参数
TIPS_TXT_RESTORE_CALI_PARAMETERS, // 恢复校准参数
TIPS_TXT_RESTORE_DEV_PARAMETERS, // 恢复设备参数
TIPS_TXT_RESTORE_RT_DATA, // 恢复实时数据
TIPS_TXT_RESTORE_HART_DATA, // 恢复HART数据
TIPS_TXT_RESTORE_HART_PARAMETERS, // 恢复HART参数
TIPS_TXT_CONTROL_SIGNAL_GENERATOR, // 控制信号发生器
TIPS_TXT_CONTROL_PWM_CURRENT, // 控制PWM电流
TIPS_TXT_LIMIT_POSITION_0, // 限位位置0
TIPS_TXT_LIMIT_POSITION_100, // 限位位置100
TIPS_TXT_CURRENT, // 当前电流
TIPS_TXT_PRESSURE, // 当前压力
TIPS_TXT_MAX,
} tips_txt_e;
typedef enum
{
KEY_TXT_SELECT_OPT, // 选择操作
KEY_TXT_SHORT_PRESS, // 短按
KEY_TXT_LONG_PRESS, // 长按
KEY_TXT_BACK, // 返回
KEY_TXT_ENTER, // 进入
KEY_TXT_NEXT, // 下一个
KEY_TXT_PREVIOUS, // 上一个
KEY_TXT_CANCEL, // 取消
KEY_TXT_CONFIRM, // 确认
KEY_TXT_NEXT_PAGE, // 下一页
KEY_TXT_PREVIOUS_PAGE, // 上一页
KEY_TXT_CALIBRATION_OPTIONS, // 校准选项
KEY_TXT_CONFIRM_CALIBRATION, // 确认校准
KEY_TXT_CALIBRATION_SET, // 校准设置
KEY_TXT_RUN, // 开启
KEY_TXT_INCREASE, // 增加
KEY_TXT_DECREASE, // 减少
} key_txt_e;
typedef enum
{
KEY_MODLE_MAIN, // 主菜单
KEY_MODLE_SUB, // 子菜单
KEY_MODLE_PAGE, // 菜单页
KEY_MODLE_EDIT_PAGE, // 编辑页
KEY_MODLE_CALIBRATION_PAGE, // 校准页
KEY_MODLE_CALIBRATION_PAGE_2, // 校准页2
KEY_MODLE_CONFIRM_PAGE, // 确认页
KEY_MODLE_RUN_PAGE, // 运行页
KEY_MODLE_READ_PAGE, // 只读页
KEY_MODLE_CARD_PAGE, // 卡片页
} key_modle_e;
typedef enum
{
WORK_MENU_TEMPLETE_START,
WORK_MENU_TEMPLETE_1,
WORK_MENU_TEMPLETE_2,
WORK_MENU_TEMPLETE_3,
WORK_MENU_TEMPLETE_END,
} work_menu_templete_e; // 工作界面模版
typedef enum
{
MENUS_NONE = 0, // 无菜单
MENUS_LOADING, // 首页 引导页
MENUS_WORK, // 平时工作页面
MENUS_DESIGN, // 设计页面
MENUS_PASSWORD, // 密码页面
MENUS_MAIN, // 主菜单
MENUS_DEVICE_INFO, // 设备信息
MENUS_SELFTUNE, // 一键整定
MENUS_VALVE_DIAGNOSIS, // 设备诊断
MENUS_STROKE_DIAGNOSIS, // 特性测试
MENUS_SETTING, // 出厂设置
// 二级菜单:特性测试
MENUS_RAMP_TEST, // 斜坡测试
MENUS_STEP_TEST, // 阶跃测试
MENUS_STROKE_LIMIT_POSITION_TEST, // 行程限位测试
MENUS_DRIVER_TEST, // 驱动测试
MENUS_PWM_TEST, // PWM测试
MENUS_IO_TEST, // IO测试
// 二级菜单:出厂设置
MENUS_SET_PARAMETERS, // 参数设置
MENUS_RESET_PARAMETERS, // 恢复参数
MENUS_SET_PID, // PID设置
// 其他类型的菜单
MENUS_PAGE_NONE, // 无页面
MENUS_PAGE, // 页面菜单
MENUS_EDIT_PAGE, // 编辑页面
MENUS_RESTORE_PAGE, // 恢复页面
MENUS_SET_PAGE, // 设置页面
MENUS_CALIBRATION_PAGE, // 校准页面
MENUS_MAX, // 菜单最大值
} menus_e; // 菜单索引
typedef struct
{
char *psz_desc; /*!< 当前选项的字符串描述*/
char *psz_items_desc[MENU_MAX_NUM]; /*!< 当前选项中所有选项的字符串描述 */
menusize_t items_num; /*!< 当前菜单选项总数目 */
menusize_t show_base_item; /*!< 当前菜单首个显示的选项 */
menusize_t select_item; /*!< 当前菜单选中的选项 */
} parent_menu_info_t;
typedef struct
{
BOOL accelerate; // 加速显示
BOOL forced_acceleration; // 强制加速显示
menus_e current_menu; // 当前菜单功能用于menus_task
uint8_t dir; // 按键方向 0正常 1:180度
BOOL is_init; // 是否初始化
struct flow_sem jump_work_sem;
BOOL run_enable; // 运行使能
struct flow_sem refush_sem;
BOOL looding; // 加载中
uint8_t language; // 语言 0中文 1:英文
uint16_t last_window_no; // 上一个窗口号
uint16_t last_item_no; // 上一个菜单项号
uint8_t last_base_no; // 上一个基础菜单项,在小于最大菜单项时,用于记录第一个菜单项
uint8_t last_page_no; // 上一个页面
uint64_t wm_msg; // 窗体消息
uint32_t key_long_ticks; // 长按时间
int8_t key_accelerate_ticks; // 加速显示时间
// 内部用的变量
parent_menu_info_t parent_menu; // 父菜单控制
uint8_t valve_diagnosis_index; // 阀门诊断索引
uint8_t input_password[PASSWORD_LEN]; // 输入密码
uint8_t input_password_index; // 输入密码索引
uint32_t pass_access_time; // 密码访问时间
int16_t menus_task_wait_ticks; // 菜单任务等待时间
uint16_t menu_ticks; // 菜单刷新时间
uint16_t menu_ticks_count; // 菜单刷新时间计数
uint32_t used_time_start; // 绘图开始时间
uint32_t used_time; // 绘图使用时间
uint32_t last_update_time; // 上次更新时间
uint64_t icon_laster; // 图标上次
uint8_t work_templete_index; // 工作模板索引
uint8_t work_templete_page_index; // 工作模板页面索引(内容页)
uint8_t work_templete_page_total; // 工作模板页面总数(内容页)
uint8_t device_info_index; // 设备信息索引
menu_list_t *edit_items; // 编辑项
uint8_t initial_item; // 初始项
uint32_t edit_cache[4]; // 编辑缓存
BOOL(*set_cb)
(void); // 保存回调函数
BOOL(*done_cb)
(void); // 执行回调函数
// 内部回调函数
void (*menus_task_wait_cb)(void *p);
void *menus_task_wait_cb_parm;
void (*page_lable_info_draw)(menu_show_t *info);
} menus_t;
INTERNAL_EXTERN const menu_txt_t custom_txt_table[SET_CUSTOM_MAX]; // 自定义文本表
INTERNAL_EXTERN const menu_txt_t tips_txt_table[TIPS_TXT_MAX]; // 提示文本表
INTERNAL_EXTERN const menu_txt_t device_info_txt_table[DEVICE_INFO_TXT_MAX]; // 设备信息文本表
INTERNAL_EXTERN const device_info_index_e device_info_index[DEVICE_INFO_INDEX_MAX]; // 设备信息索引表
INTERNAL_EXTERN const device_info_index_e device_info_index_edit[]; // 设备信息编辑索引表
extern void menus_init(uint8_t language); // 初始化菜单
extern menus_t *get_menus(void); // 获取菜单
extern void menus_key_register(uint64_t key); // 注册按键
extern void menus_key_long_start(void); // 按键长按计时开始
extern void menus_key_long_stop(void); // 按键长按计时停止
extern void menus_jump(menus_e page, BOOL delay); // 跳转到指定菜单
extern void menus_jump_refush(void); // 跳转到刷新界面
extern void menus_jump_asynchronous(menus_e page, BOOL loading); // 跳转到工作界面
extern void menus_rebuild(void); // 重建菜单
extern void menus_set_scandir(uint8_t dir); // 设置菜单扫描方向
extern void menus_set_language(uint8_t language); // 设置菜单语言
extern void menus_set_work_index(uint8_t index); // 设置工作模板索引
extern void menus_set_font_size(font_type_e font); // 设置字体大小
INTERNAL_EXTERN void menus_first_items_show(menu_show_t *info); // 显示一级菜单项
INTERNAL_EXTERN void menus_second_items_show(menu_show_t *info); // 显示二级菜单项
INTERNAL_EXTERN void menus_process(void); // 菜单处理进程
INTERNAL_EXTERN void menus_task(void); // 菜单任务
INTERNAL_EXTERN void menus_update(void); // 更新菜单
INTERNAL_EXTERN void menus_show_custom_window(uint8_t index); // 设置自定义弹窗
INTERNAL_EXTERN void menus_show_confirm_window(void); // 显示确认窗口
INTERNAL_EXTERN void menus_show_edit_window(menu_show_t *info); // 显示编辑窗口
INTERNAL_EXTERN void menus_edit_task(void); // 编辑任务
INTERNAL_EXTERN BOOL menus_items_is_change(uint16_t current_item); // 判断菜单项是否改变
INTERNAL_EXTERN uint16_t get_menus_current_window_no(void); // 获取当前窗口号
INTERNAL_EXTERN BOOL menus_key_structure(uint64_t done_msg); // 页面任务
INTERNAL_EXTERN void menus_page_lable_show(menu_show_t *info); // 显示页面标签
INTERNAL_EXTERN void menus_page_draw_title(font_type_e font, char *prefix); // 画标题
INTERNAL_EXTERN void menus_layout_print_top(void); // 画界面
INTERNAL_EXTERN void menus_layout_print_arrow(key_modle_e modle); // 画箭头说明
INTERNAL_EXTERN BOOL menus_layout_print_icon(void); // 画图标
INTERNAL_EXTERN BOOL menus_storage_save(fal_key_e key); // 保存
INTERNAL_EXTERN BOOL menus_task_delay_check(void); // 菜单任务延时检查
INTERNAL_EXTERN void menus_accelerate(void); // 加速
INTERNAL_EXTERN void menus_accelerate_restore(void); // 加速恢复
// 加载界面
INTERNAL_EXTERN void menus_low_battery_draw(float32 voltage, BOOL voltage_right, float32 current, BOOL current_right); // 低电量
INTERNAL_EXTERN void menus_loading_draw(BOOL only_logo);
// 输入密码界面
INTERNAL_EXTERN void menus_password_window(BOOL init);
// 主菜单
INTERNAL_EXTERN void menus_enter(void);
INTERNAL_EXTERN void menus_exit(void);
INTERNAL_EXTERN void main_menu_load(void);
INTERNAL_EXTERN void main_menu_task(void);
extern BOOL is_selftune_menu(void);
#endif // __MENUS_H__

View File

@ -0,0 +1,107 @@
#ifndef __MENUS_MAIN_H__
#define __MENUS_MAIN_H__
#include "lib.h"
typedef enum
{
DEVICE_INFO_INDEX_INSTRUMENT_MODE, // 仪器模式
DEVICE_INFO_INDEX_CONTROL_MODE, // 控制模式
DEVICE_INFO_INDEX_DEVICE_MODEL, // 设备型号
DEVICE_INFO_INDEX_DISPLAY_DIRECTION, // 显示方向
DEVICE_INFO_INDEX_DISPLAY_LANGUAGE, // 显示语言
DEVICE_INFO_INDEX_ALGORITHM_SETTING, // 算法设置
DEVICE_INFO_INDEX_SETTING_STATUS, // 整定状态
DEVICE_INFO_INDEX_MANUFACTURE_NAME, // 厂商名称
DEVICE_INFO_INDEX_HART_SHORT_ADDRESS, // HART短地址
DEVICE_INFO_INDEX_HART_LONG_ADDRESS, // HART长地址
DEVICE_INFO_INDEX_VALVE_SERIAL_NUMBER, // 阀门序列号
DEVICE_INFO_INDEX_SERIAL_NUMBER, // 定位器序列号
DEVICE_INFO_INDEX_MANUFACTURE_INFO_SERIAL_NUMBER, // 制造信息序列号
DEVICE_INFO_INDEX_INPUT_SIGNAL, // 输入信号
DEVICE_INFO_INDEX_PRESS_S_RANGE, // 气源压力范围
DEVICE_INFO_INDEX_ENVIRONMENT_TEMP, // 使用环境温度
DEVICE_INFO_INDEX_HARDWARE_VERSION, // 硬件版本
DEVICE_INFO_INDEX_SOFTWARE_VERSION, // 软件版本
DEVICE_INFO_INDEX_DEVICE_VERSION, // 设备版本
DEVICE_INFO_INDEX_WRITE_PROTECT_ENABLE, // 写入保护
DEVICE_INFO_INDEX_PRESSURE_SENSOR_STATUS, // 压力传感器状态
DEVICE_INFO_INDEX_WIRELESS_STATUS, // 蓝牙传输
DEVICE_INFO_INDEX_PWM_OUTPUT_STATUS, // PWM输出状态
DEVICE_INFO_INDEX_OUTPUT_SWITCH1_STATUS, // 输出开关1状态
DEVICE_INFO_INDEX_OUTPUT_SWITCH2_STATUS, // 输出开关2状态
DEVICE_INFO_INDEX_INSTALLATION_DIRECTION, // 安装方向
DEVICE_INFO_INDEX_ACTION_DIRECTION, // 放大器类型
DEVICE_INFO_INDEX_TRAVEL_TYPE, // 阀门类型
DEVICE_INFO_INDEX_PNEUMATIC_TYPE, // 气动类型
DEVICE_INFO_INDEX_ACTION_TYPE, // 执行机构类型
DEVICE_INFO_INDEX_CALIBPARA_LOOP, // 420mA输入电流校准
DEVICE_INFO_INDEX_CALIBPARA_LOOP_OUTPUT, // 420mA输出电流校准
DEVICE_INFO_INDEX_CALIBPARA_PS_S, // 压力表S校准
// DEVICE_INFO_INDEX_CALIBPARA_PS_A, // 压力表A校准
// DEVICE_INFO_INDEX_CALIBPARA_PS_B, // 压力表B校准
DEVICE_INFO_INDEX_MAX,
} device_info_index_e; // 设备信息
typedef enum
{
DEVICE_INFO_TXT_NULL, // 空
DEVICE_INFO_TXT_PAGE, // 页面
DEVICE_INFO_TXT_ENABLE, // 开启
DEVICE_INFO_TXT_DISABLE, // 关闭
DEVICE_INFO_TXT_INSTALL_REVERSE, // 反向安装
DEVICE_INFO_TXT_INSTALL_NORMAL, // 正向安装
DEVICE_INFO_TXT_ACTION_POSITIVE, // 正向作用
DEVICE_INFO_TXT_ACTION_NEGATIVE, // 反向作用
DEVICE_INFO_TXT_TRAVEL_STRAIGHT, // 直行程
DEVICE_INFO_TXT_TRAVEL_ANGLE, // 角行程
DEVICE_INFO_TXT_PNEUMATIC_OPEN, // 气开
DEVICE_INFO_TXT_PNEUMATIC_CLOSE, // 气关
DEVICE_INFO_TXT_SINGLE_ACTING_DIAPHRAGM, // 单作用弹簧薄膜式
DEVICE_INFO_TXT_DOUBLE_ACTING_NO_SPRING, // 双作用不带弹簧气缸
DEVICE_INFO_TXT_SINGLE_ACTING_WITH_SPRING, // 单作用带弹簧气缸
DEVICE_INFO_TXT_DOUBLE_ACTING_WITH_SPRING, // 双作用带弹簧气缸
DEVICE_INFO_TXT_TRIGGER_LOGIC_BELOW, // 低电平
DEVICE_INFO_TXT_TRIGGER_LOGIC_ABOVE, // 高电平
DEVICE_INFO_TXT_FORWARD_DISPLAY, // 正向显示
DEVICE_INFO_TXT_REVERSE_DISPLAY, // 反向显示
DEVICE_INFO_TXT_CHINESE, // 中文
DEVICE_INFO_TXT_ENGLISH, // 英文
DEVICE_INFO_TXT_VARIABLE_FREQUENCY_CONTROL_ALGORITHM, // 变频控制算法
DEVICE_INFO_TXT_CONSTANT_CONTROL_ALGORITHM, // 恒定控制算法
DEVICE_INFO_TXT_SPEED_CONTROL_ALGORITHM, // 速度控制算法
DEVICE_INFO_TXT_FREQUENCY_DOMAIN_CONTROL_ALGORITHM, // 频域控制算法
DEVICE_INFO_TXT_MANUFACTURE_NAME, // 厂商名称
DEVICE_INFO_TXT_INPUT_SIGNAL, // 输入信号
DEVICE_INFO_TXT_PRESS_S_RANGE, // 气源压力范围
DEVICE_INFO_TXT_ENVIRONMENT_TEMP, // 使用环境温度,℃
DEVICE_INFO_TXT_UNTUNED, // 未整定
DEVICE_INFO_TXT_TUNEDING, // 整定中
DEVICE_INFO_TXT_TUNED_SUCCESS, // 整定成功
DEVICE_INFO_TXT_TUNED_FAILED, // 整定失败
DEVICE_INFO_TXT_CALIBRATED, // 已校准
DEVICE_INFO_TXT_UNCALIBRATED, // 未校准
DEVICE_INFO_TXT_LOWER_LIMIT_4MA, // 下限4mA
DEVICE_INFO_TXT_UPPER_LIMIT_20MA, // 上限20mA
DEVICE_INFO_TXT_OFFSET_4MA, // 4mA偏移
DEVICE_INFO_TXT_SPAN_20MA, // 20mA范围
DEVICE_INFO_TXT_LOWER_LIMIT_200KPA, // 下限200kpa
DEVICE_INFO_TXT_UPPER_LIMIT_400KPA, // 上限400kpa
DEVICE_INFO_TXT_INST_OS, // 服务外
DEVICE_INFO_TXT_INST_IS, // 服务内
DEVICE_INFO_TXT_TEST_CTRL_MODE, // 测试控制模式
DEVICE_INFO_TXT_DIGITAL_CTRL_MODE, // 数字控制模式
DEVICE_INFO_TXT_ANALOG_CTRL_MODE, // 模拟控制模式
DEVICE_INFO_TXT_STOP_CTRL_MODE, // 停机运行模式
DEVICE_INFO_TXT_WAIT_CTRL_MODE, // 待机运行模式
DEVICE_INFO_TXT_GPS2000, // 设备型号
DEVICE_INFO_TXT_GPS3000, // 设备型号
DEVICE_INFO_TXT_MAX,
} device_info_txt_e;
INTERNAL_EXTERN void device_info_draw(menu_show_t *info);
INTERNAL_EXTERN BOOL device_info_edit_save_cb(void);
INTERNAL_EXTERN BOOL device_info_edit_done_cb(void);
INTERNAL_EXTERN void design_enter(void); // 设计页面进入函数
INTERNAL_EXTERN void design_exit(void); // 设计页面退出函数
INTERNAL_EXTERN void design_task(void); // 设计页面任务函数
#endif // __MENUS_MAIN_H__

View File

@ -0,0 +1,34 @@
#ifndef __MENUS_SETTING_H__
#define __MENUS_SETTING_H__
#include "lib.h"
#include "menus.h"
typedef enum
{
RESTORE_CALIBRATION_PARAMETERS, // 恢复校准参数
RESTORE_DEVICE_PARAMETERS, // 恢复设备参数
RESTORE_REAL_TIME_DATA, // 恢复实时数据
RESTORE_HART_DATA, // 恢复HART数据
RESTORE_HART_VARIABLE, // 恢复HART变量
RESTORE_ALL_PARAMETERS, // 恢复所有参数
RESTORE_TXT_MAX,
} restore_parameters_e;
typedef enum
{
SET_PID_KP,
SET_PID_KI,
SET_PID_KD,
SET_PID_ED, // 误差死区
} set_pid_e;
INTERNAL_EXTERN void menu_setting_enter(void);
INTERNAL_EXTERN void menu_setting_exit(void);
INTERNAL_EXTERN void menu_setting_load(void);
INTERNAL_EXTERN void menu_setting_task(void);
INTERNAL_EXTERN void device_info_edit(void);
INTERNAL_EXTERN void set_pid_enter(void);
INTERNAL_EXTERN void set_pid_exit(void);
INTERNAL_EXTERN void set_pid_task(void);
#endif // __MENUS_SETTING_H__

View File

@ -0,0 +1,47 @@
#ifndef __MENUS_TEMPELETE_H__
#define __MENUS_TEMPELETE_H__
#include "lib.h"
#include "diagnosis.h"
#define UPDATE_TRIP_CYCLE 5000 // 更新行程周期 单位毫秒 (解决更新太快导致屏幕内容和实际不一致问题)
typedef enum
{
FONT_SMALL, // 16
FONT_MEDIUM, // 24
FONT_LARGE, // 32
} font_type_e;
typedef enum
{
WORK_MENU_CREATE, // 创建
WORK_MENU_UPDATE, // 更新
WORK_MENU_REFUSH_DATA, // 刷新数据
WORK_MENU_REFUSH_PAGE, // 刷新
} work_menu_refush_e;
typedef enum
{
WORK_TXT_CURRENT = 0, // 电流
WORK_TXT_TEMPERATURE, // 温度
WORK_TXT_TARGET_STROKE, // 目标
WORK_TXT_ACTUAL_STROKE, // 实际行程
WORK_TXT_MAX,
} work_txt_table_e;
typedef struct
{
menu_txt_t label;
data_type_e act_style;
void *value;
char *unit;
} work_txt_data_table_t;
INTERNAL_EXTERN const menu_txt_t diagnosis_menu_txt_table[DIAG_CLASS_NUM]; // 诊断菜单文本表
INTERNAL_EXTERN void menus_page_draw_direct_title(char *title, font_type_e font, char *prefix); // 画直接标题
INTERNAL_EXTERN void menus_edit_items_bind(const menu_txt_t *table, uint8_t index_start, uint8_t index_end); // 绑定编辑项
INTERNAL_EXTERN void menus_edit_items_calibration(const menu_txt_t *table, uint8_t index_start, uint8_t index_end); // 设置编辑项
INTERNAL_EXTERN void menus_work_templete_1(work_menu_refush_e flag); // 工作模板1
INTERNAL_EXTERN void menus_work_templete_2(work_menu_refush_e flag); // 工作模板2
INTERNAL_EXTERN void menus_work_templete_3(work_menu_refush_e flag); // 工作模板3
#endif // __MENUS_TEMPELETE_H__

View File

@ -0,0 +1,32 @@
#ifndef __MENUS_TEST_H__
#define __MENUS_TEST_H__
#include "lib.h"
typedef enum
{
IO_TEST_1,
IO_TEST_2,
IO_TEST_MAX,
} io_test_info_e;
INTERNAL_EXTERN void menu_test_enter(void);
INTERNAL_EXTERN void menu_test_exit(void);
INTERNAL_EXTERN void menu_test_load(void);
INTERNAL_EXTERN void menu_test_task(void);
INTERNAL_EXTERN void stroke_limit_position_test_enter(void); // 限位位置测试进入函数
INTERNAL_EXTERN void stroke_limit_position_test_exit(void); // 限位位置测试退出函数
INTERNAL_EXTERN void stroke_limit_position_test_task(void); // 限位位置测试任务函数
INTERNAL_EXTERN void driver_test_enter(void); // 驱动测试进入函数
INTERNAL_EXTERN void driver_test_exit(void); // 驱动测试退出函数
INTERNAL_EXTERN void driver_test_task(void); // 驱动测试任务函数
INTERNAL_EXTERN void pwm_test_enter(void); // PWM测试进入函数
INTERNAL_EXTERN void pwm_test_exit(void); // PWM测试退出函数
INTERNAL_EXTERN void pwm_test_task(void); // PWM测试任务函数
INTERNAL_EXTERN void io_test_enter(void); // IO测试进入函数
INTERNAL_EXTERN void io_test_exit(void); // IO测试退出函数
INTERNAL_EXTERN void io_test_task(void); // IO测试任务函数
#endif // __MENUS_TEST_H__

View File

@ -10,24 +10,10 @@
#include "app.h"
#include "main.h"
#include "mode.h"
#include "mode_diagnosis.h"
mode_params_t mode_params; // 模式参数
static mode_t _mode;
static uint8_t deal_dev_work_mode(void)
{
uint8_t mode = udevice.dev_work_mode;
if (udevice.dev_work_mode == FORBIDEN_MODE || udevice.dev_work_mode == TEST_MODE)
{
return mode;
}
else
{
return mode;
}
}
mode_params_u mode_params __attribute__((section("NOINIT"), zero_init)); // 模式参数
mode_t mode;
/**
* @brief
@ -37,7 +23,7 @@ static uint8_t deal_dev_work_mode(void)
*/
static void mode_autoload_change(uint16_t autoload)
{
LL_TIM_SetAutoReload(TIM7, autoload);
LL_TIM_SetAutoReload(MODE_TIM, autoload);
}
/**
@ -47,26 +33,134 @@ static void mode_autoload_change(uint16_t autoload)
*/
static void mode_params_save_cb(void)
{
fal_execution_kv_write(KEY_CALIBPARA_PARAM, (uint8_t *)&calib_param, (CALIBPARA_NUM * sizeof(calib_param_t)));
fal_execution_kv_write(KEY_MODE_PARAM, (uint8_t *)&mode_params, sizeof(mode_params_t));
fal_execution_kv_read(KEY_MODE_PARAM, (uint8_t *)&mode_params, sizeof(mode_params_t));
fal_execution_sem_update();
}
/**
* @brief
* @brief
* @return {*}
* @note
* @note > 100ms,S口会读到0值
*/
void mode_test_process(void)
void mode_pressure_statistics(void)
{
switch (mode_get()->test_project)
if (mode_diagnosis_get()->run == FALSE)
{
case MODE_DIAGNOSIS: // EPM特性诊断
mode_get()->ctrl.state = FALSE;
flow_event = FLOW_EVENT_DIAGNOSIS;
break;
default:
break;
static uint8_t wait_tick = 0; // 定时器周期是100ms因为功耗关闭传感器到恢复数据采集需要一定时间
float32 pressure = 0.0f;
if (++wait_tick < 3) // 300ms内不处理
{
return;
}
if (udevice.press_sensor_enable != TRUE)
{
return;
}
static uint8_t id = PRESSURE_PARAM_MAX;
static float32 pressure_cross_point_last = 0.0f;
switch (id)
{
case PRESSURE_PARAM_S:
pressure = get_pressure_limit_deal(pressure_kpa2unit(get_pressure(PRESSURE_PARAM_S), udevice.press_unit), udevice.press_unit);
// rt_data.pressure_s = lpf_window_update(&mode_get()->pressure_s_window, pressure);
rt_data.pressure_s = pressure;
if (pressure != 0.0f)
{
id = PRESSURE_PARAM_A;
BP_S_POWER_OFF();
BP_A_POWER_ON();
}
else
{
id = PRESSURE_PARAM_S;
BP_S_POWER_ON();
}
rt_data.pressure_s_kpa = pressure_unit2kpa(rt_data.pressure_s, udevice.press_unit);
break;
case PRESSURE_PARAM_A:
pressure = get_pressure_limit_deal(pressure_kpa2unit(get_pressure(PRESSURE_PARAM_A), udevice.press_unit), udevice.press_unit);
// rt_data.pressure_a = lpf_window_update(&mode_get()->pressure_a_window, pressure);
rt_data.pressure_a = pressure;
if (rt_data.pressure_s != 0) // S口压力不为0的情况下才读取A口和B口的压力
{
id = PRESSURE_PARAM_B;
BP_A_POWER_OFF();
BP_B_POWER_ON();
}
else
{
rt_data.pressure_a = 0;
id = PRESSURE_PARAM_S;
BP_A_POWER_OFF();
BP_S_POWER_ON();
}
rt_data.pressure_a_kpa = pressure_unit2kpa(rt_data.pressure_a, udevice.press_unit);
break;
case PRESSURE_PARAM_B:
pressure = get_pressure_limit_deal(pressure_kpa2unit(get_pressure(PRESSURE_PARAM_B), udevice.press_unit), udevice.press_unit);
// rt_data.pressure_b = lpf_window_update(&mode_get()->pressure_b_window, pressure);
rt_data.pressure_b = pressure;
id = PRESSURE_PARAM_S;
BP_B_POWER_OFF();
BP_S_POWER_ON();
if (rt_data.pressure_s != 0) // S口压力不为0的情况下才读取A口和B口的压力
{
pressure_cross_point_last = ((rt_data.pressure_a + rt_data.pressure_b) * 0.5f / rt_data.pressure_s) * 100;
if (pressure_cross_point_last <= 40)
{
rt_data.pressure_cross_point = 0;
break;
}
else if (pressure_cross_point_last >= 80)
{
rt_data.pressure_cross_point = 0;
break;
}
rt_data.pressure_cross_point = lpf_update(&mode_get()->pressure_cross_point_lpf, pressure_cross_point_last);
}
else
{
rt_data.pressure_b = 0;
}
rt_data.pressure_b_kpa = pressure_unit2kpa(rt_data.pressure_b, udevice.press_unit);
break;
case PRESSURE_PARAM_MAX:
id = PRESSURE_PARAM_S;
BP_S_POWER_ON();
break;
default:
break;
}
wait_tick = 0;
}
else
{
if (BP_S_IS_POWER_ON() == FALSE)
{
BP_S_POWER_ON();
}
if (BP_A_IS_POWER_ON() == FALSE)
{
BP_A_POWER_ON();
}
if (BP_B_IS_POWER_ON() == FALSE)
{
BP_B_POWER_ON();
}
rt_data.pressure_s = get_pressure_limit_deal(pressure_kpa2unit(get_pressure(PRESSURE_PARAM_S), udevice.press_unit), udevice.press_unit);
if (rt_data.pressure_s != 0.0f)
{
rt_data.pressure_s_kpa = pressure_unit2kpa(rt_data.pressure_s, udevice.press_unit);
rt_data.pressure_a = get_pressure_limit_deal(pressure_kpa2unit(get_pressure(PRESSURE_PARAM_A), udevice.press_unit), udevice.press_unit);
rt_data.pressure_a_kpa = pressure_unit2kpa(rt_data.pressure_a, udevice.press_unit);
rt_data.pressure_b = get_pressure_limit_deal(pressure_kpa2unit(get_pressure(PRESSURE_PARAM_B), udevice.press_unit), udevice.press_unit);
rt_data.pressure_b_kpa = pressure_unit2kpa(rt_data.pressure_b, udevice.press_unit);
}
}
}
@ -77,189 +171,271 @@ void mode_test_process(void)
*/
void mode_travel_statistics(void)
{
static uint8_t internal_count = 0;
float32 loop = 0.0;
float32 current = 0.0f; // 输入电流
float32 deviation = 0.0f; // 系统偏差
// 输入电流
loop = get_current();
loop = get_current_deal(loop);
if (internal_count++ >= 10)
{
internal_count = 0;
rt_data.loop_current = loop;
}
else
{
if (ABS(rt_data.loop_current - loop) >= 0.05f)
{
rt_data.loop_current = loop;
}
}
current = get_current(FILTER_AVERAGE);
rt_data.loop_current = kalman_update(&mode_get()->loop_current_km, current);
// 获取目标行程
if (mode_get()->ctrl.mode == ON_LINE_MODE) // 在线模式
if (udevice.inst_mode == INST_IS)
{
rt_data.target_travel = i2psb(rt_data.loop_current);
rt_data.target_travel = (uint16_t)(rt_data.target_travel * 10) * 0.1f;
}
else if (mode_get()->ctrl.mode == OFF_LINE_MODE) // 离线模式
{
rt_data.target_travel = udevice.travel_setpoint;
}
else if (mode_get()->ctrl.mode == TEST_MODE) // 测试模式
{
}
// 目标行程处理
rt_data.target_travel = target_travel_deal(rt_data.target_travel);
pid_target = get_pid_travel(rt_data.target_travel);
show_target = get_show_travel(rt_data.target_travel);
// 实际行程处理
rt_data.actual_travel = actual_travel_deal(rt_data.actual_travel);
show_actual = get_show_travel(rt_data.actual_travel);
// show_actual = lpf_window_update(mode_get()->show_actual_lpf, show_actual);
show_actual = kalman_update(&mode_get()->show_actual_kalman, show_actual);
show_loop = lpf_window_update(mode_get()->show_loop_lpf, rt_data.loop_current);
}
/**
* @brief
* @return {*}
* @note
*/
static void pressure_statistics(void)
{
if (udevice.press_sensor_enable != TRUE)
{
return;
}
static uint8_t id = ADC_INDEX_CLOSEALL;
switch (id)
{
case ADC_INDEX_PRESSSOURCE:
rt_data.pressure_s = get_pressure(ADC_INDEX_PRESSSOURCE);
id = ADC_INDEX_PRESSOUTA;
BP_S_POWER_OFF();
BP_A_POWER_ON();
break;
case ADC_INDEX_PRESSOUTA:
rt_data.pressure_a = get_pressure(ADC_INDEX_PRESSOUTA);
id = ADC_INDEX_PRESSOUTB;
BP_A_POWER_OFF();
BP_B_POWER_ON();
break;
case ADC_INDEX_PRESSOUTB:
rt_data.pressure_b = get_pressure(ADC_INDEX_PRESSOUTB);
id = ADC_INDEX_PRESSSOURCE;
BP_B_POWER_OFF();
BP_S_POWER_ON();
break;
case ADC_INDEX_CLOSEALL:
id = ADC_INDEX_PRESSSOURCE;
BP_S_POWER_ON();
break;
default:
break;
}
}
/**
* @brief
* @return {*}
* @note TIM7中执行
*/
void mode_process(void)
{
pressure_statistics(); // 气压轮询读取
if (mode_get()->ctrl.state == FALSE) // 不进行算法控制
{
return;
}
// travel_statistics因为在flow中被更新如果UI更新时会导致延时所以在这里更新
// 系统的tick是10ms一次,200ms更新一次数据
if (FALSE == mode_get()->interface_req.mode_is_adjusting())
{
if (sys_get_tick() - mode_get()->alog_control_ticks >= 20) // 200ms
// 模拟模式通过4~20mA计算目标
if (*mode_get()->ctrl.mode == ANALOG_CTRL_MODE)
{
mode_get()->alog_control_ticks = sys_get_tick();
mode_travel_statistics();
rt_data.target_travel = i2psb(rt_data.loop_current);
rt_save.travel_set_pt = rt_data.target_travel;
}
// 数字模式通过HART指令设定目标
else if (*mode_get()->ctrl.mode == DIGITAL_CTRL_MODE)
{
rt_data.target_travel = rt_save.travel_set_pt;
}
// 测试模式:通过上位机下发目标
else if (*mode_get()->ctrl.mode == TEST_CTRL_MODE)
{
rt_data.target_travel = rt_data.test_target;
}
}
else
{
if (sys_get_tick() - mode_get()->alog_control_ticks >= 100) // 1000ms
{
mode_get()->alog_control_ticks = sys_get_tick();
mode_travel_statistics();
}
}
// 当电流达到4mA时才进行控制
if (rt_data.loop_current >= LOOP_CURRENT_MIN)
{
if (udevice.dev_algorithm_mode == MODE_CONSTANT_CONTROL_ALGORITHM)
{
}
else if (udevice.dev_algorithm_mode == MODE_SPEED_CONTROL_ALGORITHM)
{
}
else if (udevice.dev_algorithm_mode == MODE_FREQUENCY_DOMAIN_CONTROL_ALGORITHM)
{
mode_pwmp_hd_process();
}
else if (udevice.dev_algorithm_mode == MODE_VARIABLE_FREQUENCY_CONTROL_ALGORITHM)
if (*mode_get()->ctrl.mode == TEST_CTRL_MODE)
{
rt_data.target_travel = rt_data.test_target;
}
else
{
DBG_ASSERT(FALSE __DBG_LINE);
rt_data.target_travel = 0;
// 手动加载模式
if (udevice.manual_loader == ALLOW_SERVO_CTRL)
{
rt_data.target_travel = i2psb(rt_data.loop_current);
rt_save.travel_set_pt = rt_data.target_travel;
}
}
}
// 目标行程处理
if (udevice.crc != 0)
{
rt_data.target_travel = target_travel_deal(rt_data.target_travel);
}
rt_data.pid_target = get_pid_travel(rt_data.target_travel);
if (rt_data.pid_target > 60)
{
__NOP();
}
// 实际行程处理
if (rt_data.actual_travel > udevice.cutoff_limit_lo && rt_data.actual_travel < udevice.cutoff_limit_hi)
{
deviation = udevice.deviation;
}
rt_data.servo_feedback = rt_data.actual_travel + deviation;
rt_data.crossover_out_u = get_actual_travel_adc();
// 显示内容
rt_data.show_target = get_show_travel(rt_data.target_travel);
if (ABS(rt_data.target_travel - rt_data.show_target) > MA_TO_PERCENT_01)
{
rt_data.show_target = get_show_travel(rt_data.target_travel);
lpf_window_reset(&mode_get()->show_target_window);
}
else
{
pdctrl_out(0);
rt_data.show_target = get_show_travel(rt_data.target_travel);
rt_data.show_target = lpf_window_update(&mode_get()->show_target_window, rt_data.show_target);
}
rt_data.show_actual = get_show_travel(rt_data.servo_feedback);
rt_data.show_actual = get_show_actual_travel(rt_data.show_target, rt_data.show_actual, 0.1f);
rt_data.show_loop = rt_data.loop_current;
}
// 行程统计
static void mode_stroke_statistics(void)
{
static float32 last_travel = 0.0f;
static float32 last_target = 0.0f;
float32 err = ABS(rt_data.pid_actual - last_travel);
float32 err_target = ABS(rt_data.pid_target - last_target); // 目标位置的差值
float32 err_move = ABS(rt_data.pid_actual - last_target); // 实际位置和上次目标位置的差值
float32 err_act = ABS(rt_data.pid_actual - rt_data.pid_target); // 实际位置和目标位置的差值
if (mode_get()->interface_req.mode_is_adjusting() == FALSE) // 不在整定中
{
// 累计行程
if (err >= udevice.travel_sum_dead)
{
rt_save.travel_accum += err;
last_travel = rt_data.pid_actual;
}
// 设定的目标位置-当前目标位置>=死区
if (err_target >= udevice.act_sum_dead)
{
// 移动的距离大于等于死区,实际距离目标位置小于死区
if ((err_move >= udevice.act_sum_dead) && (err_act < udevice.act_sum_dead))
{
last_target = rt_data.pid_target;
rt_save.cycle_count++;
}
}
else
{
// 实际位置和目标位置差值大于死区,移动距离大于死区
if ((err_act > udevice.act_sum_dead) && (err > udevice.act_sum_dead))
{
rt_save.cycle_count++;
}
}
}
}
/*********************************************************************************************************************/
/**
* @brief
* @brief
* @param {uint8_t} work_mode
* @return {*}
* @note
*/
void mode_detection(void)
void mode_master_detection(void)
{
mode_get()->ctrl.mode = deal_dev_work_mode();
switch (mode_get()->ctrl.mode)
switch (*mode_get()->ctrl.mode)
{
case ON_LINE_MODE:
case OFF_LINE_MODE:
case WAIT_MODE:
if (mode_get()->ctrl.state != TRUE)
case DIGITAL_CTRL_MODE:
case ANALOG_CTRL_MODE:
{
if (udevice.inst_mode == INST_IS || udevice.manual_loader == ALLOW_SERVO_CTRL)
{
mode_get()->ctrl.state = TRUE;
pdctrl_run(); // 输出软使能
if (mode_get()->ctrl.state != TRUE)
{
// 当前控制算法模块从禁止到允许
mode_get()->ctrl.state = TRUE;
mode_get()->interface_req.mode_process_start();
pdctrl_run(); // 输出软使能
}
}
break;
case FORBIDEN_MODE:
if (mode_get()->ctrl.state != FALSE)
else
{
mode_get()->ctrl.state = FALSE;
pdctrl_stop(); // 输出软禁止
}
break;
case TEST_MODE:
}
case TEST_CTRL_MODE:
mode_get()->ctrl.state = TRUE;
break;
case STOP_MODE: // 停机
mode_get()->ctrl.state = FALSE;
// 关闭LCD
// 关闭诊断
// 由各自模块处理
break;
case WAIT_MODE: // 待机
mode_get()->ctrl.state = FALSE;
mode_test_process();
break;
default:
break;
}
}
/**
* @brief
* @return {*}
* @note
*/
void mode_ctrl_gather(void)
{
if (mode_get()->ctrl.state == FALSE || mode_get()->positioner_model >= POSITIONER_MODEL_MAX) // 不进行算法控制
{
return;
}
if (mode_get()->interface_req.mode_is_adjusting() == FALSE)
{
mode_travel_statistics();
mode_stroke_statistics();
}
mode_pressure_statistics(); // 气压轮询读取
}
/**
* @brief
*
*
*/
void mode_ctrl_output(void)
{
if (*mode_get()->ctrl.mode == DIGITAL_CTRL_MODE ||
*mode_get()->ctrl.mode == ANALOG_CTRL_MODE)
{
actual_travel_deal(rt_data.actual_travel); // 实际行程处理,对外输出
}
else if (*mode_get()->ctrl.mode == TEST_CTRL_MODE)
{
if (calib_param[CALIBPARA_VIP].is_calibration == TRUE)
{
pwm_output_position(rt_data.show_target);
}
else
{
pwm_duty2current(rt_data.loop_current);
}
}
else
{
actual_travel_deal(0);
}
}
/**
* @brief
* @return {*}
* @note TIM7中执行
*/
void mode_ctrl_process(void)
{
if (mode_get()->ctrl.state == FALSE || mode_get()->positioner_model >= POSITIONER_MODEL_MAX) // 不进行算法控制
{
return;
}
mode_travel_statistics();
// 当电流达到4mA时才进行控制
switch (udevice.dev_algorithm_mode)
{
case MODE_CONSTANT_CONTROL_ALGORITHM:
mode_dac_process();
break;
case MODE_SPEED_CONTROL_ALGORITHM:
mode_pwmp_process();
break;
case MODE_FREQUENCY_DOMAIN_CONTROL_ALGORITHM:
mode_pwmp_hd_process();
break;
case MODE_VARIABLE_FREQUENCY_CONTROL_ALGORITHM:
mode_control_process();
break;
default:
DBG_ASSERT(FALSE __DBG_LINE);
break;
}
mode_diagnosis_inspection();
}
/**
* @brief
* @param {BOOL} state
* @return {*}
* @note
*/
void mode_enter_test(test_item_e item)
{
mode_get()->test_item = item;
}
/**
* @brief
* @return {*}
@ -267,32 +443,39 @@ void mode_detection(void)
*/
void mode_init(void)
{
osel_memset((uint8_t *)&_mode, 0, sizeof(mode_t));
rt_data.mode_auto_load = (LL_TIM_GetAutoReload(MODE_TIM) + 1) * 0.1;
osel_memset((uint8_t *)&mode, 0, sizeof(mode_t));
mode_get()->positioner_model = udevice.dev_model;
mode_get()->alog_control_ticks = sys_get_tick();
mode_autoload_change(mode_default_autoload);
mode_get()->ctrl.mode = (uint8_t *)&udevice.control_mode;
mode_autoload_change(rt_data.mode_auto_load * 10);
// 反初始化,释放内存
mode_dac_dinit();
mode_pwmp_dinit();
mode_pwmp_hd_dinit();
mode_control_dinit();
switch (udevice.dev_algorithm_mode)
{
case MODE_CONSTANT_CONTROL_ALGORITHM:
pdctrl_init(PDCTRL_DAC);
mode_dac_init(&mode_get()->interface_req, mode_get()->positioner_model, &mode_params.dac,
mode_params_save_cb);
break;
case MODE_SPEED_CONTROL_ALGORITHM:
pdctrl_init(PDCTRL_PWMP);
pdctrl_init(PDCTRL_DAC);
mode_pwmp_init(&mode_get()->interface_req, mode_get()->positioner_model, &mode_params.pwmp,
mode_params_save_cb);
break;
case MODE_FREQUENCY_DOMAIN_CONTROL_ALGORITHM:
//pdctrl_init(PDCTRL_PWMP);
pdctrl_init(PDCTRL_DAC);
mode_pwmp_hd_init(&mode_get()->interface_req, mode_get()->positioner_model, &mode_params.mode_pwmp_hd_params,
pdctrl_init(PDCTRL_PWMP);
mode_pwmp_hd_init(&mode_get()->interface_req, mode_get()->positioner_model, &mode_params.pwmp_hd,
mode_params_save_cb);
break;
case MODE_VARIABLE_FREQUENCY_CONTROL_ALGORITHM:
pdctrl_init(PDCTRL_PWM);
pdctrl_init(PDCTRL_DAC);
mode_control_init(&mode_get()->interface_req, mode_get()->positioner_model, &mode_params.control,
mode_params_save_cb);
break;
default:
DBG_ASSERT(FALSE __DBG_LINE);
@ -310,13 +493,15 @@ void mode_init(void)
DBG_ASSERT(mode_get()->interface_req.mode_control_idle != NULL __DBG_LINE);
DBG_ASSERT(mode_get()->interface_req.mode_is_adjusting != NULL __DBG_LINE);
mode_get()->show_loop_lpf = lpf_window_init(10);
mode_get()->show_actual_lpf = lpf_window_init(10);
kalman_init(&mode_get()->loop_kalman);
kalman_init(&mode_get()->show_actual_kalman);
mode_get()->loop_kalman.filter_limit = 0.3f;
mode_get()->show_actual_kalman.filter_limit = 0.3f;
// 滤波初始化
kalman_init(&mode_get()->loop_current_km, 0.03f);
mode_get()->pressure_cross_point_lpf.alpha = 0.1;
lpf_init(&mode_get()->pressure_cross_point_lpf);
lpf_window_init(&mode_get()->show_target_window, 10);
lpf_window_init(&mode_get()->pressure_s_window, 10);
lpf_window_init(&mode_get()->pressure_a_window, 10);
lpf_window_init(&mode_get()->pressure_b_window, 10);
mode_diagnosis_init(); // 控制模块诊断初始化,必须放在rt_data.mode_auto_load之后
}
/**
@ -326,5 +511,5 @@ void mode_init(void)
*/
mode_t *mode_get(void)
{
return &_mode;
return &mode;
}

View File

@ -13,13 +13,15 @@
#include "filter.h"
#include "mode_def.h"
#include "mode_dac.h"
#include "mode_pwmp.h"
#include "mode_pwmp_hd.h"
#include "mode_control.h"
typedef enum
{
MODE_CONSTANT_CONTROL_ALGORITHM, ///< 恒定控制算法 gaopengjie
MODE_VARIABLE_FREQUENCY_CONTROL_ALGORITHM, ///< 变频控制算法 xushenghao
MODE_CONSTANT_CONTROL_ALGORITHM, ///< 恒定控制算法 gaopengjie
MODE_SPEED_CONTROL_ALGORITHM, ///< 速度控制算法 zhangxiaoming
MODE_FREQUENCY_DOMAIN_CONTROL_ALGORITHM, ///< 频域控制算法 hangdian
} mode_algorithm_e;
@ -27,21 +29,24 @@ typedef enum
/// 测试项目
typedef enum
{
NO_TEST_PROJECT = 0, // 无测试项目
MODE_DIAGNOSIS = 1, // 性能诊断
MANUAL_TEST = 2, // 手动按键测试
TEST_PROJECT_MAX,
} test_project_e;
TEST_ITEM_NONE, // 无测试项目
TEST_ITEM_DIAGNOSIS, // 性能诊断
TEST_ITEM_MANUAL, // 手动按键测试
TEST_ITEM_MAX,
} test_item_e;
typedef union
{
mode_dac_storage_data_t dac;
pwmp_storage_pars_t pwmp;
mode_pwmp_hd_storage_data_t pwmp_hd;
mode_control_storage_t control;
} mode_params_u;
typedef struct
{
mode_pwmp_hd_params_u mode_pwmp_hd_params; ///< PWMP HD模式参数
} mode_params_t;
typedef struct
{
BOOL state; // TRUE:算法控制器可以运行 FALSE:算法控制器不可以运行
uint8_t mode; // 模式
BOOL state; // TRUE:算法控制器可以运行 FALSE:算法控制器不可以运行
uint8_t *mode; // 模式
} mode_ctrl_t;
typedef struct
@ -49,21 +54,26 @@ typedef struct
mode_interface_req_t interface_req; ///< 模式接口请求
// 内部变量
uint16_t positioner_model; ///< 定位器型号
__IO test_project_e test_project; ///< 测试项目
__IO mode_ctrl_t ctrl; ///< 控制器
__IO uint32_t alog_control_ticks; ///< 算法控制数据刷新计数器
lpf_window_t *show_loop_lpf;
lpf_window_t *show_actual_lpf;
kalman_t loop_kalman;
kalman_t show_actual_kalman;
test_item_e test_item; ///< 测试项目
mode_adjust_initiate_e adjust_initiate; ///< 自整定发起方式,用于上位机整定流程
uint16_t positioner_model; ///< 定位器型号
__IO mode_ctrl_t ctrl; ///< 控制器
kalman_t loop_current_km; ///< 环路电流卡尔曼滤波器
lpf_t pressure_cross_point_lpf; ///< 压力交叉点滤波器
lpf_window_t show_target_window; ///< 显示目标滤波
lpf_window_t pressure_s_window; ///< 压力S滤波
lpf_window_t pressure_a_window; ///< 压力A滤波
lpf_window_t pressure_b_window; ///< 压力B滤波
} mode_t;
extern void mode_init(void); ///< 工作模式初始化
extern mode_t *mode_get(void); ///< 获取工作模式
extern void mode_detection(void); ///< 工作模式处理
extern void mode_travel_statistics(void); ///< 行程统计
extern void mode_process(void); ///< 算法控制模块
extern void mode_test_process(void); ///< 测试模式处理
extern void mode_init(void); ///< 工作模式初始化
extern void mode_enter_test(test_item_e item); ///< 模式测试
extern mode_t *mode_get(void); ///< 获取工作模式
extern void mode_master_detection(void); ///< 工作模式处理
extern void mode_travel_statistics(void); ///< 行程统计
extern void mode_ctrl_process(void); ///< 算法控制模块
extern void mode_ctrl_gather(void); ///< 算法控制模块数据采集
extern void mode_ctrl_output(void); ///< 控制输出模式函数
extern void mode_pressure_statistics(void); ///< 压力统计
#endif

View File

@ -0,0 +1,72 @@
/**
* @file mode_control.h
* @author xushenghao
* @date 2024-03-01 00:30:20
* @brief DACPWM变频
* @copyright Copyright (c) 2024 by xxx, All Rights Reserved.
*/
#ifndef __MODE_CONTROL_H
#define __MODE_CONTROL_H
#include "lib.h"
#include "filter.h"
#include "mode_def.h"
#include "mode_control_def.h"
#include "mode_control_adjust.h"
#define MODE_CONTROL_CYCLE_25 249 // 控制周期25ms
#define MODE_CONTROL_CYCLE_50 499 // 控制周期50ms
#define MODE_CONTROL_CYCLE MODE_CONTROL_CYCLE_25 // 控制周期
#define MODE_CONTROL_CYCLE_BASE 100 // 控制周期基准线
/**
* @brief
*
* 使
*
* @param req
* @param positioner_model
* @param params
* @param params_save_cb
*/
extern void mode_control_init(mode_interface_req_t *req, uint16_t positioner_model, mode_control_storage_t *params, void (*params_save_cb)(void));
/**
* @brief
*
*
*/
extern void mode_control_dinit(void);
/**
* @brief
*
* 使
*
* @param data
*/
extern void mode_control_output(uint16_t data);
/**
* @brief
*
*
*/
extern void mode_control_process(void);
/**
* @brief
*
*
*/
extern void mode_control_compensate(void);
/**
* @brief
*
* 使
*
* @param state
*/
extern void mode_control_state_set(mode_control_process_state_e state);
#endif // __MODE_CONTROL_H

View File

@ -0,0 +1,83 @@
#ifndef __MODE_CONTROL_ADJUST_H__
#define __MODE_CONTROL_ADJUST_H__
#include "mode_control_def.h"
typedef enum
{
CONTROL_ADJUST_IDEL, // 空闲
CONTROL_ADJUST_UPWARD_SLOPE, // 上升斜坡
CONTROL_ADJUST_DOWNWARD_SLOPE, // 下降斜坡
CONTROL_ADJUST_TUNING, // 自整定
CONTROL_ADJUST_SAVE, // 存储变量
CONTROL_ADJUST_BLEEDING, // 在整定状态中放气
CONTROL_ADJUST_AERATE, // 在整定状态中充气
CONTROL_ADJUST_STOP,
CONTROL_ADJUST_FAIL, // 整定失败
CONTROL_ADJUST_PAUSE, // 整定暂停
CONTROL_ADJUST_TEST,
} mode_control_adjust_state_e; // 整定状态
#define CONTROL_ADJUST_STEP LCD_ADJUST_STOP // 整定步骤
typedef struct
{
uint16_t out;
uint16_t psb;
uint16_t ipsb;
float32 electric;
} mode_control_adjust_data_t;
typedef struct
{
uint16_t enter_count1; // 进入次数
mode_control_adjust_state_e adjust_state;
mode_control_adjust_state_e adjust_state2;
uint16_t *output; // 输出
__IO int16_t wait_count;
__IO uint16_t current_psi_a; // 当前位置的A压力
__IO uint16_t last_psi_a; // 上一次位置的A压力
__IO uint16_t current_psb; // 当前位置AD值
BOOL wait_hode_flag; // 等待保持标志
BOOL adc_0_100_flag; // 判断0-100移动过程中ad值是增大还是减少TRUE 增大FALSE 减小
uint16_t adc_record_0; // 记录放气时阀门最小位置ad值
uint16_t adc_record_1; // 记录放气时阀门最小位置ad值
uint16_t adc_record_2; // 记录充气时阀门最大位置ad值
uint16_t adc_diff;
uint16_t arr_record_0;
uint16_t arr_record_1;
uint16_t arr_record_2;
uint16_t bleeding_min_arr; // 最小放气值
uint16_t bleeding_max_arr; // 最大放气值
uint16_t balance_arr; // 平衡值
uint16_t aerate_min_arr; // 最小充气值
uint16_t aerate_max_arr; // 最大充气值
uint32_t all_open_time; // 全开时间
uint32_t all_close_time; // 全关时间
uint32_t tmp_time; // 临时用来记录全开全关时间
__IO uint16_t arr_current; // 当前推动阀门的计数器
__IO uint16_t arr_last; // 上一次计数器值
uint8_t test_index; // 测试索引
BOOL ipsb_enable; // 是否启用ipsb
mode_control_storage_t storage_data; // 存储数据,用于保留原始数据
stable_percent_step_t stable_percent_steps[EQUILIBRIUM_POINT_END]; // 稳定百分比
mode_control_adjust_data_t ads[800]; // 整定过程中的数据
uint16_t ads_index; // 整定数据索引
mode_control_adjust_tuning_pi_state_e tuning_pi_state; // 自整定状态
mode_control_move_dir_e tuning_pi_dir; // 自整定方向
uint8_t tuning_pi_sst_index;
} mode_control_adjust_t;
extern mode_control_adjust_t *mode_control_adjust;
extern mode_control_adjust_t *mode_control_adjust_get(void);
extern void mode_control_adjust_process(uint8_t *state);
extern void mode_control_adjust_stop(uint8_t *state);
#endif // __MODE_CONTROL_ADJUST_H__

View File

@ -0,0 +1,290 @@
#ifndef __MODE_CONTROL_DEF_H__
#define __MODE_CONTROL_DEF_H__
#include "lib.h"
#include "filter.h"
#include "mode_def.h"
#include "pid.h"
#include "params.h"
#include "pdctrl.h"
#define MODE_CONTROL_ADJUST_DIFF_ADC_MAX 6 // 在整定过程中判断是否稳定的AD误差大于此值则认为不稳定
#define MODE_CONTROL_STABLE_STEP 1 // 稳定步长
#define MODE_CONTROL_STABLE_STEP_COUNT ((100 / MODE_CONTROL_STABLE_STEP) + 1) // 稳定步长个数 0-100
#define MODE_CONTROL_UNDER_LINE_MIN 10.0f // 下限最小值
#define MODE_CONTROL_UNDER_LINE 25.0f
#define MODE_CONTROL_STEP_THRESHOLD 10 // 阶跃阈值
#define MODE_CONTROL_UPWARD_DOWNWARD_TICKS 3 // 上升下降时间tick数
#define MODE_CONTROL_MAX_OUTPUT_CURRENT_GPS2000 1.8f
#define MODE_CONTROL_MIN_OUTPUT_CURRENT_GPS2000 0.2f
#define MODE_CONTROL_MAX_OUTPUT_CURRENT_GPS3000 1.7f
#define MODE_CONTROL_MIN_OUTPUT_CURRENT_GPS3000 0.3f
#define MODE_CONTROL_TARGET_ARRAY_SIZE 50 // 目标数组大小
#define MODE_CONTROL_OUTPUT_STABLE_ARRAY_SIZE 40 // 输出数组大小,用于判断稳定输出
#define MODE_CONTROL_ADJUST_TEMPERATURE_UNDER -30 // 整定温度下限
#define MODE_CONTROL_ADJUST_TEMPERATURE_UPLINE 30 // 整定温度上限
#define MODE_CONTROL_STABLE_TEMPERATURE 10 // 温差在xx度以内,使用稳定值
#define MODE_CONTROL_ADJUST_BASE_DAC_2000 500 // DAC整定启动值
#define MODE_CONTROL_ADJUST_BASE_DAC_3000 1000 // DAC整定启动值
typedef enum
{
CONTROL_MOVE_DIR_NONE,
CONTROL_MOVE_DIR_UPWARD, // 上升
CONTROL_MOVE_DIR_DOWNWARD, // 下降
CONTROL_MOVE_DIR_STOP, // 停止
} mode_control_move_dir_e;
typedef enum
{
// 取消
CONTROL_FINE_CANCEL,
// 使用平衡值
CONTROL_FINE_BALANCE,
// 使用动态值
CONTROL_FINE_DYNAMIC,
} mode_control_fine_tuning_e;
typedef enum
{
CONTROL_PROCESS_CONTROL, // 控制
CONTROL_PROCESS_ADJUST, // 整定
CONTROL_PROCESS_ADJUST_STOP, // 整定停止
CONTROL_PROCESS_MANUAL, // 手动
CONTROL_PROCESS_STOP, // 停止
CONTROL_PROCESS_CONTROL_FAIL, // 失败,无法控制
CONTROL_PROCESS_STROKE_TEST, // 行程限位测试
} mode_control_process_state_e; // 处理状态
typedef enum
{
EQUILIBRIUM_POINT_START = 0,
EQUILIBRIUM_POINT_0,
EQUILIBRIUM_POINT_10,
EQUILIBRIUM_POINT_20,
EQUILIBRIUM_POINT_30,
EQUILIBRIUM_POINT_40,
EQUILIBRIUM_POINT_50,
EQUILIBRIUM_POINT_60,
EQUILIBRIUM_POINT_70,
EQUILIBRIUM_POINT_80,
EQUILIBRIUM_POINT_90,
EQUILIBRIUM_POINT_100,
EQUILIBRIUM_POINT_END,
} mode_control_adjust_tuning_pi_state_e;
typedef struct
{
uint8_t step;
uint16_t driver_output;
float32_t current;
} stable_percent_step_t; // 稳定百分比
typedef struct
{
pdctrl_mode_e driver_mode; // 驱动模式 DAC/PWM
tuned_result_e tuned_flag; // 整定标志 0未整定1整定中2整定成功3整定失败
mode_adjust_error_e tuned_err_code; // 整定错误码
uint8_t process_change_flag; // 磁条接收的反馈电压由大变小 0 由小变大 1
uint16_t ad_0;
uint16_t ad_100;
uint16_t ad_diff;
uint16_t bleeding_min_arr; // 在100的位置获取的放气值
uint16_t bleeding_max_arr; // 在0的位置获取的放气值
uint16_t aerate_min_arr; // 在100的位置获取的充气值
uint16_t aerate_max_arr; // 在0的位置获取的充气值
uint16_t bleeding_arr;
uint16_t aerate_arr;
float32 bleeding_max_current; ///< 最大放气电流(毫安,放大100倍0.01ma=1)
float32 bleeding_min_current; ///< 最小放气电流(毫安放大100倍, 0.01ma=1)
float32 aerate_min_current; ///< 最小充气电流(毫安,放大100倍0.01ma=1)
float32 aerate_max_current; ///< 最大充气电流(毫安,放大100倍0.01ma=1)
float32 kp;
float32 ki;
float32 kd;
float32 move_speed_up; // 上升移动速度
float32 move_speed_down; // 下降移动速度
float32 all_open_time; // 全开时间
float32 all_close_time; // 全关时间
int8_t stable_temperature; // 整定稳定温度值
stable_percent_step_t stable_percent_steps[21]; // 稳定百分比
} mode_control_storage_t;
typedef struct
{
BOOL first_run; // 首次运行
uint16_t enter_count; // 进入次数
uint16_t enter_count1; // 进入次数
uint16_t enter_count2; // 持续输出相同次数
pid_common_position_t *position;
// 参数
struct
{
uint16_t arr_min;
uint16_t arr_max;
uint16_t arr_bleeding;
uint16_t arr_aerate;
float32 slope; // 斜率
float32 sv; // 平滑系数
float32 internal_dead_zone; // 内部死区
feedback_char_e feedback_char; // 反馈特性
} params;
// 实际数据
struct
{
uint16_t current_adc; // 当前位置反馈的AD值
uint16_t balance_arr; // 平衡值
int16_t balance_arr_correct; // 平衡值校正
float32 balance_percent; // 平衡值百分比
float32 output; // 输出值
float32 target; // 目标值(一阶滞后滤波法处理后的数据)
float32 target_real; // 目标值(真实值)
float32 feedback; // 反馈值
float32 error; // 实际偏差
float32 target_list[MODE_CONTROL_TARGET_ARRAY_SIZE]; // 目标数组
} real_data;
// 稳定控制
struct
{
BOOL flag; // 稳定标志
mode_control_fine_tuning_e fine_tuning; // 精调模式
int16_t offset; // 稳定偏移值
uint32_t count; // 稳定状态次数
uint16_t arr; // 稳定数值
float32 percent; // 稳定百分比
float32 percent_last; // 稳定百分比
float32 current; // 稳定电流
float32 output; // 稳定输出值
float32 output_list[MODE_CONTROL_OUTPUT_STABLE_ARRAY_SIZE]; // 稳定输出数组
} stable;
struct
{
BOOL flag; // 阶跃标志
BOOL change; // 阶跃变化标志
BOOL access; // 进入PID微调控制区域确认
uint16_t count; // 进入PID控制区域确认次数
} step;
// 行程统计
struct
{
BOOL flag; // 行程标志 0未到位 1到位
mode_control_move_dir_e dir; // 行程方向
mode_control_move_dir_e step_dir; // 阶跃时行程方向
uint16_t need_ticks; // 需要的时间
uint16_t used_ticks; // 已经使用的时间
float32 stroke_speed; // 行程速度
float32 stroke_dead_upper_limit; // 行程死区上限
float32 stroke_dead_lower_limit; // 行程死区下限
float32 start_position; // 启动时位置
float32 target_position; // 到达目标位置
} stroke;
struct
{
// 0-100区间电流
float32 current_0_100;
// 10-90区间电流
float32 current_10_90;
// 平衡区间占比
float32 balance_percent;
// 其余占比
float32 other_percent;
// 向上偏移
float32 up_offset;
// 向下偏移
float32 down_offset;
} output_range;
struct
{
float32 min;
float32 max;
float32 balance;
} output_percent;
} mode_control_params_t;
typedef struct
{
kalman_t actual_km;
lpf_t target_lpf;
lpf_window_t ctrl_output_lpf_window;
} mode_control_filter_t;
typedef struct
{
uint16_t output; // 输出
uint16_t manual_output; // 手动模式下输出
struct
{
uint16_t default_min_value; // 默认值 DAC:0 PWM:3999
uint16_t positioner_model; // 定位器型号
uint16_t wait_count_max; // 等待次数最大值
float32 max_current;
float32 min_current;
} params;
struct
{
uint16_t current_adc; // 当前位置反馈的AD值
uint16_t current_ipsb_adc; // 当前小回路反馈的AD值
float32 current_electric; // 当前电流
} real_data;
struct
{
uint8_t process_state; // 处理状态机
uint8_t adjust_state; // 整定状态机
uint8_t diagnosis_state; // 诊断状态机
uint8_t lcd_adjust_state; // LCD自整定流程状态
} fsm;
mode_control_storage_t *storage; // 存储数据
mode_control_params_t control_data; // 控制
mode_control_filter_t filter; // 滤波
void (*params_save_cb)(void); // 参数保存回调函数
} mode_control_t;
extern mode_control_t *mode_control;
extern float32 mode_control_get_kp(void);
extern float32 mode_control_get_ki(void);
extern float32 mode_control_get_kd(void);
extern float32 mode_control_get_slope(uint16_t arr_max, uint16_t arr_min);
extern float32 mode_control_get_percent_upline(void);
extern float32 mode_control_get_percent_underline(void);
extern uint16_t mode_control_get_default_min_value(void);
extern uint16_t mode_control_get_default_max_value(void);
extern uint16_t mode_control_get_default_max_value_allow(void);
extern uint16_t mode_control_get_default_min_value_allow(void);
extern uint16_t mode_control_get_wait_ticks(uint16_t time);
extern uint16_t mode_control_get_stable_arr(float32 target);
extern uint16_t mode_control_percent_convert_arr(float32 percent);
extern float32 mode_control_arr_convert_percent(int16_t arr);
extern void mode_control_stable_insert(float32 array[], uint8_t len, float32 value);
extern BOOL mode_control_stable_check_deviation(float32 array[], uint8_t len, float32 err);
extern void mode_control_bluetooth_output_trip(float32 trip);
extern void mode_control_bluetooth_output_control(void);
extern void mode_control_pid_load(void);
extern void mode_control_set_parms(void);
extern void mode_control_start(void);
extern void mode_control_execute(void);
extern void mode_control_set_magnetic_stripe_specifications(void);
extern float32 mode_control_add_offset(float32 value);
#endif // __MODE_CONTROL_DEF_H__

View File

@ -0,0 +1,290 @@
#ifndef __MODE_DAC_H__
#define __MODE_DAC_H__
#include "lib.h"
#include "filter.h"
#include "mode_def.h"
#define G_PID_FUZZY 0 // 模糊PID
#define FSM_SET(st) BIT_SET(st, BIT7)
#define FSM_CLR(st) BIT_CLR(st, BIT7)
#define FSM_IS_WAIT(st) (st & BIT7)
// DAC工作任务枚举
typedef enum
{
DAC_PROCESS_IDLE, ///< 空闲
DAC_PROCESS_CONTROL, ///< 开始控制
DAC_PROCESS_CONTROL_STOP, ///< 控制结束
DAC_PROCESS_ADJUST, ///< 开始整定
DAC_PROCESS_ADJUST_STOP, ///< 整定结束
DAC_PROCESS_TEST, ///< 测试
} mode_dac_process_state_e;
// 整定步骤枚举
typedef enum
{
ADJUST_POS_100, ///< 获取最大反馈位置
ADJUST_POS_0, ///< 获取最小反馈位置
ADJUST_SAVE_POS, ///< 记录阀门安装方向
ADJUST_ALL_OPEN_TIME, ///< 记录全开时间
ADJUST_ALL_CLOSE_TIME, ///< 记录全关时间
ADJUST_PARAM_PREPARE, ///< 参数保存
ADJUST_DAC_BOTTOM_START, ///< 获取起点启动电流
ADJUST_DAC_TOP, ///< 获取阀门顶点电流大小
ADJUST_DAC_TOP_START, ///< 防止顶点电流过大,向下调整
ADJUST_DAC_ORIGN, ///< 防止起点启动电流过大,向下微调
ADJUST_DAC_END, ///< 整定顶点电流,等待顶点电流稳定
ADJUST_DAC_END_AMEND, ///< 微调顶点电流
ADJUST_DAC_BOTTOM, ///< 测量排底电流
ADJUST_CTRL_CURRUNT, ///< 保存测试电流
ADJUST_PID, ///< 计算PID参数
ADJUST_STEP, ///< 以10%步进,记录各点位稳定值
ADJUST_SAVE_ALL, ///< 保存所有参数
ADJUST_STOP, ///< 整定结束
} mode_dac_adjust_e;
// PID参数整定步骤枚举
typedef enum
{
G_PID_WAIT_ORIGN,
G_PID_JUMP,
G_PID_OVER,
} g_pid_adjust_e;
// 阶跃步骤枚举
typedef enum
{
G_STEP_TAO,
G_STEP_K,
G_STEP_GOBACK,
G_STEP_T1,
G_STEP_T2,
G_STEP_SAVE,
} g_step_e;
// 显示整定步骤枚举
typedef enum
{
LCD_ADJUST_POS = 1,
LCD_ADJUST_CTRL_PARAM,
LCD_ADJUST_MEASURE,
LCD_ADJUST_PID,
LCD_ADJUST_SAVE_ALL,
} mode_dac_lcd_e;
#define DAC_ADJUST_STEP LCD_ADJUST_SAVE_ALL // 整定步骤
// 整定状态枚举
typedef enum
{
ADJUST_WAIT,
ADJUST_ONGING,
ADJUST_OK,
ADJUST_TAO_ERR,
ADJUST_JUMP_ERR_1,
ADJUST_JUMP_ERR_2,
ADJUST_JUMP_ERR,
ADJUST_DAC_MAX_ERR,
ADJUST_DAC_MIN_ERR,
ADJUST_DAC_START0_ERR,
ADJUST_DAC_START100_ERR,
ADJUST_DAC_ORIGN_ERR,
ADJUST_DAC_START_ERR,
ADJUST_DAC_END_ERR,
ADJUST_DAC_AMEND_ERR,
ADJUST_POS100_ERR,
ADJUST_POS0_ERR,
} dac_adjust_state_e;
// 执行/不执行
typedef enum
{
EXECUTE_NONE = 0, // 不执行操作
EXECUTE_DAC = 1, // 执行DAC输出
} execute_e;
// 充气/放气
typedef enum
{
AIR_INFLATE, // 充气
AIR_ESCAPE, // 放气
} air_opt_e;
// 减/加
typedef enum
{
SUB = 0, // 减
ADD = 1, // 加
} cal_opt_e;
// 操作状态
typedef enum
{
ONGOING = 2, // 过程
WAIT = 3, // 等待
NEAR = 4, // 接近
FAR = 5, // 背离
} state_opt_e;
/*********************************** 执行器 ***********************************/
typedef struct
{
execute_e code; ///< 操作标志
uint16_t dac; ///< DAC值
} execute_rsp_t;
/*********************************** 滤波器 ***********************************/
typedef struct
{
lpf_window_t handle;
uint16_t value;
} win_filter_t;
/*********************************** 控制任务 ***********************************/
typedef struct
{
float32 ctrl_target; // 目标位置
float32 last_target; // 上次目标
float32 ctrl_feedback; // 实际位置
float32 last_feedback; // 上次实际只有目标位置改变大于0.2才会更新
float32 real_error; // 误差
float32 update_error; // 更新误差,目标位置与上次实际位置的差值
BOOL dir; // 方向
uint16_t dac_max; // 输出最大值
uint16_t dac_min; // 输出最小值
float32 output; // 输出值
float32 ratio; // 输出值百分比
float32 kf; // 增益
BOOL switch_flag; // 开关阀标志
BOOL callback_flag; // 超调标志
BOOL unreach_flag; // 欠调标志
BOOL update_flag; // 目标更新标志
BOOL dead_flag; // 死区稳定标志
float32 current; // 电流
__IO int16_t ctrl_cycle; // 控制周期
__IO uint32_t enter_count; // 执行时间计数
__IO uint32_t dead_count; // 死区时间计数
} mode_dac_master_t;
/*********************************** 整定任务 ***********************************/
// PID参数整定
typedef struct
{
g_pid_adjust_e pid_adjust_state; // 当前PID参数整定步骤
g_pid_adjust_e pid_adjust_next_state; // 下个PID参数整定步骤
g_step_e step_state; // 阶跃步骤
float32 tao; // 滞后时间
float32 k; // k值
float32 t, t1, t2; // t值
// 临时变量
BOOL jump_flag, t1_flag, t2_flag;
float32 t1_pos, t2_pos, cur_pos, last_pos;
uint32_t opt_cnt, wait_cnt;
} adjust_pid_t;
// 整定时序
typedef struct
{
uint8_t visit_tag;
int32_t visit_cnt;
int32_t visit_cycle;
} adjust_timer_t;
typedef struct
{
BOOL adjust_enable; // 整定使能
mode_dac_adjust_e adjust_state; // 当前整定状态
mode_dac_adjust_e adjust_next_state; // 下次整定状态
uint8_t adjust_execute_state; // 执行整定状态
uint8_t adjust_lcd_state; // 显示整定状态
adjust_pid_t gpid; // PID参数整定
adjust_timer_t timer; // 整定时序
// 临时变量
float32 cur_pos, psb_pos; ///< 当前位置/初始位置
float32 speed; ///< 每500ms动作百分比速度
uint16_t up_offset; ///< 上行阶跃值偏移量
uint16_t lo_offset; ///< 下行阶跃值偏移量(量程的百分之一)
uint16_t psb_adc, cur_adc, last_adc, dif_adc, err_adc;
uint16_t cur_dac, start_dac;
uint8_t index;
uint32_t cnt;
} mode_dac_adjust_t;
/*********************************** 测试任务 ***********************************/
typedef struct
{
uint16_t output;
uint16_t megnet_adc;
uint16_t minor_adc;
float32 current;
} mode_dac_test_t;
/*********************************** 保存参数 ***********************************/
typedef struct
{
uint8_t dev_tuned_flag;
uint16_t dev_magnet_0; // 大回路0位置
uint16_t dev_magnet_100; // 大回路100位置
uint16_t dev_minor_0; // 小回路0位置
uint16_t dev_minor_100; // 小回路100位置
uint16_t invert_feedback; // 定位器安装方向
uint16_t dev_orign; // 起点值,阀门从起点启动的电流值,数字量
uint16_t dev_end; // 终点值阀门稳定在99%的电流值,数字量
uint16_t dev_top; // 冲顶值,阀门最高点所需要输出的电流值
uint16_t dev_bottom; // 排底值阀门维持在0%的电流值
float32 dev_lo_step[11]; // 排底值
float32 dev_up_step[11]; // 阶跃值
uint32_t dev_open_time; // 全开时间
uint32_t dev_close_time; // 全关时间
float32 dev_cur_lower; // 电流下限,模拟量
float32 dev_cur_upper; // 电流上限,模拟量
float32 dev_kp;
float32 dev_ki;
float32 dev_kd;
float32 dev_kv;
float32 dev_kf;
} mode_dac_storage_data_t;
/*********************************** 模式管理 ***********************************/
typedef struct
{
mode_dac_process_state_e process_state; // 任务
execute_rsp_t dac_rsp; // 执行器
win_filter_t magnet_filter; // 磁条滤波器
win_filter_t minor_filter; // 小回路滤波器
mode_dac_master_t master; // 控制任务
mode_dac_adjust_t adjust; // 整定任务
mode_dac_test_t test; // 测试任务
mode_dac_storage_data_t *save; // 保存参数
void (*params_save_cb)(void); // 保存函数
} mode_dac_t;
/*********************************** 接口声明 ***********************************/
// DAC模式句柄
extern mode_dac_t *mode_dac;
// DAC模式初始化
void mode_dac_init(mode_interface_req_t *req, uint16_t positioner_model, mode_dac_storage_data_t *params, void (*params_save_cb)(void));
// DAC模式反初始化
void mode_dac_dinit(void);
// DAC模式进程
void mode_dac_process(void);
#endif

View File

@ -1,8 +1,52 @@
#ifndef __MODE_DEF_H__
#define __MODE_DEF_H__
#define MODE_DIAGNOSIS_STORAGE_SIZE (12 * 1024) // 诊断存储空间大小
#define DIAGNOSIS_EPM_DBG 0 // 测试:诊断EPM调试
typedef enum
{
ADJUST_INITIATE_NONE = 0, // 无
ADJUST_INITIATE_INTERNAL, // 内部发起
ADJUST_INITIATE_EXTERNAL, // 外部发起
} mode_adjust_initiate_e; // 自整定发起方式
typedef enum
{
// 整定无错误
ADJUST_STEP_NONE_ERROR = 0,
// 输入气源压力:输入气源压力错误
ADJUST_STEP_INPUT_PRESSURE_ERROR,
// A口压力A口压力错误
ADJUST_STEP_A_PRESSURE_ERROR,
// B口压力B口压力错误
ADJUST_STEP_B_PRESSURE_ERROR,
// 小回路:小回路错误
ADJUST_STEP_SMALL_LOOP_ERROR,
// IP回路电流异常
ADJUST_STEP_IP_LOOP_ERROR,
// EPM驱动异常
ADJUST_STEP_EPM_LOOP_ERROR,
// 查找上下限位:下限位错误
ADJUST_STEP_FIND_LOWER_LIMIT_ERROR,
// 查找上下限位:上限位错误
ADJUST_STEP_FIND_UPPER_LIMIT_ERROR,
// 启动电流范围:启动电流范围错误
ADJUST_STEP_START_CURRENT_RANGE_ERROR,
// 最终位置电流范围:最终位置电流范围错误
ADJUST_STEP_FINAL_CURRENT_RANGE_ERROR,
// 起终点电流差:起终点电流差错误
ADJUST_STEP_START_FINAL_CURRENT_DIFF_ERROR,
// 磁条最小值:磁条最小值错误
ADJUST_STEP_MAGNETIC_MIN_ERROR,
// 磁条最大值:磁条最大值错误
ADJUST_STEP_MAGNETIC_MAX_ERROR,
// 10%位置的平衡值10%位置的平衡值错误
ADJUST_STEP_10_PERCENT_BALANCE_ERROR,
// 50%位置的平衡值50%位置的平衡值错误
ADJUST_STEP_50_PERCENT_BALANCE_ERROR,
// 执行机构:震荡、超调
ADJUST_STEP_EXECUTE_MECHANISM_ERROR,
// 整定超时
ADJUST_STEP_TIMEOUT_ERROR,
} mode_adjust_error_e; // 整定错误码
typedef struct
{
@ -35,22 +79,15 @@ typedef enum
typedef enum
{
// 这一部分只用于LCD整定界面
LCD_ADJUST_IDEL = 1, // 准备中
LCD_ADJUST_POSITION0, // 位置0
LCD_ADJUST_POSITION100, // 位置100
LCD_ADJUST_TIMER, // 计时
LCD_ADJUST_TUNING, // 自整定
LCD_ADJUST_SAVE, // 存储变量
LCD_ADJUST_STOP, // 停止
} lcd_adjust_step_e; // 整定步骤
typedef enum
{
MODE_DIAGNOSIS_EPM_STEP_ANCHOR_POINT = 1, // 第一步先找锚点
MODE_DIAGNOSIS_EPM_STEP_AERATE = 2, // 最大充气时间
MODE_DIAGNOSIS_EPM_STEP_BLEEDING = 3, // 最大放气时间
MODE_DIAGNOSIS_EPM_STEP_CONTROL = 4, // 控制
} mode_diagnosis_epm_step_e;
LCD_ADJUST_STEP_1 = 1,
LCD_ADJUST_STEP_2,
LCD_ADJUST_STEP_3,
LCD_ADJUST_STEP_4,
LCD_ADJUST_STEP_5,
LCD_ADJUST_STEP_6,
LCD_ADJUST_STEP_7,
LCD_ADJUST_STOP, // 停止
} lcd_adjust_step_e; // 整定步骤
typedef enum
{
@ -59,23 +96,6 @@ typedef enum
MODE_DIAGNOSIS_FAIL, // 诊断失败
} mode_diagnosis_runing_state_e;
typedef struct
{
BOOL enabled; // 是否使能
float current_trip; // 当前行程
float drive_output; // 驱动输出
float pressure_A; // A口压力
float pressure_B; // B口压力
float feedback_current; // 反馈电流
// decompression的数据
int32_t decompression_current_trip; // 当前行程
int32_t decompression_drive_output; // 驱动输出
int32_t decompression_pressure_A; // A口压力
int32_t decompression_pressure_B; // B口压力
int32_t decompression_feedback_current; // 反馈电流
} mode_diagnosis_epm_data_t; // epm诊断需要采集的数据
typedef struct
{
void (*mode_process_stop)(void); // 停止:停止算法控制和整定,流程进入等待状态

View File

@ -0,0 +1,227 @@
/**
* @file mode_diagnosis.h
* @author xushenghao
* @date 2024-03-01 00:05:33
* @brief EPM测试指令
* @copyright Copyright (c) 2024 by xxx, All Rights Reserved.
*/
#ifndef __MODE_DIAGNOSIS_H
#define __MODE_DIAGNOSIS_H
#include "lib.h"
#include <fal.h>
#include "mode_def.h"
#include "hart_frame.h"
#include "app_hart_user.h"
#define DIAGNOSIS_EPM_DBG FALSE // 测试:诊断EPM调试
#define MODE_DIAGNOSIS_FILE_SIZE (27994) // 文件大小
#define FINISHED_BYTE (0x40) // 结束标志
#define MODE_DIAGNOSIS_STORAGE_SIZE (4 * 1024) // 诊断存储空间大小
#if MODE_DIAGNOSIS_STORAGE_SIZE < (HART_PACKED4_LEN * 2)
#error "MODE_DIAGNOSIS_STORAGE_SIZE must be greater than or equal to HART_PACKED4_LEN*2"
#endif
#define STABILITY_TIME (15) // 稳定时间 秒
typedef enum
{
MODE_DIAGNOSIS_TYPE_NONE, // 无
MODE_DIAGNOSIS_TYPE_SLOPE_STEP, // 斜坡 和 阶跃测试
MODE_DIAGNOSIS_TYPE_EPM, // EPM
MODE_DIAGNOSIS_TYPE_ONLINE // 在线测试
} mode_diagnosis_type_e;
typedef enum
{
MODE_DIAGNOSIS_OUTPUT_DATA_TRAVEL_SET_POINT = BIT1, // DIN_IMPLIED_VALVE_POSITION 9
MODE_DIAGNOSIS_OUTPUT_DATA_TRAVEL = BIT2, // DIN_TRAVEL 3
MODE_DIAGNOSIS_OUTPUT_DATA_DRIVE_SIGNAL = BIT3, // DIN_DRIVE_SIGNAL 4
MODE_DIAGNOSIS_OUTPUT_DATA_PRESSURE_A = BIT4, // DIN_PRESSURE_PORT_A 2
MODE_DIAGNOSIS_OUTPUT_DATA_PRESSURE_B = BIT5, // DIN_PRESSURE_PORT_B 5
MODE_DIAGNOSIS_OUTPUT_DATA_SUPPLY_PRESSURE = BIT6, // DIN_SUPPLY_PRESSURE 8
MODE_DIAGNOSIS_OUTPUT_DATA_RELAY_POSITION = BIT7, // DIN_MINOR_LOOP_NORMAL 79
MODE_DIAGNOSIS_OUTPUT_DATA_TRAVEL_DEVIATION = BIT8, // ???
MODE_DIAGNOSIS_OUTPUT_DATA_INPUT_SET_PT = BIT9, // DIN_TRAVEL_SETPOINT 6
MODE_DIAGNOSIS_OUTPUT_DATA_INPUT_CURRENT = BIT10, // DIN_ANALOG_INPUT 0
} mode_diagnosis_output_data_e;
#pragma pack(1)
/**
*
= + 15s
RampRate = ( / *16.384) 01
= RampRate /16.384 *
= /
= / RampRate*16.384
*/
typedef struct
{
uint8_t read_or_write; // 读写标志 01
uint32_t timestamp; // 时间戳 注:手动赋值
uint8_t variable_code[HART_PACKED4_LEN]; // 设备变量和HART中的设备变量有关系
uint8_t sampling_time; // 采样时间
uint16_t target; // 目标位置
uint16_t ramp; // 斜率
uint32_t points; // 总点数
} mode_diagnosis_slop_file_head_t; // 一共18个字节用于标识文件头
/**
*
*/
typedef struct
{
uint8_t read_or_write; // 读写标志 01
uint8_t variable_code[HART_PACKED4_LEN]; // 设备变量和HART中的设备变量有关系
uint8_t sampling_time; // 采样时间
uint32_t points; // 总点数
} mode_diagnosis_online_file_head_t; // 一共9个字节用于标识文件头
typedef struct
{
mode_diagnosis_slop_file_head_t head; // 文件头
sqqueue_ctrl_t queue;
} mode_diagnosis_slop_file_storage_t; // 斜坡测试
typedef struct
{
mode_diagnosis_online_file_head_t head;
} mode_diagnosis_online_file_storage_t;
typedef union
{
mode_diagnosis_slop_file_head_t slope; // 斜坡和阶跃测试
mode_diagnosis_online_file_head_t online; // 在线测试
} mode_diagnosis_file_head_u;
#pragma pack()
typedef struct
{
float32 v[HART_PACKED4_LEN];
int32_t decompression_v[HART_PACKED4_LEN];
} mode_diagnosis_data_t;
typedef struct
{
uint16_t size;
uint16_t written; // 已写字节数
uint16_t remain; // 剩余字节数
} mode_diagnosis_page_t;
typedef struct
{
BOOL finshed; // 是否完成
file_status_e file_status; // 文件状态
uint16_t file_size_read; // 文件已读大小
uint16_t file_size_written; // 文件已写入大小
uint16_t file_size; // 文件大小
uint8_t head_size; // 文件头大小
uint8_t *pbuf;
} mode_diagnosis_storage_t;
typedef struct
{
BOOL run;
mode_diagnosis_type_e type; // 诊断类型
mode_diagnosis_data_t last_data; // 上一次数据
struct
{
uint8_t actual_variables_num; // 实际变量数量
uint16_t ticks;
uint32_t sampling_time; // 采样时间
float32 output_increment; // 输出增量 百分比
// 只用于显示
int16_t start_target; // 开始目标
int16_t end_target; // 结束目标
uint16_t total_points; // 总数据点数
uint32_t test_time; // 测试时间
uint32_t stability_time; // 稳定时间
} params;
struct
{
uint16_t read_write_offset_time; // 读写偏移时间 秒 计算写入与上位机读取之间的时间差
uint16_t points; // 斜坡数据点数
uint32_t run_ticks; // 运行时间,标记执行了多少次中断当到达ticks时停止
uint32_t stability_ticks; // 稳定时间,减到0结束
float32 current_target; // 当前目标
float32 last_target; // 上一次目标
hart_device_variable_t *variables[HART_PACKED4_LEN];
uint16_t variables_cycles_count; // 变量循环计数
} rt_data;
} mode_diagnosis_t;
/**
* @brief Initialize the mode diagnosis module.
*/
void mode_diagnosis_init(void);
/**
* @brief Get the mode diagnosis object pointer.
*
* This function returns a pointer to the mode diagnosis object. This object is used to store and manage the relevant information of the mode diagnosis.
*
* @return The pointer to the mode diagnosis object.
*/
mode_diagnosis_t *mode_diagnosis_get(void);
/**
* @brief Get the storage of the mode diagnosis.
*
* @return The storage of the mode diagnosis.
*/
mode_diagnosis_storage_t *mode_diagnosis_get_storage(void);
/**
* @brief Stop the mode diagnosis.
*
* This function stops the mode diagnosis and saves the data to the flash.
*
* @return None.
*/
void mode_diagnosis_stop(void);
/**
* @brief Start the mode diagnosis.
*
* This function starts the mode diagnosis and records the event and data.
*
* @param[in] diagnosis_type The type of the mode diagnosis.
* @param[in] data The data of the mode diagnosis.
*
* @return @c true if the mode diagnosis is started successfully, otherwise @c false.
*/
BOOL mode_diagnosis_start(mode_diagnosis_type_e diagnosis_type, const mode_diagnosis_file_head_u *const data);
/**
* @brief Write the mode diagnosis file.
*
* This function writes the mode diagnosis file to the flash.
*
* @param[in] file_offset The offset of the file.
* @param[in] write_length The length of the data to be written.
* @param[in] wr_cache The data to be written.
* @param[in] wf_len The length of the data to be written.
*
* @return @c true if the mode diagnosis file is written successfully, otherwise @c false.
*/
BOOL mode_diagnosis_file_read(uint16_t file_offset, uint8_t read_length, uint8_t *rd_cache, uint8_t *rd_len);
/**
* @brief Perform an inspection of the mode diagnosis module.
*/
void mode_diagnosis_inspection(void);
/**
* @brief Test the mode diagnosis module.
*/
INTERNAL_EXTERN void mode_diagnosis_test(mode_diagnosis_type_e event);
#endif // __MODE_DIAGNOSIS_H

View File

@ -0,0 +1,171 @@
#ifndef __MODE_PWMP_H__
#define __MODE_PWMP_H__
#include "filter.h"
#include "mode_def.h"
#include "pid_zh1.h"
#include "mode_pwmp_adjust.h"
#define SYS_TICK 10
#define TASK_DUTY 25
#define TRAVEL_VELOCITY_MIN 0.05f
typedef enum
{
MODEL_L_12_1,
MODEL_L_23_1,
MODEL_L_34_1,
MODEL_L_45_1,
} model_type_e;
typedef enum
{
PWMP_ADJUST_IDEL,
PWMP_ADJUST_VALVE, // 整定阀门 位置0 位置100 上行时间、速度、加速度 下行时间、速度、加速度
PWMP_ADJUST_IP, // 整定ip
PWMP_ADJUST_PID, // PID
PWMP_ADJUST_CALCULATE, // 换算
PWMP_ADJUST_SAVE, // 存储变量
PWMP_ADJUST_STOP, // 停止
PWMP_ADJUST_FAIL, // 整定失败
} mode_pwmp_adjust_state_e; // 整定状态
#define PWMP_ADJUST_STEP LCD_ADJUST_STOP // 整定步骤
typedef enum
{
PWMP_PROCESS_CONTROL,
PWMP_PROCESS_CONTROL_STOP,
PWMP_PROCESS_ADJUST,
PWMP_PROCESS_ADJUST_STOP,
PWMP_PROCESS_TEST,
} mode_pwmp_process_state_e; // 处理状态
typedef struct
{
lpf_window_t target_lpf_window;
lpf_window_t actual_lpf_window;
lpf_t target_lpf;
lpf_t actual_lpf;
kalman_t target_kalman;
kalman_t actual_kalman;
} mode_pwmp_filter_t;
// 蓝牙控制参数类型
typedef struct
{
uint32_t t;
} ble_ctrl_t;
// 速度整定控制参数类型
typedef struct
{
float s;
float t;
float v1;
float v2;
float a;
} velocity_ctrl_t;
// 阀门整定控制参数类型
typedef struct
{
uint8_t step;
uint32_t t;
uint32_t count;
} valve_tune_t;
typedef enum
{
IP_POSITIVE_ACTION,
IP_NEGATIVE_NATION,
} IP_ACTION_TYPE_t;
// ip整定控制参数类型
typedef struct
{
uint8_t step;
uint16_t out, out_min, out_max, out_step;
uint32_t t;
} ip_tune_t;
// pid整定控制参数类型
typedef struct
{
uint8_t step, pre_step;
uint32_t t;
} pid_tune_t;
// 所有整定控制参数类型
typedef struct
{
uint8_t step;
TUNE_ID_t tune_id;
velocity_ctrl_t velocity;
valve_tune_t valve;
ip_tune_t ip;
pid_tune_t pid;
} tune_ctrl_t;
// 过程控制参数类型
typedef struct
{
uint32_t t;
float32 output;
velocity_ctrl_t velocity;
ble_ctrl_t ble;
} process_ctrl_t;
typedef struct
{
float Kc, Tc;
float kp, ki, kd;
} pid_storage_t;
// 整定结果保存参数类型
typedef struct
{
uint8_t tuned_flag;
uint8_t process_change_flag; // 磁条接收的反馈电压由大变小 0 由小变大 1
uint8_t magnetic_dir;
uint16_t ad_0;
uint16_t ad_100;
model_type_e model_type;
float v_l2h, v_h2l;
float t_l2h, t_h2l;
float s;
float ip_ctrl_min;
float ip_ctrl_max;
pid_storage_t inner; // 内环整定参数
pid_storage_t outer; // 外环整定参数
} pwmp_storage_pars_t;
// pwmp 对象类型
typedef struct
{
uint8_t lcd_adjust_step; ///< LCD自整定流程状态
uint8_t auto_tune_state; ///< 自整定状态 0未整定 1整定中 2整定完成 3整定失败
uint16_t current_adc; ///< 当前位置反馈的AD值
uint8_t process_state; ///< 处理状态
uint8_t adjust_state; ///< 整定状态
pwmp_storage_pars_t *data; ///< 存储参数
void (*params_save_cb)(void); ///< 参数保存回调函数
mode_pwmp_filter_t filter; ///< 滤波
process_ctrl_t process_ctrl; ///< 过程控制对象
} mode_pwmp_t;
void mode_pwmp_init(mode_interface_req_t *req, uint16_t positioner_model, pwmp_storage_pars_t *params, void (*params_save_cb)(void));
void mode_pwmp_dinit(void);
void mode_pwmp_process(void);
void pwmp_process_state_set(mode_pwmp_process_state_e state);
uint8_t pwmp_process_adjust_state_get(void); ///< 获取整定过程
uint8_t pwmp_process_adjust_result_get(void); ///< 获取整定结果
BOOL pwmp_process_idle(void); // 是否空闲(在进入PID控制区域不要绘图)
BOOL pwmp_process_is_adjust(void); ///< 是否正在整定
BOOL pwmp_algorithm_calibrated_status(void);
#endif

View File

@ -0,0 +1,179 @@
#ifndef __TUNE_H__
#define __TUNE_H__
#include <stdint.h>
#include "data_type_def.h"
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
#define AUTO_TUNE_OBJ_NUM 1 /*定义同时需要自整定对象资源的最大个数*/
typedef int32_t TUNE_ID_t; /*自整定类型定义正常Id为>=0,若小于零则返回的Id错误*/
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
typedef enum /*PID控制器类型*/
{
CONTROLER_TYPE_PI, /*PI控制器*/
CONTROLER_TYPE_PID, /*PID控制器*/
} TUNE_CONTROLER_TYPE_t;
typedef enum /*PID状态*/
{
TUNE_INIT = 0, /*PID自整定初始化中*/
TUNE_START_POINT, /*寻找起始点*/
TUNE_RUNNING, /*PID自整定中*/
TUNE_FAIL, /*整定失败*/
TUNE_SUCESS, /*整定成功*/
} TUNE_STAT_t;
typedef enum /*驱动器作用*/
{
POSITIVE_ACTION, /*设定值大于测量值时,执行单元执行高输出*/
NEGATIVE_ACTION, /*设定值大于测量值时,执行单元执行低输出*/
} DRIVER_ACTION_TYPE_t;
typedef struct TUNE_CFG_PARAM_tag
{
TUNE_CONTROLER_TYPE_t cTrlType; /*控制器类型默认PD控制器*/
DRIVER_ACTION_TYPE_t acterType; /*驱动器作用类型,默认正向作用*/
uint32_t hysteresisNum; /*反馈值在设定值处的迟滞相应个数默认为5*/
float32 maxOutputStep; /*最大输出阶跃值默认值为50*/
float32 minOutputStep; /*最小输出阶跃值默认值为0*/
float32 setpoint; /*整定设定值,默认值为为50*/
float32 ampStdDeviation; /*幅值标准差预期值,用来计算自整定波形是否稳定*/
float32 cycleStdDeviation; /*周期标准差预期值,用来计算自整定波形是否稳定*/
} TUNE_CFG_PARAM_t, *pTUNE_CFG_PARAM_t; /*pid自整定对象配置参数*/
typedef struct TUNE_OGJ_tag *pTUNE_OBJ_t; /*PID自整定参数*/
/*-----------------------------------------------------------------------------------
: void TUNE_Init(void)
: ,使TUNE_CFG_PARAM_t参数初始化自整定参数
default cTrlType = CONTROLER_TYPE_PI,
default outputStep = 50,
default hysteresisNum = 5
: NA
: NA
: true:pram is protected can't be modifid; false: writable
-----------------------------------------------------------------------------------*/
extern void TUNE_Init(void);
/*-----------------------------------------------------------------------------------
: TUNE_ID_t TUNE_New(pTUNE_CFG_PARAM_t pParam)
: PID自整定对象
: pParam
: NA
: <0AUTO_TUNE_OBJ_NUM宏定义
>=0,idId
-----------------------------------------------------------------------------------*/
extern TUNE_ID_t TUNE_New(pTUNE_CFG_PARAM_t pParam);
/*-----------------------------------------------------------------------------------
: TUNE_ID_t TUNE_New(pTUNE_CFG_PARAM_t pParam)
: ID所示自整定对象资源
: id:ID
: NA
: false:true:
tuneStat为TUNE_FAIL或者TUNE_SUCESS状态下
-----------------------------------------------------------------------------------*/
extern BOOL TUNE_Release(TUNE_ID_t id);
/*-----------------------------------------------------------------------------------
: BOOL TUNE_Work(TUNE_ID_t id, float32 feedbackVal, float32*outputVal)
:
: id:ID
delayMsec:
: outputVal:
: true:false:
-----------------------------------------------------------------------------------*/
extern TUNE_STAT_t TUNE_Work(TUNE_ID_t id, float32 feedbackVal, float32 *outputVal, uint32_t delayMsec);
/*-----------------------------------------------------------------------------------
: BOOL TUNE_SetActerType(TUNE_ID_t id, float32 maxStep,DRIVER_ACTION_TYPE_t type)
:
: id:ID
type:
: NA
: true:false:
-----------------------------------------------------------------------------------*/
extern BOOL TUNE_SetActerType(TUNE_ID_t id, DRIVER_ACTION_TYPE_t type);
/*-----------------------------------------------------------------------------------
: BOOL TUNE_Setsetpoint(TUNE_ID_t id, float32 setpoint)
:
: id:ID
setpoint:
: NA
: true:false:
-----------------------------------------------------------------------------------*/
extern BOOL TUNE_Setsetpoint(TUNE_ID_t id, float32 setpoint);
/*-----------------------------------------------------------------------------------
: BOOL TUNE_SetOutStep(TUNE_ID_t id, float32 maxStep,float32 minStep)
:
: id:ID
maxStep:
minStep:
: NA
: true:false:
------------------------------------------------------------------------------------*/
BOOL TUNE_SetOutStep(TUNE_ID_t id, float32 maxStep, float32 minStep);
/*-----------------------------------------------------------------------------------
: BOOL TUNE_SetCtrlType(TUNE_ID_t id, TUNE_CONTROLER_TYPE_t type)
:
: id:ID
type:
CONTROLER_TYPE_PIPI控制器,使
CONTROLER_TYPE_PIDPID控制器
: NA
: true:false:
-----------------------------------------------------------------------------------*/
extern BOOL TUNE_SetCtrlType(TUNE_ID_t id, TUNE_CONTROLER_TYPE_t type);
/*-----------------------------------------------------------------------------------
: float32 TUNE_GetKp(TUNE_ID_t id, float32 *pfactorP)
: P参数
: id:ID
: pfactorP:P参数
: true:
-----------------------------------------------------------------------------------*/
extern float32 TUNE_GetKp(TUNE_ID_t id, float32 *pfactorP);
/*-----------------------------------------------------------------------------------
: float32 TUNE_GetKp(TUNE_ID_t id)
: I参数
: id:ID
: pfactorI:I参数
: true:
-----------------------------------------------------------------------------------*/
extern float32 TUNE_GetKi(TUNE_ID_t id, float32 *pfactorI);
/*-----------------------------------------------------------------------------------
: float32 TUNE_GetKp(TUNE_ID_t id)
: D参数
: id:ID
: pfactorD:D参数
: true:
---------------------------------------------------------------------------------------*/
extern float32 TUNE_GetKd(TUNE_ID_t id, float32 *pfactorD);
/*-----------------------------------------------------------------------------------
: float32 TUNE_GetKp(TUNE_ID_t id)
: PID参数
: id:ID
: NA
: true:
-----------------------------------------------------------------------------------*/
extern BOOL TUNE_GetPID(TUNE_ID_t id, float32 *paramP, float32 *paramI, float32 *paramD);
/*-----------------------------------------------------------------------------------
: float32 TUNE_GetStat(TUNE_ID_t id, TUNE_STAT_t *pStat)
: PID自整定状态
: id:ID
: stat
: true:
-----------------------------------------------------------------------------------*/
extern BOOL TUNE_GetStat(TUNE_ID_t id, TUNE_STAT_t *pStat);
#endif /* __TUNE__H*/

View File

@ -2,24 +2,15 @@
#define __MODE_PWMP_HD_H__
#include "main.h"
#define MODE_DEFAULT_AUTOLOAD 99 // 预分频系数
#define WAIT_COUNT_MAX 2 // 蓝牙等待最大次数
#define VIP_H_EN_HD 1 // 高电压输出开关
///////////////////////////////////////*算法整定部分宏定义BEGIN*////////////////////////////////////////
#define TIME_CYCLE 0.01f // 定义时间周期:10ms
#define FSM_WAIT(st) BIT_SET(st, BIT7)
#define FSM_IS_WAIT(st) (st & BIT7)
#define DIFF_ADC 10U
#define DIFF_ADC_MAX 6U
///////////////////////////////////////*算法整定部分宏定义END*///////////////////////////////////////////
#define EXECUTE_PLAN EXECUTE_PLAN_1
/*----------------------------------------*/
typedef enum
{
ANGULAR_TRAVEL,
LINEAR_TRAVEL,
} mode_pwmp_hd_valve_type_e; // 阀门类型
typedef enum
{
PWMP_HD_PROCESS_CONTROL,
PWMP_HD_PROCESS_ADJUST,
@ -28,44 +19,28 @@ typedef enum
PWMP_HD_PROCESS_STOP,
} mode_pwmp_hd_process_state_e; // 处理状态
typedef enum
{
INFLATE = 0,
DEFLATE,
} mode_pwmp_hd_action_e; // 运动状态(充气/排气)
/*需要存储的变量*/
typedef struct
{
/*充气过程:各百分之十阀位的控制信号值*/
uint16_t valvepos_in[9]; // 充气过程中9个不同阀位的控制信号值
/*排气过程:各百分之十阀位的控制信号值*/
uint16_t valvepos_de[9]; // 排气过程中9个不同阀位的控制信号值
float32_t valvepos_in_k[8];
float32_t valvepos_de_k[8];
float32_t valvepos_in_b[8];
float32_t valvepos_de_b[8];
uint8_t tuned_flag; // 整定标志 0未整定1整定中2整定成功3整定失败
uint16_t startup_value; // 阀位启动值
uint16_t arr_diff; // 控制区间
uint16_t ad_diff; // 磁条区间
uint16_t pwmp_min; // 控制最小值
uint16_t pwmp_max; // 控制最大值
uint16_t pwmp_min_origin; // 整定控制最小值
uint16_t pwmp_max_origin; // 整定控制最大值
uint16_t trip_0; // 磁条0位置AD
uint16_t trip_100; // 词条100位置AD
uint16_t trip_min0; // 小回路行程0位置AD
uint16_t trip_min100; // 小回路行程100位置AD
uint16_t current0; // 电流最小值
uint16_t current100; // 电流最大值
uint16_t all_open_time; // 全开时间
uint16_t all_close_time; // 全关时间
uint16_t all_open_time_full; // 最大信号全开时间
uint16_t all_close_time_full; // 最大信号全关时间
uint16_t prov_flag; // 磁条安装的正反倒装0 正装1
uint16_t valve_type; // 阀门正反行程气开ATO 气关ATC
uint8_t tuned_flag; // 整定标志 0未整定1整定中2整定成功3整定失败
uint16_t startup_value; // 阀位启动值
uint16_t arr_diff; // 控制区间
uint16_t ad_diff; // 磁条区间
uint16_t pwmp_min; // 控制最小值
uint16_t pwmp_max; // 控制最大值
uint16_t pwmp_min_origin; // 整定控制最小值
uint16_t pwmp_max_origin; // 整定控制最大值
uint16_t trip_0; // 磁条0位置AD
uint16_t trip_100; // 词条100位置AD
uint16_t trip_min0; // 小回路行程0位置AD
uint16_t trip_min100; // 小回路行程100位置AD
uint16_t current0; // 电流最小值
uint16_t current100; // 电流最大值
uint16_t all_open_time; // 全开时间
uint16_t all_close_time; // 全关时间
uint16_t all_open_time_full; // 最大信号全开时间
uint16_t prov_flag; // 磁条安装的正反倒装0 正装1
uint16_t valve_type; // 阀门正反行程气开VALVE_CLOSE 气关VALVE_OPEN
float32 kp;
float32 ki;
float32 kd;
@ -86,28 +61,12 @@ typedef struct
{
lpf_t actual_lpf;
lpf_t target_lpf;
lpf_window_t *handle;
lpf_window_t handle;
} mode_pwmp_hd_filter_t;
typedef union
{
//
uint8_t data[256];
// 自定义数据结构
mode_pwmp_hd_storage_data_t storage;
} mode_pwmp_hd_params_u;
typedef enum
{
INAUTO_C,
OFFAUTO_C,
} mode_pwmp_hd_pid_mode_e;
typedef struct
{
mode_pwmp_hd_pid_mode_e pid_mode; // PID控制模式
mode_pwmp_hd_action_e action; // 运动状态(充气/排气)
uint8_t lcd_adjust_state; // LCD自整定流程状态
float32 duty_percent; // 占空比
float32 current_electric; // 电流
@ -121,11 +80,9 @@ typedef struct
uint16_t current_adc; // 当前位置反馈的AD值
uint32_t count; // 计数
float32 valvepos_stable; // 10%-90%阀位之间的稳定控制值
mode_pwmp_hd_control_t control;
mode_pwmp_hd_filter_t filter;
mode_pwmp_hd_params_u *pwmp_save;
mode_pwmp_hd_storage_data_t *pwmp_save;
void (*params_save_cb)(void);
} mode_pwmp_hd_t;
@ -188,10 +145,6 @@ typedef enum
PWMP_HD_ADJUST_SAVE, // 存储变量
PWMP_HD_ADJUST_BLEEDING, // 在整定状态中放气
PWMP_HD_ADJUST_BLEEDING_POSITION0, // 放气位置0
PWMP_HD_ADJUST_INITIATE, // 启动值
PWMP_HD_ADJUST_STEP_BY_10_TO_100, // 由0-100找到控制值
PWMP_HD_ADJUST_STEP_BY_10_TO_0, // 由100-0找到控制值
PWMP_HD_ADJUST_VALVEPOS_CALCULATE, // 对各区间阀位控制值进行线性化处理
PWMP_HD_ADJUST_STOP,
PWMP_HD_ADJUST_FAIL, // 整定失败
PWMP_HD_ADJUST_TEST,
@ -211,18 +164,9 @@ typedef enum
PWMP_HD_ADJUST_RESULT_FAIL,
} mode_pwmp_hd_adjust_result_e; // 整定结果
typedef struct
{
/*充气过程:各百分之十阀位的控制信号值*/
uint16_t valvepos_in[9]; // 充气过程中9个不同阀位的控制信号值
/*排气过程:各百分之十阀位的控制信号值*/
uint16_t valvepos_de[9]; // 排气过程中9个不同阀位的控制信号值
} mode_pwmp_hd_adjust_valvepos_t;
typedef struct
{
mode_pwmp_hd_adjust_state_e adjust_state;
mode_pwmp_hd_adjust_valvepos_t valvepos; // 记录处于每10%阀位的控制信号值
volatile uint16_t wait_count;
volatile uint16_t psb_adc;
@ -233,7 +177,6 @@ typedef struct
BOOL adc_0_100_flag; // 判断0-100移动过程中ad值是增大还是减少TRUE 增大FALSE 减小
BOOL flag_stable_begin;
BOOL flag_stable_end;
BOOL all_bleed_time_flag;
uint16_t adc_record_0; // 记录放气时阀门最小位置ad值
uint16_t adc_record_1; // 记录放气时阀门最小位置ad值
@ -246,18 +189,11 @@ typedef struct
uint16_t arr_record_stable_begin; // 记录阀门稳定区域开始的ad值
uint16_t arr_record_stable_end; // 记录阀门稳定区域结束的ad值
uint32_t all_open_time; // 全开时间
uint32_t all_open_time_full; // 信号为最大输出时的全开时间
uint32_t all_close_time; // 全关时间
uint32_t all_close_time_full; // 信号为最大输出时的全关时间
uint32_t tmp_time; // 临时用来记录全开全关/整定时间
uint32_t current_0; // 0位置电流大小
uint32_t current_100; // 100位置电流大小
float32 ctrl_target; // 控制目标值
float32 real_error; // 实际误差
float32 ctrl_feedback; // 反馈值
uint32_t all_open_time; // 全开时间
uint32_t all_open_time_full; // 信号为最大输出时的全开时间
uint32_t all_close_time; // 全关时间
BOOL all_close_time_flag;
uint32_t tmp_time; // 临时用来记录全开全关/整定时间
/*输出值*/
uint16_t arr_default; // 默认计数器(推动计数值)
@ -351,7 +287,7 @@ typedef struct
} execute_rsp_hd_t;
/////////////////////////////////////////*控制算法END*////////////////////////////////////////
void mode_pwmp_hd_init(mode_interface_req_t *req, uint16_t positioner_model, mode_pwmp_hd_params_u *params, void (*params_save_cb)(void));
void mode_pwmp_hd_init(mode_interface_req_t *req, uint16_t positioner_model, mode_pwmp_hd_storage_data_t *params, void (*params_save_cb)(void));
void mode_pwmp_hd_dinit(void);
void mode_pwmp_hd_process(void);
void pwmp_hd_process_state_set(mode_pwmp_hd_process_state_e state);

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,467 @@
# 算法设计
[模糊PID控制器设计文档](./模糊PID控制器设计文档.md)
# 自整定
## 说明
定位器的自整定是给控制模块准备数据的
定位器的自整定过程是一个自动化的过程,旨在为控制模块准备和优化数据,以确保控制系统能够以最佳的性能运行。这个过程通常涉及以下几个关键步骤:
1. **数据收集** :定位器在系统的正常运行过程中或通过特定的测试信号,收集系统的响应数据。这些数据包括但不限于系统的输入、输出、响应时间、稳定性指标等。
2. **系统识别** :通过分析收集到的数据,识别系统的动态特性,如传递函数、时间常数、死区时间等。这一步是自整定过程中非常关键的一环,因为正确的系统识别是制定有效控制策略的基础。
3. **参数优化** 根据系统的动态特性和预定的性能指标如快速响应、最小超调、稳定性等优化控制参数。这些参数可能包括PID控制器的比例P、积分I和微分D参数。
4. **验证和微调** :将优化后的参数应用于控制模块,观察系统的实际运行性能。根据实际性能与预期目标的差异,进行必要的微调。
5. **实施和监控** :一旦确认参数能够使系统达到最佳性能,就将这些参数固化为控制模块的默认设置,并持续监控系统性能,确保长期稳定运行。
针对GPS2000定位器需要准备的数据有回路反馈的大小、充气和放气的最大值、PID参数、目标位置的平衡值。
## 设计
![1721117781364](image/控制算法说明-许晟昊/1721117781364.png)
## 流程
```c
void mode_control_adjust_process(uint8_t *state)
{
uint8_t ts = *state;
BOOL ble_output = FALSE;
BIT_CLR(ts, BIT7); // 高位清零
{
if (mode_control_adjust == NULL)
{
mode_control_adjust = osel_mem_alloc(sizeof(mode_control_adjust_t));
DBG_ASSERT(mode_control_adjust != NULL __DBG_LINE);
}
}
mode_control_adjust->adjust_state2 = (mode_control_adjust_state_e)ts;
switch (ts)
{
case CONTROL_ADJUST_IDEL: // 空闲
mode_control_adjust_idle(state, CONTROL_ADJUST_UPWARD_SLOPE);
mode_control_adjust->test_index = 1;
break;
case CONTROL_ADJUST_UPWARD_SLOPE: // 上坡
mode_control_adjust_upward_slope(state, CONTROL_ADJUST_DOWNWARD_SLOPE);
ble_output = TRUE;
break;
case CONTROL_ADJUST_DOWNWARD_SLOPE: // 下坡
mode_control_adjust_downward_slope(state, CONTROL_ADJUST_SAVE);
ble_output = TRUE;
break;
case CONTROL_ADJUST_SAVE: // 存储变量
mode_control_adjust_save(state, CONTROL_ADJUST_TUNING);
break;
case CONTROL_ADJUST_TUNING: // 自整定
mode_control_adjust_tuning_pi(state, CONTROL_ADJUST_STOP);
ble_output = TRUE;
break;
case CONTROL_ADJUST_STOP: // 停止
mode_control_adjust_stop(state);
mode_control_pid_load();
mode_control_start();
break;
case CONTROL_ADJUST_FAIL: // 整定失败
mode_control_adjust_fail(state);
break;
case CONTROL_ADJUST_BLEEDING: // 在整定状态中放气
mode_control_adjust_bleeding(state);
break;
case CONTROL_ADJUST_AERATE: // 在整定状态中充气
mode_control_adjust_aerate(state);
break;
case CONTROL_ADJUST_TEST:
mode_control_adjust_test(state, mode_control_adjust->test_index);
break;
case CONTROL_ADJUST_PAUSE:
mode_control_adjust_pause(state);
break;
default:
break;
}
mode_control_adjust->enter_count1++;
if (ble_output == TRUE && FSM_IS_WAIT(*state) && mode_control_adjust->enter_count1 % (MODE_CONTROL_CYCLE_BASE * 2 / mode_control->params.wait_count_max) == 0)
{
float current_trip;
if (ts == CONTROL_ADJUST_TUNING)
{
mode_control_bluetooth_output_control();
}
else
{
current_trip = get_pid_travel(actual_adc_convert_percent(mode_control_adjust->current_psb));
mode_control_bluetooth_output_trip(current_trip);
}
}
}
```
# 控制模块
## 说明
算法控制模块是一个控制系统的实现,主要用于管理和调整一个或多个过程的状态。它包括一系列的函数,用于启动和停止控制过程、调整控制参数、获取调整结果、以及管理控制算法的运行状态。以下是模块中各个部分的简要说明:
**控制过程函数**
* `_process_start`:启动控制过程。
* `_process_stop`:停止控制过程,并将控制状态设置为停止。
**调整控制函数**
* `_adjust_start``_adjust_stop`:分别用于开始和停止调整过程。
* `_adjust_result`:返回调整过程的结果,判断是否正在调整或已完成调整。
* `_adjust_step_count``_adjust_step_current`:用于管理调整步骤的计数和当前步骤。
* `_adjust_data`填充调整数据结构包括位置、输出、电流、时间和PID系数等信息。
**状态检查函数**
* `_control_idle`:检查控制过程是否处于空闲状态。
* `_adjust_isrun`:检查是否正在进行调整过程。
* `_algorithm_calibrated_status`:检查算法是否已校准。
**辅助函数**
* `update_timer_count`:更新定时器计数器。
* `set_control_arr`:根据定位器模型设置控制参数。
* `get_stable_arr`:根据目标值获取稳定的控制参数。
* `limiting_amplitude`:限制振幅,根据控制过程的状态和方向调整最小和最大输出限制。
**更新限制幅度函数**
* `limiting_amplitude_update`:根据目标值和控制输出百分比更新限制幅度的相关参数。
整个模块主要关注于控制过程的启动、停止、调整以及状态的管理和检查。它通过一系列的函数实现对控制过程的精细管理包括调整PID控制参数、管理调整步骤、以及根据控制目标和实际输出调整控制输出的限制幅度。此外模块还包括对定时器的管理和根据不同的定位器模型调整控制参数的功能。
## 设计
![1721120186100](image/控制算法说明-许晟昊/1721120186100.png)
## 流程
### 初始化
```c
/**
* @brief 初始化模式控制
*
* 初始化模式控制的相关参数和回调函数,并配置相应的接口请求结构体。
*
* @param req 模式控制接口请求结构体指针
* @param positioner_model 定位器型号
* @param params 模式控制参数结构体指针
* @param params_save_cb 保存参数回调函数
*/
void mode_control_init(mode_interface_req_t *req, uint16_t positioner_model, mode_control_params_u *params, void (*params_save_cb)(void))
{
// 断言 req 不为空,否则在 __DBG_LINE 指定的位置触发断言错误
DBG_ASSERT(req != NULL __DBG_LINE);
// 断言 params 不为空,否则在 __DBG_LINE 指定的位置触发断言错误
DBG_ASSERT(params != NULL __DBG_LINE);
// 断言 params_save_cb 回调函数不为空,否则在 __DBG_LINE 指定的位置触发断言错误
DBG_ASSERT(params_save_cb != NULL __DBG_LINE);
// 设置 req 结构体中的各个函数指针
req->mode_process_start = _process_start;
req->mode_process_stop = _process_stop;
req->mode_adjust_start = _adjust_start;
req->mode_adjust_stop = _adjust_stop;
req->mode_get_adjust_data = _adjust_data;
req->mode_adjust_result = _adjust_result;
req->mode_adjust_step_count = _adjust_step_count;
req->mode_adjust_step_current = _adjust_step_current;
req->mode_control_idle = _control_idle;
req->mode_is_adjusting = _adjust_isrun;
// 启用 VIP_H_EN
VIP_H_EN_ENABLE();
// 如果 mode_control 为空,则为其分配内存
if (mode_control == NULL)
{
mode_control = (mode_control_t *)osel_mem_alloc(sizeof(mode_control_t));
}
// 检查存储结构体的大小是否大于数组长度,如果是,则触发断言错误
if (sizeof(mode_control_storage_t) > ARRAY_LEN(mode_control->storage_data->data))
{
DBG_ASSERT(FALSE __DBG_LINE);
}
// 将 mode_control 结构体清零
osel_memset((uint8_t *)mode_control, 0, sizeof(mode_control_t));
mode_control->params.default_min_value = mode_control_get_default_min_value();
mode_control->control_data.pressure_drain_flag = TRUE;
mode_control_output(mode_control->params.default_min_value);
update_timer_count(MODE_CONTROL_CYCLE);
mode_control->params.positioner_model = positioner_model;
mode_control->storage_data = params;
mode_control->params_save_cb = params_save_cb;
// 初始化滤波器相关结构体
mode_control->filter.target_lpf_window = lpf_window_init(10);
mode_control->filter.actual_lpf_window = lpf_window_init(10);
mode_control->filter.ctrl_output_lpf_window = lpf_window_init(10);
mode_control->filter.ctrl_output_lpf.alpha = 0.1;
lpf_init(&mode_control->filter.ctrl_output_lpf);
// 检查 positioner_model 是否超出最大范围
if (mode_control->params.positioner_model >= POSITIONER_MODEL_MAX)
{
// 如果超出范围,则设置控制状态为控制失败
mode_control_state_set(CONTROL_PROCESS_CONTROL_FAIL);
}
else
{
// 如果算法已经校准,则加载 PID 参数并设置其他参数
if (_algorithm_calibrated_status() == TRUE)
{
mode_control_pid_load();
mode_control_set_parms();
}
else
{
// 如果算法未校准,则将相关参数标记为未校准状态
calib_param[CALIBPARA_IPSB].is_calibration = FALSE;
}
// 启动模式控制
mode_control_start();
}
// mode_control_state_set(CONTROL_PROCESS_ADJUST);
}
```
### 控制进程
```c
/**
* @brief 模式控制处理函数
*
* 根据mode_control的状态执行不同的处理流程。
*
* @param
*
* @return
*/
void mode_control_process(void)
{
// 检查mode_control是否为空
if (mode_control == NULL)
{
return;
}
// 获取mode_control的控制数据指针
mode_control_params_t *p = &mode_control->control_data;
// 进入计数加1
p->enter_count2++;
// 根据process_state的值进行不同的处理
switch (mode_control->fsm.process_state)
{
case CONTROL_PROCESS_CONTROL: // 控制
{
// 如果算法校准状态为TRUE
if (_algorithm_calibrated_status() == TRUE)
{
// 更新mode_control
mode_control_update();
// 执行mode_control
mode_control_execute();
}
break;
}
case CONTROL_PROCESS_ADJUST: // 整定
// 更新mode_control
mode_control_update();
// 如果获取整定参数为NULL
if (mode_control_adjust_get() == NULL)
{
// 设置整定状态为IDLE
mode_control->fsm.adjust_state = CONTROL_ADJUST_IDEL;
}
// 执行整定处理
mode_control_adjust_process((uint8_t *)&mode_control->fsm.adjust_state);
break;
case CONTROL_PROCESS_MANUAL: // 手动
{
// 更新mode_control
mode_control_update();
// 如果手动输出值小于等于DAC_MAX
if (mode_control->manual_output <= DAC_MAX)
{
// 输出手动控制值
mode_control_output(mode_control->manual_output);
}
break;
}
case CONTROL_PROCESS_ADJUST_STOP:
{
// 停止整定
mode_control_adjust_stop(0);
break;
}
case CONTROL_PROCESS_STROKE_TEST:
{
// 更新mode_control
mode_control_update();
// 如果获取整定参数为NULL
if (mode_control_adjust_get() == NULL)
{
// 设置整定状态为IDLE
mode_control->fsm.adjust_state = CONTROL_ADJUST_IDEL;
}
break;
}
case CONTROL_PROCESS_STOP:
// 更新mode_control
mode_control_update();
break;
case CONTROL_PROCESS_CONTROL_FAIL:
// 控制失败处理
break;
default:
// 默认处理
break;
}
}
```
### 控制执行
```c
/**
* @brief 执行模式控制
*
* 根据当前的模式控制参数执行模式控制的相关操作。
*
*/
void mode_control_execute(void)
{
mode_control_params_t *p = &mode_control->control_data;
// 增加进入次数
p->enter_count1++;
// 如果进入次数满足条件且当前处理状态为CONTROL_PROCESS_CONTROL每100ms
if (p->enter_count1 % (MODE_CONTROL_CYCLE_BASE * 2 / mode_control->params.wait_count_max) == 0 && mode_control->fsm.process_state == CONTROL_PROCESS_CONTROL) // 100ms
{
// 通过蓝牙输出控制内容
mode_control_bluetooth_output_control(); // 通过蓝牙输出 控制内容
}
// 如果控制目标大于上限或小于下限并且当前处理状态为CONTROL_PROCESS_CONTROL
if ((p->ctrl_target >= udevice.cutoff_limit_hi || p->ctrl_target <= udevice.cutoff_limit_lo) &&
mode_control->fsm.process_state == CONTROL_PROCESS_CONTROL)
{
// 输出限制
output_limit();
}
else
{
// 如果当前处理状态为CONTROL_PROCESS_CONTROL
if (mode_control->fsm.process_state == CONTROL_PROCESS_CONTROL)
{
// 设置分程状态PID参数
set_split_range_state_params(); // 分程状态PID参数
}
// 检查稳定状态
check_stable_state(); // check stable state
// 算法实现
switch (mode_control->params.positioner_model)
{
case POSITIONER_MODEL_GPS2000:
// 控制GPS2000
control_gps2000();
break;
case POSITIONER_MODEL_GPS3000:
// 控制GPS3000
control_gps3000();
break;
default:
break;
}
}
}
```
### GPS2000控制方法
```c
/**
* @brief 控制 GPS2000
*
* 该函数用于控制 GPS2000 设备的操作逻辑,根据控制参数执行特定的控制算法,
* 并输出控制结果。
*/
static void control_gps2000(void)
{
// 获取控制参数结构体指针
mode_control_params_t *p = &mode_control->control_data;
limiting_amplitude_t max_min;
// 设置最大最小幅度
limiting_amplitude(&max_min);
// 如果刹车标志为真且实际误差小于停止点减去死区
if (p->brake_flag == TRUE && (ABS(p->real_error) < (MODE_CONTROL_STOP_POINT - get_dead_zone())))
{
// 如果刹车计数小于等待时间1000个单位时间
if (p->brake_count++ < mode_control_get_wait_ticks(1000))
{
// 设置补偿标志为真
p->compensate_flag = TRUE;
// 设置最大最小幅度为刹车百分比
max_min.min = p->real_data.balance_percent;
max_min.max = p->real_data.balance_percent;
}
else
{
// 清除步进、刹车、补偿标志
p->step_flag = FALSE;
p->brake_flag = FALSE;
p->compensate_flag = FALSE;
// 清除刹车计数
p->brake_count = 0;
}
}
// 设置模糊PID的范围为最大最小幅度
_pid.pid_u.fuzzy.set_range(&_pid.pid_u.fuzzy, max_min.min, max_min.max);
// 执行模糊PID计算得到控制输出
p->ctrl_output = _pid.pid_u.fuzzy.execute(&_pid.pid_u.fuzzy, p->ctrl_target, p->ctrl_feedback);
// 转换控制输出为百分比数组,并输出
mode_control_output(mode_control_percent_convert_arr(p->ctrl_output));
// 如果稳定标志为真且实际误差小于等于死区,且当前处于控制过程
if (p->stable.flag == TRUE && ABS(p->real_error) <= get_dead_zone() && mode_control->fsm.process_state == CONTROL_PROCESS_CONTROL)
{
// 更新最大最小幅度
limiting_amplitude_update(p->ctrl_target, p->ctrl_output);
}
}
```
# 控制问题
1。 充气和放气的最大值
确定充气和放气的最大值对于PID控制算法的性能至关重要因为这些值直接影响到控制系统的响应速度和稳定性。如何确定GPS2000这2个值
2。PID参数在30%行程下超调问题

View File

@ -0,0 +1,111 @@
# 模糊PID控制器设计文档
# 模糊PID控制器详细设计文档
## 1. 引言
### 1.1 目的
本文档旨在详细介绍模糊PID控制器的设计理念、实现方法和使用指南为开发者提供一套完整的模糊PID控制解决方案。
### 1.2 背景
PID控制器因其结构简单、稳定性好、易于实现等优点在工业控制系统中得到了广泛应用。然而传统PID控制器在面对复杂或非线性系统时性能表现不佳。模糊PID控制器通过引入模糊逻辑动态调整PID参数以适应系统在不同工作状态下的控制需求从而提高控制性能。
## 2. 设计概述
### 2.1 设计目标
- **适应性**:能够适应不同类型和不同工作状态的控制系统。
- **稳定性**:保证控制系统在各种工作条件下的稳定运行。
- **易用性**:提供简单易懂的接口,便于开发者快速实现和调试。
### 2.2 功能模块
模糊PID控制器主要包括以下几个功能模块
1. **模糊控制模块**负责根据输入的误差和误差变化率通过模糊逻辑计算出PID参数。
2. **SV平滑给定模块**:负责平滑控制目标值,减少控制过程中的突变。
3. **变速积分模块**:根据误差的大小调整积分速率,提高控制效率。
4. **参数设置模块**提供接口函数用于设置和调整PID参数。
## 3. 功能模块详细设计
### 3.1 模糊控制模块
#### 3.1.1 输入处理
- **误差处理**:将实时误差 `e`限制在预定的范围内,并进行模糊化处理。
- **误差变化率处理**:将误差变化率 `ec`进行相同的处理。
#### 3.1.2 模糊规则库
- **规则定义**根据系统的具体需求定义一套模糊规则用于计算PID参数。
- **规则应用**:根据输入的误差和误差变化率的模糊化值,通过模糊规则库计算出 `kp`、`ki`、`kd`。
### 3.2 SV平滑给定模块
- **平滑策略**:根据当前目标值与新目标值之间的差值,动态调整目标值变化的步长,实现平滑过渡。
### 3.3 变速积分模块
- **积分策略**:根据误差的大小,调整积分速率。误差较小时,使用完整积分;误差较大时,减小或停止积分。
### 3.4 参数设置模块
- **接口设计**提供一系列接口函数用于设置PID控制器的参数如输出限制、死区误差等。
## 4. 使用说明
### 4.1 初始化
- **控制器初始化**根据控制对象的特性初始化模糊PID控制器的相关参数和模糊规则库。
### 4.2 实时控制
- **参数调整**在控制循环中根据实时误差和误差变化率动态调整PID参数。
- **控制执行**根据调整后的PID参数执行PID控制算法输出控制信号。
### 4.3 参数调整
- **动态调整**根据系统运行情况通过参数设置模块调整PID参数优化控制效果。
## 5. 结论
模糊PID控制器通过动态调整PID参数提高了控制系统的适应性和稳定性特别适用于复杂或非线性系统的控制。本文档提供了模糊PID控制器的详细设计方案旨在帮助开发者更好地理解和应用模糊PID控制技术
## 概述
本文档旨在详细介绍模糊PID控制器的设计与实现。模糊PID控制器结合了传统PID控制和模糊逻辑控制的优点通过模糊逻辑对PID参数进行动态调整以适应控制系统在不同工作状态下的需求。
## 功能模块
### 1. 模糊控制模块
- **功能描述**:根据误差 `e`和误差变化率 `ec`的模糊化值通过模糊规则库计算出模糊PID控制器的三个参数比例系数 `kp`、积分系数 `ki`、微分系数 `kd`
- **实现方法**:首先将输入的误差 `e`和误差变化率 `ec`限制在预定范围内,然后通过模糊化处理得到其隶属度和模糊位置标号,最后根据模糊规则库计算出 `kp`、`ki`、`kd`的值。
### 2. SV平滑给定模块
- **功能描述**平滑控制目标值Setpoint Value, SV以减少控制过程中的突变提高系统的稳定性。
- **实现方法**:根据当前目标值与新目标值之间的差值,动态调整目标值的变化步长,以实现平滑过渡。
### 3. 变速积分模块
- **功能描述**:根据误差的大小调整积分速率,以提高控制系统的快速性和稳定性。
- **实现方法**:当误差较小时,使用完整积分;当误差在一定范围内变化时,通过线性函数调整积分速率;当误差较大时,减小或停止积分,以避免积分饱和。
### 4. 参数设置模块
- **功能描述**提供接口函数用于设置PID控制器的各项参数包括输出限制范围、死区误差、积分输出值、PID参数等。
- **实现方法**:根据控制器的子类型(位置型或增量型),分别设置相应参数的值。
## 使用说明
1. **初始化**根据控制对象的具体情况初始化模糊PID控制器的结构体包括最大误差、最小误差、PID参数的模糊规则库等。
2. **实时控制**:在控制循环中,根据当前的误差 `e`和误差变化率 `ec`调用模糊控制模块计算出动态调整的PID参数然后根据这些参数进行PID控制。
3. **参数调整**根据系统运行情况通过参数设置模块调整PID控制器的参数以优化控制效果。
## 结论
模糊PID控制器通过引入模糊逻辑使得PID参数能够根据控制系统的实时状态动态调整从而提高了控制系统的适应性和稳定性。通过本文档的设计与实现开发者可以更好地理解和应用模糊PID控制器。

View File

@ -0,0 +1,126 @@
#include "at_bluetooth.h"
#define MEM_CACHE_LEN (64U)
unsigned char bluetooth_state = 0;
static unsigned char at_memcmp_cache[MEM_CACHE_LEN];
static unsigned char at_cmd_test(unsigned char *p, unsigned char len);
static unsigned char at_cmd_name(unsigned char *p, unsigned char len);
#if BLE_TYPE == BLE_TYPE_HC42
/* AT指令表 */
const at_cmd_func_t at_cmd_func[] = {
{AT_CMD_TEST, "AT", at_cmd_test},
{AT_CMD_NAME_REQ, "AT+NAME", at_cmd_name},
{AT_CMD_NAME, "AT+NAME=", at_cmd_name},
{AT_END, NULL, NULL}};
const char split_c = '=';
#elif BLE_TYPE == BLE_TYPE_MX02
/* AT指令表 */
const at_cmd_func_t at_cmd_func[] = {
{AT_CMD_TEST, "AT", at_cmd_test}, // 这个指令没用为了和HC42统一
{AT_GET_VER, "AT+VER", at_cmd_test},
{AT_CMD_NAME_REQ, "AT+NAME", at_cmd_name},
{AT_CMD_NAME, "AT+NAME=", at_cmd_name},
{AT_END, NULL, NULL}};
const char split_c = ':';
#endif
void at_set_memcmp_cache(unsigned char *p, unsigned char len)
{
osel_memset(at_memcmp_cache, 0, MEM_CACHE_LEN);
osel_memcpy(at_memcmp_cache, p, len);
}
/* 指令执行函数 */
static unsigned char at_cmd_test(unsigned char *p, unsigned char len)
{
BIT_SET(bluetooth_state, BIT0);
return 0;
}
static unsigned char at_cmd_name(unsigned char *p, unsigned char len)
{
if (*p == split_c)
{
p++; // 偏移一个字节split_c
if (osel_memcmp(p, at_memcmp_cache, osel_mstrlen(at_memcmp_cache)) == 0) // 去掉最后\r\n
{
BIT_SET(bluetooth_state, BIT1);
}
}
return 0;
}
/* 查找指令表中对应的指令 */
unsigned char at_cmd_search(unsigned char *p, unsigned char len)
{
unsigned char ret = 0;
// unsigned char* pstr;
unsigned char i, n;
for (i = 1; at_cmd_func[i].cmd != AT_END; i++)
{
n = osel_mstrlen((unsigned char *)at_cmd_func[i].str);
if (!osel_memcmp(p, (unsigned char *)at_cmd_func[i].str, n))
{
ret = i;
break;
}
}
return ret;
}
/* AT指令解析 */
unsigned char at_cmd_parse(unsigned char *p, unsigned char len)
{
unsigned char ret = AT_SUCCESS;
unsigned char index = 0;
if (len < 2)
return AT_ERR; /* 不符合指令最小长度 */
if ((p[0] == 'A') && (p[1] == 'T'))
{
if (len == 2)
{ /* 测试指令 */
if (at_cmd_func[AT_CMD_TEST].cb != NULL)
at_cmd_func[AT_CMD_TEST].cb(NULL, 0); /* 执行测试指令 */
}
else if (p[2] == '+')
{ /* 执行指令解析 */
index = at_cmd_search(p, len); /* 查找匹配的执行指令0-已匹配,!0-未匹配 */
if (index)
{
if (at_cmd_func[index].cb != NULL)
{ /* 判断指令对应执行函数是否存在 */
unsigned char n;
n = osel_mstrlen((unsigned char *)at_cmd_func[index].str);
ret = at_cmd_func[index].cb(p + n, len - n); /* 执行对应的指令函数, p+n:将指令参数传输执行函数len-n-2:指令参数有效长度 */
}
else
ret = AT_ERR_FUN_UNUSED; /* 没有可执行函数 */
}
else
{
ret = AT_ERR_UNINVAIL; /* 未找到匹配的指令 */
}
}
}
else
{ /* 格式不匹配 */
return AT_ERR;
}
return ret;
}

View File

@ -21,8 +21,95 @@
#include "eeprom_fm24.h"
#include "mode.h"
#define EQUAL_ALPHA 50.0f // 等百分比范围比
#define LOG_ALPHA log(EQUAL_ALPHA)
static float32 last_travel = 0; // 上次目标值
/**
* @brief ,
*
*
*
* @param setpoint
*
* @return
*
* @note 01000
* b * log(setpoint) / log(base) + linear_coefficient * setpoint
* b为13.25linear_coefficient为0.123base为对数底数2
*/
static inline float32 logarithmic_conversion(float32 setpoint)
{
static const float32 b = 13.24f;
static const float32 linear_coefficient = 0.123f;
static const float32 base_log = 0.6931471805599453f; // 直接使用log(2)的预计算值
float32 res = 0.0f;
if (setpoint <= 0)
{
return 0;
}
else if (setpoint >= 100)
{
return 100;
}
else
{
res = b * log(setpoint) / base_log + linear_coefficient * setpoint;
if (res < 0)
{
res = 0.0f;
}
else if (res > 100)
{
res = 100.0f;
}
return res;
}
}
/**
* @brief
*
*
*
* @param setpoint
*
* @return
*/
static float32 travel_char_custom_conversion(float32 setpoint)
{
float32 res = 0.0f;
// 获取自定义属性表指针
custom_property_table_t *p = (custom_property_table_t *)&udevice.custom_property_table;
// 遍历所有点
for (uint8_t i = 0; i < p->points; i++)
{
// 将无符号16位整数转换为浮点数得到当前点的设定值最小值
float32 setpoint_min = UINT16_TO_FLOAT(p->setpoint[i]);
// 将无符号16位整数转换为浮点数得到当前点的设定值最大值下一个点的设定值最小值
float32 setpoint_max = UINT16_TO_FLOAT(p->setpoint[i + 1]);
// 判断输入设定值是否在当前设定值范围内
if (setpoint >= setpoint_min && setpoint <= setpoint_max)
{
// 将无符号16位整数转换为浮点数得到当前点的对应值最小值
float32 min = UINT16_TO_FLOAT(p->value[i]);
// 将无符号16位整数转换为浮点数得到当前点的对应值最大值下一个点的对应值最小值
float32 max = UINT16_TO_FLOAT(p->value[i + 1]);
// 计算斜率:线性
float32 k = (max - min) / (setpoint_max - setpoint_min);
// 根据斜率和输入设定值计算对应值
res = k * (setpoint - setpoint_min) + min;
// 跳出循环
break;
}
}
// 返回计算得到的对应值
return res;
}
/**
* @brief
* @param {char} *s -
@ -72,7 +159,7 @@ void hart_long_address_to_string(char *s, uint8_t *sn, uint8_t len)
{
for (uint8_t i = 0; i < len; i++)
{
s[i] = NUM_TO_ASCII(*(sn + i));
sprintf(s + i * 2, "%02X", sn[i]);
}
}
@ -85,7 +172,8 @@ void hart_long_address_to_string(char *s, uint8_t *sn, uint8_t len)
float32 get_show_travel(float32 in)
{
float32 travel = in;
travel = travel < 0 ? 0 : travel;
travel = travel > 100 ? 100 : travel;
if (udevice.display_travel_mode == TRAVEL_DISPLAY_REVERSE) // 反向显示
{
travel = 100 - travel;
@ -94,6 +182,63 @@ float32 get_show_travel(float32 in)
return travel;
}
/**
* @brief 1%,
* @param {float32} tag
* @param {float32} cur
* @param {float32} err
* @return {*}
* @note
*/
float32 get_show_actual_travel(float32 tag, float32 cur, float32 err)
{
if (ABS(tag - cur) <= err)
{
return tag;
}
else
{
if (ABS(tag - cur) < err * 2)
{
if (cur < tag)
{
return cur + err;
}
else
{
return cur - err;
}
}
else
{
return cur;
}
}
}
/**
* @brief
*
* ASCII
*
* @return uint32_t
*/
uint32_t dev_serial_num_deal(void)
{
uint8_t b[INST_SERIAL_NUM_LEN];
uint8_t c[3];
for (uint8_t i = 0; i < INST_SERIAL_NUM_LEN; i++)
{
b[i] = ASCII_TO_NUM(udevice.dev_serial_num[i]);
}
c[0] = (b[INST_SERIAL_NUM_LEN - 6] << 4) | b[INST_SERIAL_NUM_LEN - 5];
c[1] = (b[INST_SERIAL_NUM_LEN - 4] << 4) | b[INST_SERIAL_NUM_LEN - 3];
c[2] = (b[INST_SERIAL_NUM_LEN - 2] << 4) | b[INST_SERIAL_NUM_LEN - 1];
return c[0] << 16 | c[1] << 8 | c[2];
}
/**
* @brief PID控制行程
* @param {float32} in -
@ -104,31 +249,31 @@ float32 get_pid_travel(float32 in)
{
float32 travel = in;
if (udevice.value_action_type == ATC) // 气关
if (udevice.zero_power_condition == VALVE_OPEN) // 气关
{
travel = 100 - travel;
}
return travel;
}
/**
* @brief
* @brief ,SWO输出和PWM输出
* @param {float32} in -
* @return {*}
* @note
*/
float32 actual_travel_deal(float32 in)
void actual_travel_deal(float32 in)
{
float32 travel = in;
if (udevice.dev_work_mode != TEST_MODE)
if (udevice.control_mode == DIGITAL_CTRL_MODE || udevice.control_mode == ANALOG_CTRL_MODE)
{
// SWO输出
swo_output_deal(travel);
// PWM输出阀位占空比
pwm_output_deal(travel);
}
return travel;
}
/**
@ -141,7 +286,7 @@ void pwm_output_deal(float32 in)
{
float32 travel = in;
if (udevice.output_current_enable == true) // pwm输出使能
if (udevice.output_current_enable == true && calib_param[CALIBPARA_VIP].is_calibration == TRUE) // pwm输出使能
{
pwm_output_position(travel);
}
@ -154,13 +299,13 @@ void swo_output_deal(float32 in)
if (udevice.swo_logic[0] == TRIGGER_LOGIC_BELOW)
{
if (travel < udevice.swo_value[0])
SWO1_OPEN();
else
SWO1_CLOSE();
else
SWO1_OPEN();
}
else if (udevice.swo_logic[0] == TRIGGER_LOGIC_ABOVE)
{
if (travel > udevice.swo_value[0])
if (travel < udevice.swo_value[0])
SWO1_OPEN();
else
SWO1_CLOSE();
@ -172,10 +317,10 @@ void swo_output_deal(float32 in)
if (udevice.swo_logic[1] == TRIGGER_LOGIC_BELOW)
{
if (travel < udevice.swo_value[1])
SWO2_OPEN();
else
if (travel > udevice.swo_value[1])
SWO2_CLOSE();
else
SWO2_OPEN();
}
else if (udevice.swo_logic[1] == TRIGGER_LOGIC_ABOVE)
{
@ -203,10 +348,11 @@ float32 target_travel_deal(float32 in)
// 小信号切除
travel = small_signal_deal(travel);
// 死区处理
travel = dead_zone_deal(travel);
// travel = dead_zone_deal(travel);
// 分程处理
travel = part_travel_deal(travel);
travel = floorf(travel * 100.f) / 100.f;
return travel;
}
@ -241,7 +387,7 @@ float32 dead_zone_deal(float32 in)
float32 travel = in;
float32 target_diff = fabsf(travel - last_travel);
if (target_diff >= udevice.travel_dead)
if (target_diff >= udevice.integral_db)
{
last_travel = travel;
}
@ -258,28 +404,41 @@ float32 dead_zone_deal(float32 in)
float32 small_signal_deal(float32 in)
{
float32 travel = in;
float32 travel_cut_lower = 0;
float32 travel_cut_upper = 0;
float32 cutoff_limit_lo = 0;
float32 cutoff_limit_hi = 0;
if (udevice.travel_cut_enable > 0) // 使能,使用设定值
if (udevice.travel_cut_enable == TRUE) // 使能,使用设定值
{
travel_cut_lower = udevice.travel_cut_lower;
travel_cut_upper = udevice.travel_cut_upper;
cutoff_limit_lo = udevice.cutoff_limit_lo;
cutoff_limit_hi = udevice.cutoff_limit_hi;
}
else // 禁用,使用默认值
{
travel_cut_lower = 0;
travel_cut_upper = 100;
cutoff_limit_lo = 0;
cutoff_limit_hi = 100;
}
// 最大最小需要快速的反应
if (travel >= travel_cut_upper) // 上限
if (travel >= 0 && travel <= 100)
{
travel = 100.0;
// 最大最小需要快速的反应
if (travel >= cutoff_limit_hi) // 上限
{
travel = 100.0;
rt_data.flag.bits.small_signal_deal = TRUE;
}
else if (travel <= cutoff_limit_lo) // 下限
{
travel = 0;
rt_data.flag.bits.small_signal_deal = TRUE;
}
else
{
rt_data.flag.bits.small_signal_deal = FALSE;
}
}
else if (travel <= travel_cut_lower) // 下限
else
{
travel = 0;
rt_data.flag.bits.small_signal_deal = FALSE;
}
return travel;
@ -292,57 +451,48 @@ float32 small_signal_deal(float32 in)
*/
float32 i2psb(float32 in)
{
float32 deltI, ftmp;
float32 travel;
uint16_t index;
if (in < LOOP_CURRENT_MIN)
float32 travel_target_percent = 0.0f, ftmp = 0.0f;
float32 travel = 0.0f;
// 线性 等百分比 快开 : 输入的电流值直接转换成百分比
float32 normalized_in = CURRENT_PERCENT(in); // 计算一次,复用结果
switch (udevice.travel_char)
{
case TRAVEL_CHAR_LINEAR:
travel_target_percent = normalized_in * 100; // 线性:电流百分百就是行程百分比
break;
case TRAVEL_CHAR_EQUAL: // 等百分比
travel_target_percent = (exp(normalized_in * LOG_ALPHA) - 1) * 100 / (EQUAL_ALPHA - 1); // 使用指数函数和预定义的常数LOG_ALPHA和EQUAL_ALPHA来计算等百分比行程
break;
case TRAVEL_CHAR_QUICK_OPEN: // 快开
travel_target_percent = logarithmic_conversion(normalized_in * 100); // 调用logarithmic_conversion函数来计算快开特性的行程百分比
break;
case TRAVEL_CHAR_CUSTOM: // 自定义特性
travel_target_percent = travel_char_custom_conversion(normalized_in * 100);
break;
default:
return 0;
}
else
{
// 计算相邻两个点之间的电流差值
deltI = udevice.input_upper - udevice.input_lower;
deltI /= 16;
// 判断输入电流在哪个范围内
ftmp = in - LOOP_CURRENT_MIN;
index = ftmp / deltI;
/* 计算百分比
(I - Iindex)
% = ------------- * (%[index+1]-%[index]) + %[index]
deltI
*/
if (index > 15)
{
ftmp = valve_characteristics_table[udevice.valve_chart][16];
}
else
{
ftmp = in - LOOP_CURRENT_MIN;
ftmp -= deltI * index;
ftmp /= deltI;
ftmp *= (valve_characteristics_table[udevice.valve_chart][index + 1] - valve_characteristics_table[udevice.valve_chart][index]);
ftmp += valve_characteristics_table[udevice.valve_chart][index];
}
}
ftmp /= 100;
ftmp = travel_target_percent;
/*
I增大时
I增大时
I增大时
I增大时
*/
if (udevice.value_action_type == ATO)
if (udevice.zero_power_condition == VALVE_CLOSE)
{
// 气开
if (udevice.dev_driver_dir == CONTROLLER_ACTING_NORMAL)
if (udevice.act_style.bits.dev_driver_dir == CONTROLLER_ACTING_NORMAL)
{
// 定位器正作用:电流增大->气压增大->弹簧压缩->开方向->%增大(正显示、反馈)
travel = ftmp;
}
else if (udevice.dev_driver_dir == CONTROLLER_ACTING_REVERSE)
else if (udevice.act_style.bits.dev_driver_dir == CONTROLLER_ACTING_REVERSE)
{
// 定位器反作用:电流增大->气压减小->弹簧释放->关方向->%减小(正显示、反馈)
travel = 100 - ftmp;
@ -355,7 +505,7 @@ float32 i2psb(float32 in)
else
{
// 气关
if (udevice.dev_driver_dir == CONTROLLER_ACTING_NORMAL)
if (udevice.act_style.bits.dev_driver_dir == CONTROLLER_ACTING_NORMAL)
{
// 定位器正作用:电流增大->气压增大->弹簧压缩->关方向->%减小(正显示、反馈)
travel = 100 - ftmp;
@ -367,26 +517,77 @@ float32 i2psb(float32 in)
}
}
if (travel < 0)
travel = 0;
else if (travel > 100)
travel = 100;
if (travel < MIN_TARGET_PERCENT)
{
travel = MIN_TARGET_PERCENT;
}
else if (travel > MAX_TARGET_PERCENT)
{
travel = MAX_TARGET_PERCENT;
}
return travel;
}
/**
* @brief
* @brief
* @param {float32} celsius
* @return {float32}
* @return {float32} fahrenhite
* @note
*/
float32 temperature_c2f(float32 celsius)
float32 temperature_c2unit(float32 in, uint16_t unit)
{
float32 temp = 32 + celsius * 1.8f;
float32 temp = 0.0f;
switch (unit)
{
case TEMPERATURE_UNIT_C: // ℃
temp = in;
break;
case TEMPERATURE_UNIT_F: // ℉
temp = 32 + in * 1.8f;
break;
default:
temp = in;
break;
}
return temp;
}
/**
* @brief kPa
*
* kPa
*
* @param in
* @param unit
*
* @return kPa
*/
float32 pressure_unit2kpa(float32 in, uint16_t unit)
{
float32 pre = 0;
switch (unit)
{
case PRESSURE_UNIT_KPA: // kPa
pre = in;
break;
case PRESSURE_UNIT_PSI: // psi
pre = in / 0.145037743897f;
break;
case PRESSURE_UNIT_BAR: // bar
pre = in / 0.01f;
break;
case PRESSURE_UNIT_KGF: // kgf/cm2
pre = in / 0.0101972f;
break;
default:
pre = in;
break;
}
return pre;
}
/**
* @brief kPa -> mPa psi bar kgf/cm2
* @param {float32} kpa kPa
@ -399,21 +600,21 @@ float32 pressure_kpa2unit(float32 kpa, uint16_t unit)
float32 pre = 0;
switch (unit)
{
case PRESSURE_UNIT_Kpa: // kPa
case PRESSURE_UNIT_KPA: // kPa
pre = kpa;
break;
case PRESSURE_UNIT_Mpa: // mPa
pre = kpa * 0.001f;
break;
case PRESSURE_UNIT_Psi: // psi
case PRESSURE_UNIT_PSI: // psi
pre = kpa * 0.145037743897f;
break;
case PRESSURE_UNIT_Bar: // bar
case PRESSURE_UNIT_BAR: // bar
pre = kpa * 0.01f;
break;
case PRESSURE_UNIT_Kgf: // kgf/cm2
case PRESSURE_UNIT_KGF: // kgf/cm2
pre = kpa * 0.0101972f;
break;
case PRESSURE_UNIT_MPA: // MPA
pre = kpa * 0.01f;
break;
default:
pre = kpa;
break;
@ -421,6 +622,30 @@ float32 pressure_kpa2unit(float32 kpa, uint16_t unit)
return pre;
}
/**
* @brief
* @param {uint16_t} unit
* @return {*}
* @note
*/
BOOL pressure_unit_need_decimal_display(uint16_t unit)
{
BOOL ret = FALSE;
switch (unit)
{
case PRESSURE_UNIT_KPA: // kPa
ret = TRUE;
break;
case PRESSURE_UNIT_PSI: // psi
case PRESSURE_UNIT_BAR: // bar
case PRESSURE_UNIT_KGF: // kgf/cm2
default:
ret = FALSE;
break;
}
return ret;
}
/**
* @brief
* @param {char} *s -
@ -433,20 +658,20 @@ void get_pressure_unit(char *s, uint16_t unit)
DBG_ASSERT(s != NULL __DBG_LINE);
switch (unit)
{
case PRESSURE_UNIT_Kpa: // kPa
case PRESSURE_UNIT_KPA: // kPa
sprintf(s, "kPa");
break;
case PRESSURE_UNIT_Mpa: // mPa
sprintf(s, "mPa");
break;
case PRESSURE_UNIT_Psi: // psi
case PRESSURE_UNIT_PSI: // psi
sprintf(s, "psi");
break;
case PRESSURE_UNIT_Bar: // bar
case PRESSURE_UNIT_BAR: // bar
sprintf(s, "bar");
break;
case PRESSURE_UNIT_Kgf: // kgf/cm2
sprintf(s, "kgf/cm2");
case PRESSURE_UNIT_KGF: // kgf/cm2
sprintf(s, "kgf");
break;
case PRESSURE_UNIT_MPA: // mpa
sprintf(s, "mPa");
break;
default:
sprintf(s, "kPa");
@ -455,12 +680,118 @@ void get_pressure_unit(char *s, uint16_t unit)
}
/**
* @brief
* @param {uint16_t} psi_adc
* @brief
* @param {float32} i
* @param {uint16_t} unit
* @return {*}
* @note
*/
float32 pressure_adc_to_percent(uint16_t psi_adc)
float32 get_pressure_limit_deal(float32 in, uint16_t unit)
{
return (float32)psi_adc * 100 / (float32)ADC_MAX;
float32 max = 1000;
float32 min = 10;
switch (unit)
{
case PRESSURE_UNIT_KPA: // kPa
min = 20;
break;
case PRESSURE_UNIT_PSI: // psi
max = max * 0.145037743897f;
min = 1;
break;
case PRESSURE_UNIT_BAR: // bar
max = max * 0.01f;
min = 0.1;
break;
case PRESSURE_UNIT_MPA: // Mpa
max = max * 0.01f;
min = 0.1;
break;
case PRESSURE_UNIT_KGF: // kgf/cm2
max = max * 0.0101972f;
min = 0.1;
break;
default:
min = 10;
break;
}
if (in > max)
{
return max;
}
else if (in < min)
{
return 0;
}
else
{
return in;
}
}
// 将压力数据转换成百分比
float32 pressure_to_percent(float32 pressure)
{
return (pressure * 100.0f) / (udevice.press_100_percent - udevice.press_0_percent);
}
// 判断是否双作用
BOOL is_double_acting(void)
{
return udevice.act_style.bits.value_relay_type % 2 != 0 ? TRUE : FALSE;
}
// 计算校准参数
void calib_param_calculate(calibration_e index, int16_t offset, int16_t span, float32 min, float32 max)
{
calib_param_t *p = (calib_param_t *)&calib_param[index];
DBG_ASSERT(p != NULL __DBG_LINE);
float32 adc_min = 0.0f;
float32 adc_max = 0.0f;
float32 ma = 0.0f;
float32 adc = 0.0f;
p->offset = offset;
p->span = span;
p->max = max;
p->min = min;
adc_min = p->original_adc_value[0] + offset;
adc_max = p->original_adc_value[1] + offset;
ma = max - min;
adc = adc_max - adc_min;
p->slope = ma / adc;
p->is_calibration = TRUE; // 标记已校准
p->crc = crc32_compute((uint8_t *)p, sizeof(calib_param_t) - sizeof(uint32_t));
}
// AD值线性转换
float32 adc_linear_conversion(calibration_e index, uint16_t adc)
{
float32 f = 0.0f;
calib_param_t *p = (calib_param_t *)&calib_param[index];
DBG_ASSERT(p != NULL __DBG_LINE);
if (p->is_calibration)
{
f = ((adc - (p->original_adc_value[0] + p->offset))) * p->slope;
}
return f;
}
// 上次整定状态更新
void last_tuned_state_update(void)
{
switch (udevice.tuned_flag)
{
case TUNED_NONE:
udevice.auto_cal_status = NEVER_HAPPENED;
break;
case TUNED_SUCCESS:
udevice.auto_cal_status = CAL_SUCCESS;
break;
case TUNED_FAILED:
udevice.auto_cal_status = TIMEOUT;
break;
default:
break;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -13,132 +13,227 @@
KVKey-Value fal_execution_kv_write() KV
fal_execution_inspection() fal_execution_kv_read() 使 fal_execution_get()
fdb_kv_get_blob() KV blob 0
fal_execution_set_crc() fal_execution_set_cmac() CRC CMAC TRUE FALSE
fal_execution_set_crc() CRC TRUE FALSE
fal_execution_kv_write() 使 fal_execution_get()
fdb_kv_set_blob() KV fal_execution_set_crc() fal_execution_set_cmac()
CRC CMAC TRUE FALSE fal_execution_inspection()
fdb_kv_set_blob() KV fal_execution_set_crc()
CRC校验 TRUE FALSE fal_execution_inspection()
M95_1 FM24 HART HART
0 FM24
*/
#include "fal_execution.h"
#include "board.h"
#include "sys.h"
#include "delay.h"
#include "entity.h"
#include "cmac.h"
#include "mode_diagnosis.h"
#include "diagnosis.h"
#define FAL_DBG_ENABLE 0 // 等测试完成后再删除
const char *FAL_KV_KEY[KEY_MAX] =
const char *fal_kv_key[KEY_MAX] =
{
"calibpara_param",
"device",
"hart_device_variable_param",
"real_time_data",
"mode_param",
};
static fal_execution_status_t fal_execution_status; // eeprom状态
static fal_execution_t fal_executions[FAL_EXECUTION_MAX];
static struct fdb_default_kv_node m95_1_kv_table[] = {
{(char *)&FAL_KV_KEY[KEY_CALIBPARA_PARAM], &calib_param, sizeof(calib_param_t) * CALIBPARA_NUM}, // 校准参数
{(char *)&FAL_KV_KEY[KEY_DEVICE], &udevice, sizeof(device_typedef)}, // 设备内设置的信息
{(char *)&FAL_KV_KEY[KEY_MODE_PARAM], &mode_params, sizeof(mode_params_t)}, // 模式参数:控制算法自定义参数
};
"noinit_data", // 非初始化数据
"device", // 设备信息
"rt_data", // 实时数据
"diag_rst", // 诊断结果
}; // 里面的顺序要和fal_key_e一一对应
fal_execution_t fal_executions[FAL_EXECUTION_MAX];
fal_execution_status_t fal_execution_status; // eeprom状态
static struct fdb_default_kv_node m95_1_kv_table[] = {};
static struct fdb_default_kv_node fm24_kv_table[] = {
{(char *)&FAL_KV_KEY[KEY_REAL_TIME_DATA], &rt_data, sizeof(real_time_data_t)}, // 实时数据
{(char *)&fal_kv_key[KEY_DEVICE], (void *)&udevice, sizeof(udevice_t)}, // 设备内设置的信息
{(char *)&fal_kv_key[KEY_DIAGNOSIS_RESULT], (void *)&diag_result, sizeof(diag_result_t)}, // 诊断结果
{(char *)&fal_kv_key[KEY_NOINIT_DATA], (void *)&noinit_data, sizeof(noinit_data_t)}, // 非初始化数据
{(char *)&fal_kv_key[KEY_REAL_TIME_DATA], (void *)&rt_save, sizeof(rt_save_param_t)}, // 实时数据
};
// 数据加密校验
typedef struct
{
uint8_t mic[4];
} fal_inspection_cmac_t;
uint32_t fal_inspection_crc[KEY_MAX];
static struct flow fal_execution_fw; // fal执行流程
struct flow_sem fal_write_sem; // 有的是突发的写入检查
static uint8_t cmac_key[] = {
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; // 密钥
static uint16_t fal_inspection_crc[KEY_MAX]; // 用于保存结构体CRC值保证相同数据内容不写入
static fal_inspection_cmac_t fal_inspection_cmac[KEY_MAX]; // 用于保存结构体CMAC值保证相同数据内容不写入
static fal_execution_t *fal_execution_get(const fal_key_e key); // 获取fal_execution_t结构体
// 内部接口 // 获取时间戳
static fal_execution_t *fal_execution_get(const fal_key_e key); // 获取fal_execution_t结构体
static void fal_execution_set_crc(const uint8_t index, const uint8_t *const data, const uint16_t length); // 数据的CRC计算
static void fal_execution_set_cmac(const uint8_t index, const uint8_t *const data, const uint16_t length); // 数据的CMAC计算
static BOOL fal_execution_data_storage_check(const uint8_t index, const uint8_t *const data, const uint16_t length); // 数据的校验
/**
* @brief fal执行初始化
* @return {*}
* @note
*/
void fal_execution_init(void)
void fal_execution_init(fal_execution_e index, uint16_t data_size)
{
fal_execution_status.init.data = 0;
fal_execution_status.read.data = 0;
fal_execution_status.write.data = 0;
static BOOL inited = FALSE;
uint32_t start_time = 0;
if (inited == FALSE)
{
fal_execution_status.init.data = 0;
fal_execution_status.read.data = 0;
fal_execution_status.write.data = 0;
osel_memset((uint8_t *)&fal_inspection_crc, 0, sizeof(uint32_t) * KEY_MAX);
inited = TRUE;
FL_INIT(&fal_execution_fw); // fal执行
}
fal_execution_t *p = NULL;
fdb_err_t res = FDB_NO_ERR;
osel_memset((uint8_t *)&fal_inspection_crc, 0, sizeof(uint16_t) * KEY_MAX);
// 初始化M95_1
p = &fal_executions[FAL_EXECUTION_EEPROM_M95_1];
p->eeprom_index = FAL_EXECUTION_EEPROM_M95_1;
p->kv.kvs = m95_1_kv_table;
p->kv.num = ARRAY_LEN(m95_1_kv_table);
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_LOCK, NULL);
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_UNLOCK, NULL);
res = fdb_kvdb_init(&p->kvdb, "env", "KVDB", &p->kv, NULL);
if (res != FDB_NO_ERR)
switch (index)
{
fal_execution_status.init.bits.M95_1 = 0;
fal_execution_status.read.bits.M95_1 = 0;
fal_execution_status.write.bits.M95_1 = 0;
case FAL_EXECUTION_EEPROM_M95_1:
{
DBG_ASSERT(data_size <= EEPROM_M95_1_BLOCK_SIZE __DBG_LINE);
// 初始化M95_1
p = &fal_executions[FAL_EXECUTION_EEPROM_M95_1];
p->storage_index = FAL_EXECUTION_EEPROM_M95_1;
p->read_key = KEY_MAX;
p->write_key = KEY_MAX;
p->kv.kvs = m95_1_kv_table;
p->kv.num = ARRAY_LEN(m95_1_kv_table);
p->data_size = data_size;
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_LOCK, NULL);
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_UNLOCK, NULL);
start_time = sys_millis();
res = fdb_kvdb_init(&p->kvdb, "env", "KVDB", &p->kv, NULL);
p->init_use_time = sys_millis() - start_time;
if (res != FDB_NO_ERR)
{
fal_execution_status.init.bits.M95_1 = 0;
fal_execution_status.read.bits.M95_1 = 0;
fal_execution_status.write.bits.M95_1 = 0;
}
else
{
fal_execution_status.init.bits.M95_1 = 1;
fal_execution_status.read.bits.M95_1 = 1;
fal_execution_status.write.bits.M95_1 = 1;
}
break;
}
else
case FAL_EXECUTION_EEPROM_M95_2:
{
fal_execution_status.init.bits.M95_1 = 1;
fal_execution_status.read.bits.M95_1 = 1;
fal_execution_status.write.bits.M95_1 = 1;
DBG_ASSERT(data_size <= EEPROM_M95_2_BLOCK_SIZE __DBG_LINE);
// 初始化M95_2
p = &fal_executions[FAL_EXECUTION_EEPROM_M95_2];
p->read_key = KEY_MAX;
p->write_key = KEY_MAX;
p->storage_index = FAL_EXECUTION_EEPROM_M95_2;
p->data_size = data_size;
fdb_tsdb_control(&p->tsdb, FDB_TSDB_CTRL_SET_LOCK, NULL);
fdb_tsdb_control(&p->tsdb, FDB_TSDB_CTRL_SET_UNLOCK, NULL);
start_time = sys_millis();
res = fdb_tsdb_init(&p->tsdb, "log", "TSDB", fal_execution_get_time, 128, NULL);
p->init_use_time = sys_millis() - start_time;
if (res != FDB_NO_ERR)
{
fal_execution_status.init.bits.M95_2 = 0;
fal_execution_status.read.bits.M95_2 = 0;
fal_execution_status.write.bits.M95_2 = 0;
}
else
{
fal_execution_status.init.bits.M95_2 = 1;
fal_execution_status.read.bits.M95_2 = 1;
fal_execution_status.write.bits.M95_2 = 1;
}
break;
}
case FAL_EXECUTION_EEPROM_FM24:
{
DBG_ASSERT(data_size <= EEPROM_FM24_BLOCK_SIZE __DBG_LINE);
// 初始化FM24
p = &fal_executions[FAL_EXECUTION_EEPROM_FM24];
p->storage_index = FAL_EXECUTION_EEPROM_FM24;
p->read_key = KEY_MAX;
p->write_key = KEY_MAX;
p->kv.kvs = fm24_kv_table;
p->kv.num = ARRAY_LEN(fm24_kv_table);
p->data_size = data_size;
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_LOCK, NULL);
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_UNLOCK, NULL);
start_time = sys_millis();
res = fdb_kvdb_init(&p->kvdb, "env", "RTDB", &p->kv, NULL);
p->init_use_time = sys_millis() - start_time;
if (res != FDB_NO_ERR)
{
fal_execution_status.init.bits.FM24 = 0;
fal_execution_status.read.bits.FM24 = 0;
fal_execution_status.write.bits.FM24 = 0;
}
else
{
fal_execution_status.init.bits.FM24 = 1;
fal_execution_status.read.bits.FM24 = 1;
fal_execution_status.write.bits.FM24 = 1;
}
break;
}
default:
DBG_ASSERT(FALSE __DBG_LINE);
break;
}
p->statistics_enable = FALSE;
}
/**
* @brief FAL
*
* FAL FAL
*
* @param index FAL
* @param enable TRUE FALSE
*/
void fal_execution_statistics_enable(fal_execution_e index, BOOL enable)
{
fal_execution_t *p = NULL;
p = &fal_executions[index];
p->statistics_enable = enable;
}
/**
* @brief FAL
*
* FAL
* 使
*
* @param index FAL
*/
void fal_execution_statistics(fal_execution_e index)
{
fal_execution_t *p = NULL;
p = &fal_executions[index];
uint32_t start_time = 0;
if (p->statistics_enable == FALSE)
{
return;
}
// 初始化M95_2
p = &fal_executions[FAL_EXECUTION_EEPROM_M95_2];
p->eeprom_index = FAL_EXECUTION_EEPROM_M95_2;
fdb_tsdb_control(&p->tsdb, FDB_TSDB_CTRL_SET_LOCK, NULL);
fdb_tsdb_control(&p->tsdb, FDB_TSDB_CTRL_SET_UNLOCK, NULL);
res = fdb_tsdb_init(&p->tsdb, "log", "TSDB", fal_execution_get_time, 128, NULL);
if (res != FDB_NO_ERR)
start_time = sys_millis();
// 占用百分百
{
fal_execution_status.init.bits.M95_2 = 0;
fal_execution_status.read.bits.M95_2 = 0;
fal_execution_status.write.bits.M95_2 = 0;
}
else
{
fal_execution_status.init.bits.M95_2 = 1;
fal_execution_status.read.bits.M95_2 = 1;
fal_execution_status.write.bits.M95_2 = 1;
// p->statistics.used = fdb_kv_used(&p->kvdb);
}
// 初始化FM24
p = &fal_executions[FAL_EXECUTION_EEPROM_FM24];
p->eeprom_index = FAL_EXECUTION_EEPROM_FM24;
p->kv.kvs = fm24_kv_table;
p->kv.num = ARRAY_LEN(fm24_kv_table);
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_LOCK, NULL);
fdb_kvdb_control(&p->kvdb, FDB_KVDB_CTRL_SET_UNLOCK, NULL);
res = fdb_kvdb_init(&p->kvdb, "env", "RTDB", &p->kv, NULL);
if (res != FDB_NO_ERR)
{
fal_execution_status.init.bits.FM24 = 0;
fal_execution_status.read.bits.FM24 = 0;
fal_execution_status.write.bits.FM24 = 0;
}
else
{
fal_execution_status.init.bits.FM24 = 1;
fal_execution_status.read.bits.FM24 = 1;
fal_execution_status.write.bits.FM24 = 1;
}
p->statistics_use_time = sys_millis() - start_time;
}
/**
* @brief
*
*
*
* @param index
* @param enable TRUE FALSE
*/
void fal_execution_set_enable(fal_execution_e index, BOOL enable)
{
fal_execution_t *p = NULL;
p = &fal_executions[index];
p->enable = enable;
}
/**
@ -181,16 +276,10 @@ static fal_execution_t *fal_execution_get(const fal_key_e key)
fal_execution_t *p = NULL;
switch (key)
{
case KEY_CALIBPARA_PARAM: // 校准参数
case KEY_DEVICE: // 设备内设置的信息
case KEY_MODE_PARAM: // 模式参数:控制算法自定义参数
case KEY_HART_DEVICE_VARIABLE_PARAM: // HART设备信息
if (fal_execution_status.init.bits.M95_1 == 1)
{
p = &fal_executions[FAL_EXECUTION_EEPROM_M95_1];
}
break;
case KEY_REAL_TIME_DATA: // 实时数据
case KEY_DEVICE: // 设备内设置的信息
case KEY_NOINIT_DATA: // 非初始化数据
case KEY_DIAGNOSIS_RESULT: // 诊断结果
case KEY_REAL_TIME_DATA: // 实时数据
if (fal_execution_status.init.bits.FM24 == 1)
{
p = &fal_executions[FAL_EXECUTION_EEPROM_FM24];
@ -211,33 +300,12 @@ static fal_execution_t *fal_execution_get(const fal_key_e key)
* @return {*}
* @note
*/
static void fal_execution_set_crc(const uint8_t index, const uint8_t *const data, const uint16_t length)
void fal_execution_set_crc(const uint8_t index, const uint8_t *const data, const uint16_t length)
{
uint16_t crc = crc16_compute(data, length);
uint32_t crc = crc32_compute(data, length);
fal_inspection_crc[index] = crc;
}
/**
* @brief CMAC计算
* @param {uint8_t} index
* @param {uint8_t} *data
* @param {uint16_t} length
* @return {*}
* @note
*/
static void fal_execution_set_cmac(const uint8_t index, const uint8_t *const data, const uint16_t length)
{
uint8_t mic[16];
uint8_t *p;
AES_CMAC_CTX AesCmacCtx[1]; // 密钥扩展表
AES_CMAC_Init(AesCmacCtx); // 完成密钥扩展表的初始化
AES_CMAC_SetKey(AesCmacCtx, cmac_key); // 完成密钥扩展表数据 // 存放生成校验数据的数组
AES_CMAC_Update(AesCmacCtx, data, length & 0xFF); // 完成数据的奇偶校验
AES_CMAC_Final(mic, AesCmacCtx); // 生成16个字节的校验表
uint32_t xor_vol = (uint32_t)((uint32_t)mic[3] << 24 | (uint32_t)mic[2] << 16 | (uint32_t)mic[1] << 8 | (uint32_t)mic[0]); // 取表4个字节作为校验码
p = (uint8_t *)&xor_vol;
osel_memcpy(fal_inspection_cmac[index].mic, p, 4);
}
/**
* @brief
* @param {uint8_t} index
@ -246,36 +314,15 @@ static void fal_execution_set_cmac(const uint8_t index, const uint8_t *const dat
* @return {*}
* @note CRC校验和CMAC校验
*/
static BOOL fal_execution_data_storage_check(const uint8_t index, const uint8_t *const data, const uint16_t length)
BOOL fal_execution_data_storage_check(const uint8_t index, const uint8_t *const data, const uint16_t length)
{
// CRC校验
uint32_t crc = 0;
crc = crc32_compute(data, length);
if (crc != fal_inspection_crc[index])
{
uint16_t crc = 0;
crc = crc16_compute(data, length);
if (crc != fal_inspection_crc[index])
{
return FALSE;
}
return FALSE;
}
// CMAC校验
{
uint8_t mic[16];
uint8_t *p;
AES_CMAC_CTX AesCmacCtx[1]; // 密钥扩展表
AES_CMAC_Init(AesCmacCtx); // 完成密钥扩展表的初始化
AES_CMAC_SetKey(AesCmacCtx, cmac_key); // 完成密钥扩展表数据 // 存放生成校验数据的数组
AES_CMAC_Update(AesCmacCtx, data, length & 0xFF); // 完成数据的奇偶校验
AES_CMAC_Final(mic, AesCmacCtx); // 生成16个字节的校验表
uint32_t xor_vol = (uint32_t)((uint32_t)mic[3] << 24 | (uint32_t)mic[2] << 16 | (uint32_t)mic[1] << 8 | (uint32_t)mic[0]); // 取表4个字节作为校验码
p = (uint8_t *)&xor_vol;
if (osel_memcmp(fal_inspection_cmac[index].mic, p, 4) != 0)
{
return FALSE;
}
}
return TRUE;
}
@ -286,15 +333,7 @@ fdb_time_t fal_execution_get_time(void)
*/
rtc_date_t dd;
rtc_time_t tt;
uDateTime_TypeDef timestamp; // 时间戳
get_timestamp((uDateTime_TypeDef *)&timestamp);
dd.year = hex_format_dec(timestamp.Date.Year);
dd.month = hex_format_dec(timestamp.Date.Month);
dd.day = hex_format_dec(timestamp.Date.Day);
tt.hour = hex_format_dec(timestamp.Date.Hour);
tt.minute = hex_format_dec(timestamp.Date.Minute);
tt.second = hex_format_dec(timestamp.Date.Second);
get_real_time((uint8_t *)&dd.year, &dd.month, &dd.day, &tt.hour, &tt.minute, &tt.second);
return (int32_t)time2stamp(&dd, &tt);
}
/**
@ -310,7 +349,8 @@ fdb_time_t fal_execution_get_time(void)
*/
BOOL fal_execution_kv_read(const fal_key_e key, const uint8_t *data, uint16_t length)
{
DBG_ASSERT(FAL_KV_KEY[key] != NULL __DBG_LINE);
DBG_ASSERT(fal_kv_key[key] != NULL __DBG_LINE);
uint32_t start_time = 0;
BOOL rv = FALSE;
struct fdb_blob blob; // 定义一个 fdb_blob 结构体变量 blob
fal_execution_t *p = fal_execution_get(key); // 将给定的键转换为相应的执行结构
@ -318,19 +358,28 @@ BOOL fal_execution_kv_read(const fal_key_e key, const uint8_t *data, uint16_t le
{
return FALSE;
}
fdb_kv_get_blob(&p->kvdb, FAL_KV_KEY[key], fdb_blob_make(&blob, data, length)); // 从 KV 存储中读取数据并存储在 blob 变量中
if (blob.saved.len > 0) // 如果 blob 变量中的数据长度大于 0
if (p->enable == FALSE)
{
fal_execution_set_crc((uint8_t)key, data, length); // 数据的CRC计算
fal_execution_set_cmac((uint8_t)key, data, length); // 数据的CMAC计算
rv = TRUE; // 返回 true
return FALSE;
}
start_time = sys_millis();
fdb_kv_get_blob(&p->kvdb, fal_kv_key[key], fdb_blob_make(&blob, data, length)); // 从 KV 存储中读取数据并存储在 blob 变量中
p->read_use_time = sys_millis() - start_time;
p->read_key = key;
if (blob.saved.len > 0)
{
fal_execution_set_crc((uint8_t)key, data, length); // 数据的CRC计算
rv = TRUE; // 返回 true
}
else
{
rv = FALSE; // 返回 false
__NOP();
}
switch (p->eeprom_index)
switch (p->storage_index)
{
case FAL_EXECUTION_EEPROM_M95_1:
fal_execution_status.read.bits.M95_1 = rv == TRUE ? 1 : 0;
@ -361,7 +410,13 @@ BOOL fal_execution_kv_read(const fal_key_e key, const uint8_t *data, uint16_t le
*/
BOOL fal_execution_kv_write(const fal_key_e key, const uint8_t *const data, const uint16_t length)
{
DBG_ASSERT(FAL_KV_KEY[key] != NULL __DBG_LINE);
if (get_current_by_resistance() < FAL_WRITE_CURRENT)
{
return TRUE;
}
DBG_ASSERT(fal_kv_key[key] != NULL __DBG_LINE);
uint32_t start_time = 0;
BOOL rv = FALSE;
struct fdb_blob blob;
fdb_err_t res = FDB_NO_ERR;
@ -370,13 +425,20 @@ BOOL fal_execution_kv_write(const fal_key_e key, const uint8_t *const data, cons
{
return FALSE;
}
if (p->enable == FALSE)
{
return FALSE;
}
res = fdb_kv_set_blob(&p->kvdb, FAL_KV_KEY[key], fdb_blob_make(&blob, data, length));
start_time = sys_millis();
res = fdb_kv_set_blob(&p->kvdb, fal_kv_key[key], fdb_blob_make(&blob, data, length));
p->write_use_time = sys_millis() - start_time;
p->write_key = key;
if (res == FDB_NO_ERR)
{
fal_execution_set_crc((uint8_t)key, data, length); // 数据的CRC计算
fal_execution_set_cmac((uint8_t)key, data, length); // 数据的CMAC计算
fal_execution_set_crc((uint8_t)key, data, length); // 数据的CRC计算
rv = TRUE;
}
else
@ -384,24 +446,65 @@ BOOL fal_execution_kv_write(const fal_key_e key, const uint8_t *const data, cons
rv = FALSE;
}
switch (p->eeprom_index)
switch (p->storage_index)
{
case FAL_EXECUTION_EEPROM_M95_1:
fal_execution_status.write.bits.M95_1 = rv == TRUE ? 1 : 0;
fal_execution_status.read.bits.M95_1 = rv == TRUE ? 1 : 0;
break;
case FAL_EXECUTION_EEPROM_M95_2:
fal_execution_status.write.bits.M95_2 = rv == TRUE ? 1 : 0;
fal_execution_status.read.bits.M95_2 = rv == TRUE ? 1 : 0;
break;
case FAL_EXECUTION_EEPROM_FM24:
fal_execution_status.write.bits.FM24 = rv == TRUE ? 1 : 0;
fal_execution_status.read.bits.FM24 = rv == TRUE ? 1 : 0;
break;
default:
DBG_ASSERT(FALSE __DBG_LINE);
break;
}
return rv;
}
/**
* @brief
*
*
*
* @param key
*
* @return
*/
void fal_execution_kv_delete(const fal_key_e key)
{
if (get_current_by_resistance() < FAL_WRITE_CURRENT)
{
return;
}
DBG_ASSERT(fal_kv_key[key] != NULL __DBG_LINE);
uint32_t start_time = 0;
fal_execution_t *p = fal_execution_get(key);
if (p == NULL)
{
return;
}
if (p->enable == FALSE)
{
return;
}
start_time = sys_millis();
fdb_kv_del(&p->kvdb, fal_kv_key[key]);
p->write_use_time = sys_millis() - start_time;
fal_inspection_crc[key] = 0;
return;
}
/**
* @brief fal执行状态
* @param {fal_execution_e} index
@ -469,115 +572,245 @@ void fal_execution_status_set(fal_execution_e index, BOOL status)
}
#if FAL_DBG_ENABLE
#include <stdlib.h>
#include "convert.h"
// 测试
static void fal_execution_inspection_test(void)
{
if (FALSE == fal_execution_kv_write(KEY_CALIBPARA_PARAM, (uint8_t *)&calib_param, (CALIBPARA_NUM * sizeof(calib_param_t))))
{
fal_execution_status.write.bits.M95_1 = 0;
}
else
{
fal_execution_status.write.bits.M95_1 = 1;
}
if (FALSE == fal_execution_kv_write(KEY_DEVICE, (uint8_t *)&udevice, sizeof(device_typedef)))
{
fal_execution_status.write.bits.M95_1 = 0;
}
else
{
fal_execution_status.write.bits.M95_1 = 1;
}
if (FALSE == fal_execution_kv_write(KEY_HART_DEVICE_VARIABLE_PARAM, (uint8_t *)hart_storage_variable, sizeof(hart_storage_variable_t)))
{
fal_execution_status.write.bits.M95_1 = 0;
}
else
{
fal_execution_status.write.bits.M95_1 = 1;
}
for (uint8_t i = 0; i < 10; i++)
{
get_timestamp((uDateTime_TypeDef *)&rt_data.save.real_time);
if (FALSE == fal_execution_kv_write(KEY_REAL_TIME_DATA, (uint8_t *)&rt_data.save, sizeof(rt_save_param_t)))
{
fal_execution_status.write.bits.FM24 = 0;
}
else
{
fal_execution_status.write.bits.FM24 = 1;
}
}
}
#endif
void fal_execution_inspection(uint16_t cycle)
/**
* @brief fal
*
* fal_write_sem fal
*
* @note
*/
void fal_execution_sem_update(void)
{
FLOW_SEM_RELEASE(&fal_write_sem);
}
// 检查存储的数据
static void fal_execution_read_and_check_data(fal_key_e key, uint16_t length)
{
uint8_t r_count = 3;
int8_t count = r_count;
fal_execution_t *p = fal_execution_get(key); // 将给定的键转换为相应的执行结构
if (p == NULL)
{
return;
}
uint8_t *data = (uint8_t *)osel_mem_alloc(length);
DBG_ASSERT(data != NULL __DBG_LINE);
while (count > 0)
{
if (TRUE == fal_execution_kv_read(key, data, length))
{
if (TRUE == fal_execution_data_storage_check(key, data, length))
{
break;
}
}
count--;
}
osel_mem_free(data);
if (count <= 0)
{
fal_inspection_crc[key] = 0;
}
}
/**
* @brief
*
*
*
* @param key
* @param data
* @param length
*/
void fal_execution_write_and_check_data(fal_key_e key, uint8_t *data, uint16_t length)
{
uint8_t w_count = 3;
int8_t count = w_count;
fal_execution_t *p = fal_execution_get(key); // 将给定的键转换为相应的执行结构
if (p == NULL)
{
return;
}
if (FALSE == fal_execution_data_storage_check(key, data, length))
{
// 读取数据
uint8_t *read_data = (uint8_t *)osel_mem_alloc(length);
DBG_ASSERT(read_data != NULL __DBG_LINE);
while (count > 0)
{
fal_execution_kv_write(key, data, length);
for (uint8_t i = 0; i < 10; i++)
{
__NOP();
}
fal_execution_kv_read(key, read_data, length);
// 比较数据
if (osel_memcmp(data, read_data, length) == 0)
{
break;
}
count--;
}
osel_mem_free(read_data);
if (count <= 0)
{
fal_inspection_crc[key] = 0;
p->write_error_num++;
}
else
{
if (p->write_error_num > 0)
{
p->write_error_num--;
}
}
}
}
/**
* @brief FAL信号检查
*
* mode模块专门使用
*
* @return
*/
void fal_execution_inspection_sem(void)
{
uint32_t crc = 0;
// 设备参数
crc = crc32_compute((uint8_t *)&udevice, sizeof(udevice_t) - sizeof(uint32_t));
if (crc != udevice.crc)
{
udevice.crc = crc;
fal_inspection_crc[KEY_DEVICE] = 0;
}
fal_execution_write_and_check_data(KEY_DEVICE, (uint8_t *)&udevice, sizeof(udevice_t));
// 非初始化数据
{
crc = crc32_compute((uint8_t *)&noinit_data, sizeof(noinit_data_t) - sizeof(uint32_t));
if (crc != noinit_data.crc)
{
noinit_data.crc = crc;
fal_inspection_crc[KEY_NOINIT_DATA] = 0;
}
fal_execution_write_and_check_data(KEY_NOINIT_DATA, (uint8_t *)&noinit_data, sizeof(noinit_data_t));
}
}
static void fal_execution_check_data_internal(uint16_t cycle)
{
static uint32_t check_data_tm = 0;
uint32_t tms = 60000 * 10;
if (sys_millis() - check_data_tm >= tms)
{
check_data_tm = sys_millis();
fal_execution_read_and_check_data(KEY_DEVICE, sizeof(udevice_t));
fal_execution_read_and_check_data(KEY_REAL_TIME_DATA, sizeof(rt_save_param_t));
}
}
static void fal_execution_inspection_internal(uint16_t cycle)
{
#if FAL_DBG_ENABLE
fal_execution_inspection_test();
#else
if (fal_execution_status.init.bits.M95_1 == 1) // M95_1初始化成功,才执行下面的操作
uint32_t crc = 0;
static uint32_t rtdata_tm = 0;
uint32_t tms = (uint32_t)(udevice.save_cycle * 1000);
if (sys_millis() - rtdata_tm >= tms)
{
// 校准参数
rtdata_tm = sys_millis();
// 写入数据
{
if (FALSE == fal_execution_data_storage_check(KEY_CALIBPARA_PARAM, (uint8_t *)&calib_param, (CALIBPARA_NUM * sizeof(calib_param_t))))
// 非初始化数据
{
if (FALSE == fal_execution_kv_write(KEY_CALIBPARA_PARAM, (uint8_t *)&calib_param, (CALIBPARA_NUM * sizeof(calib_param_t))))
crc = crc32_compute((uint8_t *)&noinit_data, sizeof(noinit_data_t) - sizeof(uint32_t));
if (crc != noinit_data.crc)
{
fal_execution_status.write.bits.M95_1 = 0;
noinit_data.crc = crc;
fal_inspection_crc[KEY_NOINIT_DATA] = 0;
}
else
fal_execution_write_and_check_data(KEY_NOINIT_DATA, (uint8_t *)&noinit_data, sizeof(noinit_data_t));
}
// 诊断结果
{
crc = crc32_compute((uint8_t *)&diag_result, sizeof(diag_result_t) - sizeof(uint32_t));
if (crc != diag_result.crc)
{
fal_execution_status.write.bits.M95_1 = 1;
diag_result.crc = crc;
fal_inspection_crc[KEY_DIAGNOSIS_RESULT] = 0;
}
return; // 退出
fal_execution_write_and_check_data(KEY_DIAGNOSIS_RESULT, (uint8_t *)&diag_result, sizeof(diag_result_t));
}
// 实时数据
{
crc = crc32_compute((uint8_t *)&rt_save, sizeof(rt_save_param_t) - sizeof(uint32_t));
if (crc != rt_save.crc)
{
rt_save.crc = crc;
fal_inspection_crc[KEY_REAL_TIME_DATA] = 0;
}
fal_execution_write_and_check_data(KEY_REAL_TIME_DATA, (uint8_t *)&rt_save, sizeof(rt_save_param_t));
// sys_soft_reset();
}
}
// 设备参数
{
if (FALSE == fal_execution_data_storage_check(KEY_DEVICE, (uint8_t *)&udevice, sizeof(device_typedef)))
{
if (FALSE == fal_execution_kv_write(KEY_DEVICE, (uint8_t *)&udevice, sizeof(device_typedef)))
{
fal_execution_status.write.bits.M95_1 = 0;
}
else
{
fal_execution_status.write.bits.M95_1 = 1;
}
return; // 退出
}
}
}
if (fal_execution_status.init.bits.FM24 == 1) // FM24初始化成功,才执行下面的操作
{
// 实时数据
static uint16_t rtdata_cnt = 0;
rtdata_cnt++;
uint32_t save_cycle = udevice.save_cycle * 1000; // ms
uint16_t save_cnt = save_cycle / cycle;
if (rtdata_cnt >= save_cnt)
{
rtdata_cnt = 0;
if (FALSE == fal_execution_data_storage_check(KEY_REAL_TIME_DATA, (uint8_t *)&rt_data.save, sizeof(rt_save_param_t)))
{
get_timestamp((uDateTime_TypeDef *)&rt_data.save.real_time);
if (FALSE == fal_execution_kv_write(KEY_REAL_TIME_DATA, (uint8_t *)&rt_data.save, sizeof(rt_save_param_t)))
{
fal_execution_status.write.bits.FM24 = 0;
}
else
{
fal_execution_status.write.bits.FM24 = 1;
}
return; // 退出
}
}
fal_execution_sem_update();
}
#endif
}
static uint8_t fal_execution_inspection(struct flow *fl)
{
FL_HEAD(fl);
for (;;)
{
FL_LOCK_WAIT_SEM_OR_TIMEOUT(fl, &fal_write_sem, FL_CLOCK_SEC * 1);
if (FL_SEM_IS_RELEASE(fl, &fal_write_sem))
{
FL_SEM_INIT(&fal_write_sem, 0);
fal_execution_inspection_sem();
}
else
{
if (mode_get()->ctrl.mode != TEST_CTRL_MODE)
{
fal_execution_inspection_internal(1000);
}
fal_execution_check_data_internal(1000);
}
}
FL_TAIL(fl);
}
/**
* @brief
*
*
*
* @note fal_execution_inspection fal_execution_fw
*/
void fal_execution_process(void)
{
fal_execution_inspection(&fal_execution_fw);
}

View File

@ -10,8 +10,10 @@
#include "bsp.h"
#include <stdlib.h>
#include "sys.h"
#include "hart.h"
#include "menus.h"
#define INVALID_BUTTON_TICKS 1000 // 无效按键时间 毫秒
#define INVALID_BUTTON_TICKS 200 // 无效按键时间 毫秒
/* 按钮 */
struct Button key_1;
@ -47,7 +49,7 @@ static BOOL allow_condition(void)
/**
* key的初始化在LCD板子上电之前
*/
if (!LCD_IS_POWER_ON() || (sys_millis() - key_start_ticks < INVALID_BUTTON_TICKS)) // 仿真的时候按键会有毛刺在xx秒之后按下有效
if (sys_millis() - key_start_ticks < INVALID_BUTTON_TICKS) // 仿真的时候按键会有毛刺在xx秒之后按下有效
{
key_imitate = 0; // 清除标志位
return FALSE;
@ -79,22 +81,22 @@ static uint8_t read_button_gpio(uint8_t button_id)
switch (button_id)
{
case KEY1:
case KEY_ESC:
return GPIO_READ(KEY1_GPIO_Port, KEY1_Pin);
case KEY2:
case KEY_LEFT:
return GPIO_READ(KEY2_GPIO_Port, KEY2_Pin);
case KEY3:
case KEY_UP:
return GPIO_READ(KEY3_GPIO_Port, KEY3_Pin);
case KEY4:
case KEY_DOWN:
return GPIO_READ(KEY4_GPIO_Port, KEY4_Pin);
case KEY5:
case KEY_RIGHT:
return GPIO_READ(KEY5_GPIO_Port, KEY5_Pin);
case KEY6:
case KEY_ENT:
return GPIO_READ(KEY6_GPIO_Port, KEY6_Pin);
case KEYAUTO:
case KEY_AUTO:
return GPIO_READ(KEY_AUTO_GPIO_Port, KEY_AUTO_Pin);
default:
return 0;
return ACTIVE_LEVEL_HIGH;
}
}
@ -110,8 +112,8 @@ static void key_2_5_press_down(void)
{
return;
}
// 检查标志,判断key2和key5同时按下
if (key_imitate == (KEY2 | KEY5))
// 检查标志,判断左右同时按下
if (key_imitate == (KEY_LEFT | KEY_RIGHT))
{
key_imitate = 0; // 清除标志位
#if LCD_DESIGN == FALSE
@ -130,15 +132,14 @@ static void key_2_5_press_down(void)
*/
static void key_1_press_down_handler(void *btn)
{
__NOP();
// 方向0: 按键1->KEY1, 方向180: 按键1->KEY6
struct Button *handle = (struct Button *)btn;
if (get_menus()->dir == 0)
{
menus_key_register(KEY1); // 注册为菜单功能键
menus_key_register(handle->button_id); // 注册为菜单功能键
}
else
{
menus_key_register(KEY6); // 注册为菜单功能键
menus_key_register(handle->button_id_reverse); // 注册为菜单功能键
}
}
@ -161,14 +162,23 @@ static void key_1_double_click_handler(void *btn)
*/
static void key_1_long_press_hold_handler(void *btn)
{
__NOP();
struct Button *handle = (struct Button *)btn;
long_done_flag = TRUE;
if (key_1.ticks >= (2000 / TICKS_INTERVAL) && key1_done_flag == FALSE)
if (key_1.ticks >= (1000 / TICKS_INTERVAL) && key1_done_flag == FALSE)
{
key1_done_flag = TRUE;
__NOP();
// 跳转到工作界面
menus_jump(MENUS_WORK, TRUE);
if (handle->button_id == KEY_ESC)
{
// 跳转到工作界面
menus_jump(MENUS_WORK, TRUE);
}
else
{
// 跳转到菜单界面
menus_jump(MENUS_MAIN, FALSE); // 跳转到主菜单界面
}
}
}
@ -193,21 +203,18 @@ static void key_1_up_handler(void *btn)
*/
static void key_2_press_down_handler(void *btn)
{
__NOP();
// 方向0: 按键2->KEY2, 方向180: 按键2->KEY5
struct Button *handle = (struct Button *)btn;
if (get_menus()->dir == 0)
{
key_imitate |= KEY2; // 设置按下标志(组合键)
key_imitate |= handle->button_id; // 设置按下标志(组合键)
key2_5_imitate_timers = EFFECTIVE_TIME / TICKS_INTERVAL; // 设置按下时间(组合键)
hart_cache_data_send(rnd_key_2); // 按键测试
menus_key_register(KEY2); // 注册为菜单功能键
menus_key_register(handle->button_id); // 注册为菜单功能键
}
else
{
key_imitate |= KEY5; // 设置按下标志(组合键)
key_imitate |= handle->button_id_reverse; // 设置按下标志(组合键)
key2_5_imitate_timers = EFFECTIVE_TIME / TICKS_INTERVAL; // 设置按下时间(组合键)
hart_cache_data_send(rnd_key_5); // 按键测试
menus_key_register(KEY5); // 注册为菜单功能键
menus_key_register(handle->button_id_reverse); // 注册为菜单功能键
}
// 组合键判断
key_2_5_press_down();
@ -254,17 +261,14 @@ static void key_2_up_handler(void *btn)
*/
static void key_3_press_down_handler(void *btn)
{
__NOP();
// 方向0: 按键3->KEY3, 方向180: 按键3->KEY4
struct Button *handle = (struct Button *)btn;
if (get_menus()->dir == 0)
{
hart_cache_data_send(rnd_key_3); // 按键测试
menus_key_register(KEY3); // 注册为菜单功能键
menus_key_register(handle->button_id); // 注册为菜单功能键
}
else
{
hart_cache_data_send(rnd_key_4); // 按键测试
menus_key_register(KEY4); // 注册为菜单功能键
menus_key_register(handle->button_id_reverse); // 注册为菜单功能键
}
}
@ -287,18 +291,17 @@ static void key_3_double_click_handler(void *btn)
*/
static void key_3_long_press_hold_handler(void *btn)
{
__NOP();
DISABLE_TIM(TIM7);
// 方向0: 按键3->KEY3, 方向180: 按键3->KEY4
struct Button *handle = (struct Button *)btn;
DISABLE_TIM(MODE_TIM);
if (get_menus()->dir == 0)
{
menus_key_register(KEY3 | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
menus_key_register(handle->button_id | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
}
else
{
menus_key_register(KEY4 | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
menus_key_register(handle->button_id_reverse | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
}
}
@ -306,7 +309,7 @@ static void key_3_long_press_hold_handler(void *btn)
static void key_3_up_handler(void *btn)
{
__NOP();
ENABLE_TIM(TIM7);
ENABLE_TIM(MODE_TIM);
menus_key_long_stop(); // 清除长按时间
}
@ -318,17 +321,14 @@ static void key_3_up_handler(void *btn)
*/
static void key_4_press_down_handler(void *btn)
{
__NOP();
// 方向0: 按键4->KEY4, 方向180: 按键4->KEY3
struct Button *handle = (struct Button *)btn;
if (get_menus()->dir == 0)
{
hart_cache_data_send(rnd_key_4); // 按键测试
menus_key_register(KEY4); // 注册为菜单功能键
menus_key_register(handle->button_id); // 注册为菜单功能键
}
else
{
hart_cache_data_send(rnd_key_3); // 按键测试
menus_key_register(KEY3); // 注册为菜单功能键
menus_key_register(handle->button_id_reverse); // 注册为菜单功能键
}
}
@ -351,18 +351,17 @@ static void key_4_double_click_handler(void *btn)
*/
static void key_4_long_press_hold_handler(void *btn)
{
__NOP();
DISABLE_TIM(TIM7);
// 方向0: 按键4->KEY4, 方向180: 按键4->KEY3
struct Button *handle = (struct Button *)btn;
DISABLE_TIM(MODE_TIM);
if (get_menus()->dir == 0)
{
menus_key_register(KEY4 | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
menus_key_register(handle->button_id | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
}
else
{
menus_key_register(KEY3 | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
menus_key_register(handle->button_id_reverse | WM_LONG); // 注册为菜单功能键
menus_key_long_start(); // 开始计时长按时间
}
}
@ -375,7 +374,7 @@ static void key_4_long_press_hold_handler(void *btn)
static void key_4_up_handler(void *btn)
{
__NOP();
ENABLE_TIM(TIM7);
ENABLE_TIM(MODE_TIM);
menus_key_long_stop(); // 清除长按时间
}
/**
@ -386,21 +385,19 @@ static void key_4_up_handler(void *btn)
*/
static void key_5_press_down_handler(void *btn)
{
__NOP();
// 方向0: 按键5->KEY5, 方向180: 按键5->KEY2
struct Button *handle = (struct Button *)btn;
if (get_menus()->dir == 0)
{
key_imitate |= KEY5; // 设置按下标志(组合键)
key_imitate |= handle->button_id; // 设置按下标志(组合键)
key2_5_imitate_timers = EFFECTIVE_TIME / TICKS_INTERVAL; // 设置按下时间(组合键)
hart_cache_data_send(rnd_key_5); // 按键测试
menus_key_register(KEY5); // 注册为菜单功能键
menus_key_register(handle->button_id); // 注册为菜单功能键
}
else
{
key_imitate |= KEY2; // 设置按下标志(组合键)
key_imitate |= handle->button_id_reverse; // 设置按下标志(组合键)
key2_5_imitate_timers = EFFECTIVE_TIME / TICKS_INTERVAL; // 设置按下时间(组合键)
hart_cache_data_send(rnd_key_2); // 按键测试
menus_key_register(KEY2); // 注册为菜单功能键
menus_key_register(handle->button_id_reverse); // 注册为菜单功能键
}
// 组合键判断
key_2_5_press_down();
@ -447,18 +444,16 @@ static void key_5_up_handler(void *btn)
*/
static void key_6_press_down_handler(void *btn)
{
__NOP();
button_id_e key = KEY0;
// 方向0: 按键6->KEY6, 方向180: 按键6->KEY1
struct Button *handle = (struct Button *)btn;
if (get_menus()->dir == 0)
{
key = KEY6;
menus_key_register(handle->button_id);
}
else
{
key = KEY1;
menus_key_register(handle->button_id_reverse);
}
menus_key_register(key);
}
/**
@ -480,14 +475,21 @@ static void key_6_double_click_handler(void *btn)
*/
static void key_6_long_press_hold_handler(void *btn)
{
__NOP();
struct Button *handle = (struct Button *)btn;
long_done_flag = TRUE;
if (key_6.ticks >= (2000 / TICKS_INTERVAL) && key6_done_flag == FALSE)
if (key_6.ticks >= (1000 / TICKS_INTERVAL) && key6_done_flag == FALSE)
{
key6_done_flag = TRUE;
__NOP();
// 跳转到菜单界面
menus_jump(MENUS_MAIN, FALSE); // 跳转到主菜单界面
if (handle->button_id == KEY_ESC)
{
// 跳转到工作界面
menus_jump(MENUS_WORK, TRUE);
}
else
{
// 跳转到菜单界面
menus_jump(MENUS_MAIN, FALSE); // 跳转到主菜单界面
}
}
}
@ -512,7 +514,14 @@ static void key_6_up_handler(void *btn)
*/
static void key_auto_press_down_handler(void *btn)
{
__NOP();
#if HART_HARDWARE_TEST_ENABLE == TRUE
rt_data.flag.bits.hart_send_test++;
if (rt_data.flag.bits.hart_send_test == 3)
{
rt_data.flag.bits.hart_send_test = 0;
}
#endif
}
/**
@ -523,11 +532,19 @@ static void key_auto_press_down_handler(void *btn)
*/
static void key_auto_long_press_hold_handler(void *btn)
{
if (key_auto.ticks >= (3000 / TICKS_INTERVAL) && auto_done_flag == FALSE)
if (key_auto.ticks >= (1000 / TICKS_INTERVAL) && auto_done_flag == FALSE)
{
auto_done_flag = TRUE;
// 跳转到自动整定界面
menus_jump(MENUS_SELFTUNE, TRUE);
mode_get()->interface_req.mode_adjust_stop();
if (mode_get()->interface_req.mode_is_adjusting() != TRUE) ///< 如果整定中不触发自整定跳转
{
mode_get()->interface_req.mode_adjust_start();
mode_get()->adjust_initiate = ADJUST_INITIATE_INTERNAL;
menu_exit(FALSE);
menu_exit(FALSE);
menus_jump(MENUS_SELFTUNE, TRUE);
}
}
}
@ -558,13 +575,41 @@ void key_init(void)
GPIO_SET_INPUT(KEY6_GPIO_Port, KEY6_Pin);
GPIO_SET_INPUT(KEY_AUTO_GPIO_Port, KEY_AUTO_Pin);
button_init(&key_1, read_button_gpio, ACTIVE_LEVEL_LOW, KEY1);
button_init(&key_2, read_button_gpio, ACTIVE_LEVEL_LOW, KEY2);
button_init(&key_3, read_button_gpio, ACTIVE_LEVEL_LOW, KEY3);
button_init(&key_4, read_button_gpio, ACTIVE_LEVEL_LOW, KEY4);
button_init(&key_5, read_button_gpio, ACTIVE_LEVEL_LOW, KEY5);
button_init(&key_6, read_button_gpio, ACTIVE_LEVEL_LOW, KEY6);
button_init(&key_auto, read_button_gpio, ACTIVE_LEVEL_LOW, KEYAUTO);
// 按键1->KEY1, 方向180: 按键1->KEY6
// 按键2->KEY2, 方向180: 按键2->KEY5
button_init(&key_1, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_ESC, KEY_ESC);
button_init(&key_2, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_LEFT, KEY_RIGHT);
button_init(&key_3, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_UP, KEY_DOWN);
button_init(&key_4, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_DOWN, KEY_UP);
button_init(&key_5, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_RIGHT, KEY_LEFT);
button_init(&key_6, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_ENT, KEY_ENT);
button_init(&key_auto, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_AUTO, KEY_AUTO);
// 硬件上GPS2000和GPS3000的按键是反的所以需要翻转一下
// switch (udevice.dev_model)
// {
// case POSITIONER_MODEL_GPS3000:
// button_init(&key_1, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_ENT, KEY_ENT);
// button_init(&key_2, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_RIGHT, KEY_LEFT);
// button_init(&key_3, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_DOWN, KEY_UP);
// button_init(&key_4, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_UP, KEY_DOWN);
// button_init(&key_5, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_LEFT, KEY_RIGHT);
// button_init(&key_6, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_ESC, KEY_ESC);
// button_init(&key_auto, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_AUTO, KEY_AUTO);
// break;
// case POSITIONER_MODEL_GPS2000:
// default:
// button_init(&key_1, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_ESC, KEY_ESC);
// button_init(&key_2, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_LEFT, KEY_RIGHT);
// button_init(&key_3, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_UP, KEY_DOWN);
// button_init(&key_4, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_DOWN, KEY_UP);
// button_init(&key_5, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_RIGHT, KEY_LEFT);
// button_init(&key_6, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_ENT, KEY_ENT);
// button_init(&key_auto, read_button_gpio, ACTIVE_LEVEL_LOW, KEY_AUTO, KEY_AUTO);
// break;
// }
// 添加按键1按下按钮的按下按钮回调函数
button_attach(&key_1, PRESS_DOWN, key_1_press_down_handler);
@ -627,7 +672,7 @@ void key_init(void)
// 添加按键auto按下按钮的抬起按钮回调函数
button_attach(&key_auto, PRESS_UP, key_auto_up_handler);
srand((unsigned)sys_millis());
board_srand(); // 随机数种子
rnd_key_1 = rand();
rnd_key_2 = rand();
rnd_key_3 = rand();
@ -708,7 +753,7 @@ uint64_t get_key_uuid(button_id_e k)
case KEY6:
uuid = rnd_key_6;
break;
case KEY_AUTO:
case KEYAUTO:
uuid = rnd_key_auto;
break;
default:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
#include "leds.h"
#include "board.h"
pdctrl_t pdctrl_data;
pdctrl_t pdctrl_data_out;
__IO static pdctrl_mode_e out_mode = PDCTRL_DAC;
__IO static BOOL pdctrl_run_flag = FALSE;
@ -50,6 +51,7 @@ static void pwmp_init(void)
{
pdctrl_data.last_out = 0xffff;
GPIO_SET_ALTERNATE(PDCTRL_PWM_GPIO_Port, PDCTRL_PWM_Pin);
ENABLE_TIM_ARR_RELOAD(PDCTRL_PWMP_TIM);
PWM_START(PDCTRL_PWMP_TIM, PDCTRL_PWMP_CHINNEL); // PWM通道使能
}
@ -65,7 +67,6 @@ void pdctrl_init(pdctrl_mode_e mode)
out_mode = mode;
pdctrl_data.pwm_wid = PWM_WID;
osel_memset((uint8_t *)&pdctrl_data, 0, sizeof(pdctrl_t));
VIP_H_EN_DISABLE();
dac_dinit();
pwm_dinit();
pwmp_dinit();
@ -186,8 +187,8 @@ uint16_t calculate_pwm_duty(uint32_t arr)
pdctrl_data.arr_us = 1000.0f / pdctrl_data.freq;
pdctrl_data.duty_percent = ((float32)wid * 100.0f) / pdctrl_data.arr_us;
uint16_t duty = arr * pdctrl_data.duty_percent / 100;
return duty;
pdctrl_data.duty = arr * pdctrl_data.duty_percent / 100;
return pdctrl_data.duty;
}
/**
@ -218,15 +219,8 @@ void pdctrl_pwm_set_arr(uint32_t arr)
{
arr = pdctrl_data.pwm_arr_default;
}
if (arr > pdctrl_data.pwm_arr_default)
{
// arr = pdctrl_data.pwm_arr_default;
pdctrl_data.pwm_arr_default = arr;
}
LL_TIM_SetAutoReload(PDCTRL_PWM_TIM, arr);
uint16_t duty = calculate_pwm_duty(arr);
#if PDCTRL_PWM_CHINNEL == LL_TIM_CHANNEL_CH4
PWM_SET_DUTY(PDCTRL_PWM_TIM, 4, duty);
#else
@ -259,7 +253,7 @@ void pdctrl_out(uint16_t out)
return;
}
if (pdctrl_data.last_out == out && (pdctrl_data.sysclk == (SystemCoreClock / 1000)))
if (pdctrl_data.last_out == out && (pdctrl_data.sysclk != (SystemCoreClock / 1000)))
{
return;
}

View File

@ -11,17 +11,31 @@
#include "main.h"
#include "bsp.h"
#include "tim.h"
#include "lcds.h"
#include "menu.h"
#include "leds.h"
#include "rtc_rx8010.h"
#include "eeprom_m95.h"
#include "eeprom_fm24.h"
#include "eeprom_lc02b.h"
#include "ntc_3950.h"
#include "leds.h"
#include "sht40.h"
#include "dac161p997.h"
#define APP_PRELOAD_AREA 0x10007FF0 ///< 预加载区域
#define VREF_VALUE 3000 ///< 参考电压mV
#define FONT_TYPE FONT_0816 ///< 字体类型
#define LCD_SPI SPI2
#define HART_UART1 USART1
#define HART_UART2 UART5
#define HART_UART1_BAUDRATE (1200U)
#define HART_UART2_BAUDRATE (115200U)
#define APP_PRELOAD_AREA 0x10007FF0 ///< 预加载区域
#define VREF_VALUE (CPU_VREF * 1000) ///< 参考电压mV
#define TASK_TIM TIM6 ///< 任务定时器
#define MODE_TIM TIM7 ///< 模式定时器
#define MODE_GATHE_TIM TIM17 ///< 模式采集定时器
#define HART_TIM TIM16 ///< HART定时器
#define HART_OUT_TIM TIM3 ///< HART输出定时器
#ifndef ADC_MAX
#define ADC_MAX 4095 //< ADC最大
@ -34,12 +48,12 @@
#define BLE_EN_DISABLE() GPIO_RESET(BLE_PWR_GPIO_Port, BLE_PWR_Pin) ///< 蓝牙禁用
#define BLE_IS_ENABLE() (GPIO_READ(BLE_PWR_GPIO_Port, BLE_PWR_Pin) == SET) ///< 蓝牙使能状态
#define LCD_DMA DMA1 ///< LCD DMA
#define LCD_DMA_TX_CHANNEL LL_DMA_CHANNEL_5 ///< LCD DMA发送通道
#define LCD_POWER_ON() GPIO_SET(LCD_PWR_GPIO_Port, LCD_PWR_Pin) ///< LCD电源使能
#define LCD_POWER_OFF() GPIO_RESET(LCD_PWR_GPIO_Port, LCD_PWR_Pin) ///< LCD电源禁用
#define LCD_IS_POWER_ON() (GPIO_READ(LCD_PWR_GPIO_Port, LCD_PWR_Pin) == SET) ///< LCD电源使能状态
#define LCD_DETECT() (0) ///< LCD检测高电平没有接入低电平接入
#define LCD_DMA DMA1 ///< LCD DMA
#define LCD_DMA_TX_CHANNEL LL_DMA_CHANNEL_5 ///< LCD DMA发送通道
#define LCD_POWER_ON() GPIO_SET(LCD_PWR_GPIO_Port, LCD_PWR_Pin) ///< LCD电源使能
#define LCD_POWER_OFF() GPIO_RESET(LCD_PWR_GPIO_Port, LCD_PWR_Pin) ///< LCD电源禁用
#define LCD_IS_POWER_ON() (GPIO_READ(LCD_PWR_GPIO_Port, LCD_PWR_Pin) == SET) ///< LCD电源使能状态
#define LCD_DETECT() (GPIO_READ(LCD_EXTCOMIN_GPIO_Port, LCD_EXTCOMIN_Pin) == SET) ///< LCD检测高电平没有接入低电平接入
#define BP_S_POWER_ON() GPIO_SET(BP_S_PWR_GPIO_Port, BP_S_PWR_Pin)
#define BP_S_POWER_OFF() GPIO_RESET(BP_S_PWR_GPIO_Port, BP_S_PWR_Pin)
@ -53,7 +67,7 @@
#define BP_B_POWER_OFF() GPIO_RESET(BP_B_PWR_GPIO_Port, BP_B_PWR_Pin)
#define BP_B_IS_POWER_ON() (GPIO_READ(BP_B_PWR_GPIO_Port, BP_B_PWR_Pin) == SET)
/// 禁用 I/P 电流输出 0-6.2V
////< 禁用 I/P 电流输出 0-6.2V
#define VIP_H_EN_DISABLE() \
do \
{ \
@ -61,7 +75,7 @@
GPIO_SET_ANALOG(IP_H_PWR_GPIO_Port, IP_H_PWR_Pin); \
} while (0)
/// 使能 I/P 电流输出 0-6.2V
////< 使能 I/P 电流输出 0-6.2V
#define VIP_H_EN_ENABLE() \
do \
{ \
@ -69,7 +83,7 @@
GPIO_SET(IP_H_PWR_GPIO_Port, IP_H_PWR_Pin); \
} while (0)
// PWM对外输出
///< PWM对外输出
#define PWM_CTRL_OUTPUT(out) PWM_SET_DUTY(TIM3, 3, out)
/* HART */
@ -84,15 +98,20 @@
/* HART */
/* SWO */
#define SWO1_OPEN() GPIO_SET(SWO1_GPIO_Port, SWO1_Pin) ///< SWO1 开
#define SWO1_CLOSE() GPIO_RESET(SWO1_GPIO_Port, SWO1_Pin) ///< SWO1 关
#define SWO2_OPEN() GPIO_SET(SWO2_GPIO_Port, SWO2_Pin) ///< SWO2 开
#define SWO2_CLOSE() GPIO_RESET(SWO2_GPIO_Port, SWO2_Pin) ///< SWO2 关
#define SWO1_OPEN() GPIO_SET(SWO1_GPIO_Port, SWO1_Pin) ///< SWO1 开
#define SWO1_CLOSE() GPIO_RESET(SWO1_GPIO_Port, SWO1_Pin) ///< SWO1 关
#define SWO1_TOGGLE() GPIO_TOGGLE(SWO1_GPIO_Port, SWO1_Pin) ///< SWO1 翻转
#define SWO1_IS_OPEN() (GPIO_READ(SWO1_GPIO_Port, SWO1_Pin) == SET)
#define SWO2_OPEN() GPIO_SET(SWO2_GPIO_Port, SWO2_Pin) ///< SWO2 开
#define SWO2_CLOSE() GPIO_RESET(SWO2_GPIO_Port, SWO2_Pin) ///< SWO2 关
#define SWO2_TOGGLE() GPIO_TOGGLE(SWO2_GPIO_Port, SWO2_Pin) ///< SWO2 翻转
#define SWO2_IS_OPEN() (GPIO_READ(SWO2_GPIO_Port, SWO2_Pin) == SET)
typedef enum
{
FILTER_AVERAGE = 1,
FILTER_MEDIAN,
FILTER_MEDIAN_AVERAGE,
} filter_e;
typedef enum
@ -104,42 +123,53 @@ typedef enum
typedef enum
{
// 不需要跳转到bootload
///< 不需要跳转到bootload
APP_PRELOAD_BOOTLOAD_JUMP_NONE = 0,
// 更新完成等待用户通知跳转到bootload
APP_PRELOAD_BOOTLOAD_JUMP_WAIT = 1,
// 更新完成立即跳转到bootload
APP_PRELOAD_BOOTLOAD_JUMP_IMMEDIATELY,
///< 更新完成等待用户通知跳转到bootload
APP_PRELOAD_BOOTLOAD_JUMP_WAIT = 0xd501,
///< 更新完成立即跳转到bootload
APP_PRELOAD_BOOTLOAD_JUMP_IMMEDIATELY = 0xc802,
} app_preload_bootload_jump_e; ///< 预加载BOOTLOAD跳转标志
extern const uint32_t NTC_100K_B3950_List[];
extern __IO uint8_t app_preload_flag; ///< 预加载标志位
extern __IO uint8_t app_preload_language_flag; ///< 语言标志位
extern __IO uint8_t app_preload_bootload_flag; ///< 触发BOOTLOAD启动标志(在用户代码中接受代码文件)
extern __IO uint8_t app_preload_bootload_jump_flag; ///< 触发BOOTLOAD跳转标志(在用户代码中接受代码文件)
extern __IO uint32_t app_preload_cupid_encrypt; ///< CPU加密值
typedef struct
{
uint16_t app_preload_flag; ///< 预加载标志
uint8_t app_preload_language_flag; ///< 语言标志
uint32_t app_preload_cupid_encrypt; ///< 加密后的CPUID
} board_data_t;
extern void board_init(void); ///< 板卡初始化
extern void board_dinit(void); ///< 板卡反初始化
extern void board_work_stop_or_run(void); ///< 板卡工作停止或运行
extern void board_cache_reset(void); ///< 板卡缓存复位
extern uint16_t board_cache_get(board_cache_e index); ///< 板卡缓存获取
extern void driver_init(void); ///< 功耗引脚初始化
extern void driver_dinit(void); ///< 功耗引脚反初始化
extern void lcd_init(void); ///< LCD初始化
extern void lcd_dinit(void); ///< LCD反初始化
extern void system_clock_config_set_flag(BOOL flag); ///< 设置系统时钟配置标志
extern void system_clock_config_low(void); ///< 系统时钟配置低频
extern void system_clock_config_hight(void); ///< 系统时钟配置高频
extern void gui_flush(void); ///< LCD刷新
extern void gui_flush_Clear(void); ///< LCD刷新并清屏
extern void gui_clr(void); ///< 清屏
extern void gui_full(void); ///< 全屏黑色
extern void gui_open(void); ///< 打开GUI
extern void gui_close(void); ///< 关闭GUI
extern void gui_set_scandir(uint8_t dir); ///< 设置扫描方向
extern void gui_set_clear_flag(void); ///< 设置清屏标志
extern BOOL gui_get_clear_flag(void); ///< 获取清屏标志
extern board_data_t board_data; ///< 板卡数据
extern lcd_t *lcd; ///< LCD句柄
extern __IO uint16_t dbg_assert_line;
extern __IO uint16_t app_preload_bootload_flag; ///< 触发BOOTLOAD启动标志(在用户代码中接受代码文件)
extern __IO uint16_t app_preload_bootload_jump_flag; ///< 触发BOOTLOAD跳转标志(在用户代码中接受代码文件)
extern void board_init(void); ///< 板卡初始化
extern void board_dinit(void); ///< 板卡反初始化
extern void board_srand(void); ///< 板卡随机数种子
extern void board_work_stop_or_run(void); ///< 板卡工作停止或运行
extern uint16_t board_cache_get(board_cache_e index); ///< 板卡缓存获取
extern void driver_init(void); ///< 功耗引脚初始化
extern void driver_dinit(void); ///< 功耗引脚反初始化
extern BOOL is_lcd_ext_board(void); ///< 是否接入了LCD扩展板
extern void lcd_init(void); ///< LCD初始化
extern void lcd_dinit(void); ///< LCD反初始化
extern void system_clock_config_low(void); ///< 系统时钟配置低频
extern void system_clock_config_high(void); ///< 系统时钟配置高频
extern BOOL gui_can_work(void); ///< GUI是否可以工作
extern BOOL gui_is_idle(void); ///< GUI是否空闲
extern void gui_flush(void); ///< LCD刷新
extern void gui_flush_Clear(void); ///< LCD刷新并清屏
extern void gui_clr(void); ///< 清屏
extern void gui_full(void); ///< 全屏黑色
extern void gui_open(void); ///< 打开GUI
extern void gui_close(void); ///< 关闭GUI
extern void gui_set_scandir(uint8_t dir); ///< 设置扫描方向
extern void gui_set_clear_flag(void); ///< 设置清屏标志
extern BOOL gui_get_clear_flag(void); ///< 获取清屏标志
extern BOOL flash_read(uint32_t address, uint8_t *data, uint16_t length); ///< 读取Flash
extern BOOL flash_write(uint32_t address, const uint8_t *data, uint16_t length); ///< 写入Flash
extern BOOL flash_erase_page(uint32_t page); ///< 擦除Flash页
extern uint16_t get_dac(float32 output); ///< 根据目标行程计算DAC输出理论值
extern void pwm_output_position(float32 position_per); ///< PWM输出阀位百分比
@ -147,36 +177,50 @@ extern void calib_loop(void);
extern void calib_kpa(void); ///< 校准压力
extern void calib_pwm_out(void); ///< 校准PWM输出
extern void calib_parapos_perent(void); ///< 校准阀门位置参数
extern uint16_t get_actual_travel_adc_average(void); ///< 获取当前实际行程ADC值
extern uint16_t get_actual_travel_adc(void); ///< 获取当前实际行程ADC值
extern float32 get_actual_travel(filter_e filter); ///< 获取当前实际行程
extern float32 get_actual_travel_2(filter_e filter); ///< 获取当前实际行程
extern float32 get_current(void); ///< 获取当前回路电流
extern float32 get_current_deal(float32 current); ///< 获取当前回路电流
extern float32 get_current_by_resistance(void); ///< 通过电阻测算获取当前回路电流
extern float32 get_current(filter_e filter); ///< 获取当前回路电流
extern float32 get_current_deal(float32 current); ///< 电流数据处理
extern float32 get_temperature(void); ///< 获取当前温度值
extern float32 get_pressure(pressure_index_e id); ///< 获取当前压力
extern float32 get_pressure(pressure_type_e id); ///< 获取当前压力
extern float32 get_dead_zone(void); ///< 获取死区
extern float32 get_flow(void); ///< 获取当前流量
extern void get_timestamp(uDateTime_TypeDef *time); ///< 获取时间戳
extern void get_real_time(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec); ///< 获取实时时间
extern void set_real_time(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
extern BOOL get_app_preload_bootload_flag(void); ///< 获取预加载BOOTLOAD标志位
extern app_preload_bootload_jump_e get_app_preload_bootload_jump_flag(void); ///< 获取预加载BOOTLOAD跳转标志
extern void set_pwm_calib_current(void); ///< 设置输出PWM校准电流
extern void set_loop_4ma(void); ///< 设置回路电流4mA
extern void set_loop_20ma(void); ///< 设置回路电流20mA
extern void set_200kpa(void); ///< 设置200kpa
extern void set_400kpa(void); ///< 设置400kpa
extern void set_output_4ma_pwm(uint16_t value); ///< 设置输出4mA时的PWM值
extern void set_output_20ma_pwm(uint16_t value); ///< 设置输出20mA时的PWM值
extern void set_app_preload_language_flag(uint8_t language); ///< 设置预加载语言标志位
extern void set_app_preload_bootload_flag(uint8_t flag); ///< 设置预加载BOOTLOAD标志位
extern void set_app_preload_bootload_jump_flag(app_preload_bootload_jump_e flag); ///< 设置预加载BOOTLOAD标志位
extern BOOL update_real_time(date_time_t *real_time); ///< 更新实时时间
extern BOOL get_timestamp(date_time_t *time); ///< 获取时间戳
extern BOOL get_real_time(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec); ///< 获取实时时间
extern float32 get_cpu_temperature(void); ///< 获取CPU温度
extern float32 get_cpu_volt(void); ///< 获取CPU电压
extern float32 get_board_current(void); ///< 获取板卡电流
extern uint32_t get_seed(void); ///< 获取随机种子
extern BOOL uart1_get_idel_status(void); ///< 获取UART1空闲状态
extern uint32_t rt_data_time_timestamp(void); ///< 获取实时时间戳
extern BOOL rtc_get_datetime(rtc_date_t *const date, rtc_time_t *const time); ///< 获取RTC时间
extern BOOL set_real_time(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
extern uint8_t get_language(void); ///< 获取语言
extern uint8_t get_work_page_index(void); ///< 获取工作菜单索引
extern uint16_t get_app_preload_bootload_flag(void); ///< 获取预加载BOOTLOAD标志位
extern uint8_t get_app_preload_language_flag(void); ///< 获取预加载语言标志位
extern app_preload_bootload_jump_e get_app_preload_bootload_jump_flag(void); ///< 获取预加载BOOTLOAD跳转标志
extern void set_loop_4ma(void); ///< 设置回路电流4mA
extern void set_loop_20ma(void); ///< 设置回路电流20mA
extern void set_pressure_min(uint8_t unit, float32 set_value, pressure_type_e index); ///< 设置最小压力
extern void set_pressure_max(uint8_t unit, float32 set_value, pressure_type_e index); ///< 设置最大压力
extern void set_output_4ma_pwm(uint16_t value); ///< 设置输出4mA时的PWM值
extern void set_output_20ma_pwm(uint16_t value); ///< 设置输出20mA时的PWM值
extern void set_app_preload_language_flag(uint8_t language); ///< 设置预加载语言标志位
extern void set_language(uint8_t language); ///< 设置语言
extern void set_work_page_index(uint8_t index); ///< 设置工作菜单索引
extern void set_app_preload_bootload_flag(uint16_t flag); ///< 设置预加载BOOTLOAD标志位
extern void set_app_preload_bootload_jump_flag(app_preload_bootload_jump_e flag); ///< 设置预加载BOOTLOAD标志位
extern void uart1_set_idel_handle_1_sec(void); ///< 设置UART1空闲处理,1秒执行一次
extern void uart1_set_idel_status(BOOL idel); ///< 设置UART1空闲状态
/************************************** 通过电阻测算,只在测试程序中使用 **************************************/
extern float32 actual_adc_convert_percent(uint16_t adc); ///< 实际行程ADC值转换为百分比
extern float32 loop_current_convert(uint16_t adc); ///< 回路电流检测转换
extern float32 ip_dac2current(uint16_t dac); ///< DAC:IP输出电流值转换
extern float32 ip2current(void); ///< IP输出电流值转换
extern float32 pressure_adc2kpa(uint16_t adc); ///< 压力ADC值转换
extern void pwm_duty2current(float32 cur_ma); ///< PWM输出电流值转换
#endif // __BOARD_H__
#endif ///< __BOARD_H__

View File

@ -0,0 +1,81 @@
#ifndef __DAC161P997_H__
#define __DAC161P997_H__
#include "main.h"
#include "gpios.h"
#define DAC161P997_IO_PORT (DAC161P997_GPIO_Port)
#define DAC161P997_IO_PIN (DAC161P997_Pin)
#define DAC161P997_CURRENT_SLOPE 2730.625f // adc = (current / 24) * 0xffff
// Symbol Periods
#define DUTY_CYCLE_100 (1000U) // (CPU_CLK / BAUD_RATE)
#define DUTY_CYCLE_75 (DUTY_CYCLE_100 * 0.75f)
#define DUTY_CYCLE_50 (DUTY_CYCLE_100 * 0.50f)
#define DUTY_CYCLE_25 (DUTY_CYCLE_100 * 0.25f)
/************************************************************
* TI DAC161P997 REGISTER SET ADDRESSES
************************************************************/
#define DAC161P997_LCK_REG (0x0000)
#define DAC161P997_CONFIG1_REG (0x0100)
#define DAC161P997_CONFIG2_REG (0x0200)
#define DAC161P997_CONFIG3_REG (0x0300)
#define DAC161P997_ERR_LOW_REG (0x0400)
#define DAC161P997_ERR_HIGH_REG (0x0500)
// TI DAC161P997 Register Bits
#define DAC161P997_LCK_REG_LOCK (0x00AA) // any value other than 0x95
#define DAC161P997_LCK_REG_UNLOCK (0x0095)
#define DAC161P997_CONFIG1_REG_RST (0x0001)
#define DAC161P997_CONFIG1_REG_NOP (0 * 0x08u)
#define DAC161P997_CONFIG1_REG_SET_ERR (1 * 0x08u)
#define DAC161P997_CONFIG1_REG_CLEAR_ERR (2 * 0x08u)
#define DAC161P997_CONFIG1_REG_NOP3 (3 * 0x08u)
#define DAC161P997_CONFIG2_REG_LOOP (0x0001)
#define DAC161P997_CONFIG2_REG_CHANNEL (0x0002)
#define DAC161P997_CONFIG2_REG_PARITY (0x0004)
#define DAC161P997_CONFIG2_REG_FRAME (0x0008)
#define DAC161P997_CONFIG2_REG_ACK_EN (0x0010)
#define DAC161P997_CONFIG3_REG_RX_ERR_CNT_16 (0x000F)
#define DAC161P997_CONFIG3_REG_RX_ERR_CNT_8 (0x0007)
#define DAC161P997_CONFIG3_REG_RX_ERR_CNT_1 (0x0000)
// Tags
#define DACCODE_WRITE (0x00)
#define CONFIG_WRITE (0x01)
// Valid Symbols
#define ZERO_SYM (0x00)
#define ONE_SYM (0x01)
#define IDLE_SYM (0x02)
#define STATIC_LOW_SYM (0x03)
// DAC Codes for different currents
#define DACCODE_0mA (0x0000)
#define DACCODE_4mA (0x2AAA)
#define DACCODE_8mA (0x5555)
#define DACCODE_12mA (0x7FFF)
#define DACCODE_16mA (0xAAAA)
#define DACCODE_20mA (0xD555)
#define DACCODE_24mA (0xFFFF)
// cycles
// #define QUARTER_CYCLES (625)
// #define HALF_CYCLES (1250)
// #define THREE_CYCLES (1875)
// #define FULL_CYCLES (2500)
typedef struct
{
gpio_t *io;
} dac161p997_t;
void dac161p997_output_0(void);
void dac161p997_output_1(void);
void dac161p997_output_d(void);
void dac161p997_output_symbol(uint8_t sym);
void dac161p997_swif_write_reg(uint16_t data, uint8_t tag);
extern void dac161p997_output_current(float32 current);
extern void dac161p997_init(void);
#endif

View File

@ -9,7 +9,7 @@
#ifndef __EEPROM_FM24_H__
#define __EEPROM_FM24_H__
#include "main.h"
#include "spis.h"
//========在此设定芯片地址=============
#define W_ADD_COM 0xa0 // 写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
@ -47,13 +47,44 @@
#define FM24_PAGE_SIZE 256
#define FM24_SIZE (16384)
#elif e2prom == 256
#define FM24_PAGE_SIZE 512
#define FM24_SIZE (32768) // 32K
#define FM24_PAGE_SIZE 256
#define FM24_SIZE (32768) // 32K 128页
#elif e2prom == 512
#define FM24_PAGE_SIZE 512
#define FM24_SIZE (65536)
#endif
#define FM24_CMD_RDSR 0x05 /*!< Read Status Register instruction */
#define FM24_CMD_WRSR 0x01 /*!< Write Status Register instruction */
#define FM24_CMD_WREN 0x06 /*!< Write enable instruction */
#define FM24_CMD_WRDI 0x04 /*!< Write disable instruction */
#define FM24_CMD_READ 0x03 /*!< Read from Memory instruction */
#define FM24_CMD_WRITE 0x02 /*!< Write to Memory instruction */
#define FM24_DUMMY_BYTE 0x00 ///< 无用数据
typedef union
{
uint8_t data;
struct
{
uint8_t reserve1 : 1;
uint8_t wel : 1; ///< Write enable latch
uint8_t bp0 : 1; ///< Block protect 0
uint8_t bp1 : 1; ///< Block protect 1
uint8_t reserve2 : 3;
uint8_t wpen : 1; ///< Write protect enable
} bits;
} fm24_write_protection_u;
typedef struct
{
fm24_write_protection_u write_protection;
spi_t *spi;
} fm24_t;
/**
* @brief Initializes the FM24 EEPROM module.
*/
@ -64,6 +95,12 @@ extern void eeprom_fm24_init(void);
*/
extern void eeprom_fm24_dinit(void);
/**
* @brief Gets the fm24_t handle of the FM24 EEPROM module.
* @return The fm24_t handle of the FM24 EEPROM module.
*/
extern fm24_t *eeprom_fm24_get(void);
/**
* @brief Enables the FM24 EEPROM module.
*/
@ -92,6 +129,17 @@ extern BOOL eeprom_fm24_read(uint32_t read_addr, uint8_t *data, uint16_t length)
*/
extern BOOL eeprom_fm24_write(uint32_t write_addr, uint8_t *data, uint16_t length);
/**
* @brief Closes the write protection of the FM24 EEPROM module.
*/
extern void eeprom_fm24_write_protection_close(void);
/**
* @brief Gets the write protection state of the FM24 EEPROM module.
* @return TRUE if the FM24 EEPROM module is not write-protected, FALSE otherwise.
*/
extern BOOL eeprom_fm24_write_protection_state(void);
/**
* @brief Performs a test on the FM24 EEPROM module.
*/

View File

@ -10,7 +10,7 @@
#include "main.h"
#include "entity.h"
#define PRRESSURE_CALIBRATION_ADDRESS 0x00 ///< 压力校准地址
/**
* @brief Initializes the LC02B EEPROM module.
@ -44,4 +44,4 @@ void eeprom_lc02b_read(uint32_t read_addr, uint8_t *data, uint16_t length);
* @brief Performs a test on the LC02B EEPROM module.
*/
void eeprom_lc02b_test(void);
#endif // !__EEPROM_LC02B_H
#endif ///< !__EEPROM_LC02B_H

View File

@ -9,7 +9,7 @@
#ifndef __EEPROM_M95_H
#define __EEPROM_M95_H
#include "main.h"
#include "entity.h"
#include "spis.h"
#define _M95010_ 128
#define _M95020_ 256
@ -23,8 +23,8 @@
#define _M95128_ 16384
#define _M95256_ 32768
#define _M95512_ 65536 // 65K
#define _M95M02_ 262144 // 256K
#define _M95512_ 65536 ///< 65K
#define _M95M02_ 262144 ///< 256K
#define _M95_SIZE _M95512_
@ -37,22 +37,22 @@
#define M95_CMD_READ 0x03 /*!< Read from Memory instruction */
#define M95_CMD_WRITE 0x02 /*!< Write to Memory instruction */
// Instruction available only for the M95_2-D device.
///< Instruction available only for the M95_2-D device.
#define M95_CMD_RDID 0x83 /*!< Read identification page*/
#define M95_CMD_WRID 0x82 /*!< Write identification page*/
#define M95_CMD_RDLS 0x83 /*!< Reads the Identification page lock status*/
#define M95_CMD_LID 0x82 /*!< Locks the Identification page in read-only mode*/
#define M95_DUMMY_BYTE 0xA5 // 虚拟字节
#define M95_DUMMY_BYTE 0xA5 ///< 虚拟字节
// 定义存储器大小(Bytes)
///< 定义存储器大小(Bytes)
typedef enum
{
M95_PAGE_SIZE_16 = 16, // _M95010_ 、_M95020_ 、_M95040_
M95_PAGE_SIZE_32 = 32, // _M95080_ 、_M95160_、_M95320_、_M95640_
M95_PAGE_SIZE_64 = 64, // _M95128_、_M95256_
M95_PAGE_SIZE_128 = 128, // _M95512_
M95_PAGE_SIZE_256 = 256, // _M95M02_
M95_PAGE_SIZE_16 = 16, ///< _M95010_ 、_M95020_ 、_M95040_
M95_PAGE_SIZE_32 = 32, ///< _M95080_ 、_M95160_、_M95320_、_M95640_
M95_PAGE_SIZE_64 = 64, ///< _M95128_、_M95256_
M95_PAGE_SIZE_128 = 128, ///< _M95512_
M95_PAGE_SIZE_256 = 256, ///< _M95M02_
} m95_page_size_e;
typedef enum
@ -60,21 +60,30 @@ typedef enum
M95_1,
M95_2,
M95_MAX,
} m95_number_e; // 板卡上2块m95芯片定义
} m95_number_e; ///< 板卡上2块m95芯片定义
typedef union
{
uint8_t data;
struct
{
uint8_t wip : 1; ///< Write in progress
uint8_t wel : 1; ///< Write enable latch
uint8_t bp0 : 1; ///< Block protect 0
uint8_t bp1 : 1; ///< Block protect 1
uint8_t reserve : 3;
uint8_t srwd : 1; ///< Status register write protect
} bits;
} m95_write_protection_u;
typedef struct
{
m95_number_e num;
uint32_t page_size;
uint32_t total_size;
m95_write_protection_u write_protection;
spi_t *spi;
uint8_t address_bytes; // M95M02 地址大小3个字节其余M95型号芯片为2个字节
uint8_t *rxbuf;
uint8_t *txbuf;
} m95_number_t;
extern __IO m95_number_e current_m95_number; ///< 当前使用的m95芯片编号
extern m95_number_t eeprom_m95s[M95_MAX]; ///< m95芯片数组
extern m95_number_t eeprom_m95s[M95_MAX]; ///< m95芯片数组
/**
* @brief Initializes the M95 EEPROM module.
@ -100,6 +109,20 @@ extern void eeprom_m95_enable(void);
*/
extern void eeprom_m95_disable(void);
/**
* @brief Closes the write protection of the M95 EEPROM module.
*
* @param num The M95 EEPROM number.
*/
extern void eeprom_m95_write_protection_close(m95_number_e num);
/**
* @brief write protection state of the M95 EEPROM module.
*
* @param num The M95 EEPROM number.
*/
extern BOOL eeprom_m95_write_protection_state(m95_number_e num);
/**
* @brief Reads data from the M95 EEPROM module.
*
@ -108,7 +131,7 @@ extern void eeprom_m95_disable(void);
* @param data The buffer to store the read data.
* @param length The number of bytes to read.
*/
extern void eeprom_m95_read(m95_number_e num, uint32_t read_addr, uint8_t *data, uint16_t length);
extern BOOL eeprom_m95_read(m95_number_e num, uint32_t read_addr, uint8_t *data, uint16_t length);
/**
* @brief Writes data to the M95 EEPROM module.
@ -118,7 +141,7 @@ extern void eeprom_m95_read(m95_number_e num, uint32_t read_addr, uint8_t *data,
* @param data The data to write.
* @param length The number of bytes to write.
*/
extern void eeprom_m95_write(m95_number_e num, uint32_t write_addr, uint8_t *data, uint16_t length);
extern BOOL eeprom_m95_write(m95_number_e num, uint32_t write_addr, uint8_t *data, uint16_t length);
/**
* @brief Performs a test on the M95 EEPROM module.
@ -126,4 +149,9 @@ extern void eeprom_m95_write(m95_number_e num, uint32_t write_addr, uint8_t *dat
* @param num The M95 EEPROM number.
*/
extern void eeprom_m95_test(m95_number_e num);
#endif // __EEPROM_M95_H
extern BOOL eeprom_m95_1_read(uint32_t addr, uint8_t *buf, uint16_t size);
extern BOOL eeprom_m95_1_write(uint32_t addr, uint8_t *buf, uint16_t size);
extern BOOL eeprom_m95_2_read(uint32_t addr, uint8_t *buf, uint16_t size);
extern BOOL eeprom_m95_2_write(uint32_t addr, uint8_t *buf, uint16_t size);
#endif ///< __EEPROM_M95_H

View File

@ -4,11 +4,11 @@
#include "lib.h"
typedef enum
{
LEDS_1_RED,
LEDS_1_GREEN,
LEDS_1_YELLOW,
LEDS_2_ORANGE,
LEDS_2_BLUE,
LEDS_RED,
LEDS_GREEN,
LEDS_YELLOW,
LEDS_ORANGE,
LEDS_BLUE,
LEDS_MAX,
} leds_e;
@ -52,4 +52,4 @@ extern void leds_off_all(void);
* @param led The LED to toggle.
*/
extern void leds_toggle(leds_e led);
#endif // !__LEDS_H__
#endif ///< !__LEDS_H__

View File

@ -12,4 +12,4 @@
extern float32_u ntc_get_temp(uint16_t adc); ///< 获取温度值
#endif // __NTC_B3950_H__
#endif ///< __NTC_B3950_H__

View File

@ -40,17 +40,17 @@ typedef enum
THUR = BIT4,
FRI = BIT5,
SAT = BIT6
} rtc_week_e; // 星期码
} rtc_week_e; ///< 星期码
typedef struct
{
uint8_t year; // 7 bit - 1 63
uint8_t month; // 4 bit
uint8_t day; // 5 bit
uint8_t weekday; // rtc_week_e
uint8_t hour; // 5 bit
uint8_t minute; // 6 bit
uint8_t second; // 6 bit
uint8_t year; ///< 7 bit - 1 63
uint8_t month; ///< 4 bit
uint8_t day; ///< 5 bit
uint8_t weekday; ///< rtc_week_e
uint8_t hour; ///< 5 bit
uint8_t minute; ///< 6 bit
uint8_t second; ///< 6 bit
} rtc_date;
/**
@ -79,6 +79,12 @@ extern BOOL rtc_get_clock_time(uint8_t *read_buf);
*/
extern BOOL rtc_set_clock_time(rtc_date *data);
/**
* @brief Retrieves the current alarm time from the RTC module.
* @param read_buf Pointer to the buffer to store the alarm time.
* @return TRUE if the alarm time is successfully retrieved, FALSE otherwise.
*/
extern uint32_t rtc_timestamp(void);
/**
* @brief Converts the weekday value to a human-readable format.
* @param weekday Pointer to the weekday value to be converted.
@ -90,4 +96,4 @@ extern void rtc_weekday_convert(uint8_t *weekday);
* @param weekday Pointer to the weekday value to be converted.
*/
extern void rtc_weekday_rconvert(uint8_t *weekday);
#endif // !__RTC_RX8010_H__
#endif ///< !__RTC_RX8010_H__

Some files were not shown because too many files have changed in this diff Show More