Compare commits

...

2 Commits

Author SHA1 Message Date
许晟昊 005cc792a8 调整驱动 2024-12-31 17:04:20 +08:00
许晟昊 e4c3e59332 ad转换完成 2024-12-16 22:49:09 +08:00
960 changed files with 250955 additions and 2293 deletions

View File

@ -1,14 +1,14 @@
[PreviousLibFiles] [PreviousLibFiles]
LibFiles=Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_tim.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_gpio.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_tim.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_dma.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_rcc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_utils.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_exti.c;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_tim.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f407xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.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_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_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\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_adc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_tim.h;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_gpio.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_adc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_dma.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_rcc.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_utils.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_exti.c;Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_tim.c;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_gpio.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_system.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_rcc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_adc.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dma.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_bus.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_cortex.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_utils.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_exti.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_pwr.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_dmamux.h;Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_ll_tim.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f407xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h;Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.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_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_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;
[PreviousUsedKeilFiles] [PreviousUsedKeilFiles]
SourceFiles=..\Src\main.c;..\Src\gpio.c;..\Src\tim.c;..\Src\stm32f4xx_it.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_utils.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_exti.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_tim.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_utils.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_exti.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;;; SourceFiles=..\Src\main.c;..\Src\gpio.c;..\Src\adc.c;..\Src\dma.c;..\Src\tim.c;..\Src\stm32f4xx_it.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_adc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_utils.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_tim.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_gpio.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_adc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_dma.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_rcc.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_utils.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_exti.c;..\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_ll_tim.c;..\Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c;..\\Src\system_stm32f4xx.c;;;
HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc; HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc;
CDefines=USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;EXTERNAL_CLOCK_VALUE:12288000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:1;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;STM32F407xx;USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;EXTERNAL_CLOCK_VALUE:12288000;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:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;EXTERNAL_CLOCK_VALUE:12288000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:1;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;STM32F407xx;USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;EXTERNAL_CLOCK_VALUE:12288000;HSI_VALUE:16000000;LSI_VALUE:32000;VDD_VALUE:3300;PREFETCH_ENABLE:1;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;
[PreviousGenFiles] [PreviousGenFiles]
HeaderPath=..\Inc HeaderPath=..\Inc
HeaderFiles=gpio.h;tim.h;stm32f4xx_it.h;stm32_assert.h;main.h; HeaderFiles=gpio.h;adc.h;dma.h;tim.h;stm32f4xx_it.h;stm32_assert.h;main.h;
SourcePath=..\Src SourcePath=..\Src
SourceFiles=gpio.c;tim.c;stm32f4xx_it.c;main.c; SourceFiles=gpio.c;adc.c;dma.c;tim.c;stm32f4xx_it.c;main.c;

View File

@ -11,7 +11,8 @@
"intelliSenseMode": "windows-gcc-x64", "intelliSenseMode": "windows-gcc-x64",
"compilerArgs": [ "compilerArgs": [
"" ""
] ],
"configurationProvider": "cl.eide"
} }
], ],
"version": 4 "version": 4

2
.vscode/launch.json vendored
View File

@ -1,6 +1,8 @@
{ {
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "C/C++ Runner: Debug Session", "name": "C/C++ Runner: Debug Session",
"type": "cppdbg", "type": "cppdbg",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,922 @@
/**
******************************************************************************
* @file stm32f4xx_ll_adc.c
* @author MCD Application Team
* @brief ADC 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 "stm32f4xx_ll_adc.h"
#include "stm32f4xx_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "stm32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup STM32F4xx_LL_Driver
* @{
*/
#if defined (ADC1) || defined (ADC2) || defined (ADC3)
/** @addtogroup ADC_LL ADC
* @{
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/** @addtogroup ADC_LL_Private_Macros
* @{
*/
/* Check of parameters for configuration of ADC hierarchical scope: */
/* common to several ADC instances. */
#define IS_LL_ADC_COMMON_CLOCK(__CLOCK__) \
( ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV2) \
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV4) \
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV6) \
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV8) \
)
/* Check of parameters for configuration of ADC hierarchical scope: */
/* ADC instance. */
#define IS_LL_ADC_RESOLUTION(__RESOLUTION__) \
( ((__RESOLUTION__) == LL_ADC_RESOLUTION_12B) \
|| ((__RESOLUTION__) == LL_ADC_RESOLUTION_10B) \
|| ((__RESOLUTION__) == LL_ADC_RESOLUTION_8B) \
|| ((__RESOLUTION__) == LL_ADC_RESOLUTION_6B) \
)
#define IS_LL_ADC_DATA_ALIGN(__DATA_ALIGN__) \
( ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_RIGHT) \
|| ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_LEFT) \
)
#define IS_LL_ADC_SCAN_SELECTION(__SCAN_SELECTION__) \
( ((__SCAN_SELECTION__) == LL_ADC_SEQ_SCAN_DISABLE) \
|| ((__SCAN_SELECTION__) == LL_ADC_SEQ_SCAN_ENABLE) \
)
#define IS_LL_ADC_SEQ_SCAN_MODE(__SEQ_SCAN_MODE__) \
( ((__SCAN_MODE__) == LL_ADC_SEQ_SCAN_DISABLE) \
|| ((__SCAN_MODE__) == LL_ADC_SEQ_SCAN_ENABLE) \
)
/* Check of parameters for configuration of ADC hierarchical scope: */
/* ADC group regular */
#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \
( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH3) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH4) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_TRGO) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_CH1) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM5_CH1) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM5_CH2) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM5_CH3) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_CH1) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO) \
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \
)
#define IS_LL_ADC_REG_CONTINUOUS_MODE(__REG_CONTINUOUS_MODE__) \
( ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_SINGLE) \
|| ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_CONTINUOUS) \
)
#define IS_LL_ADC_REG_DMA_TRANSFER(__REG_DMA_TRANSFER__) \
( ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_NONE) \
|| ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_LIMITED) \
|| ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_UNLIMITED) \
)
#define IS_LL_ADC_REG_FLAG_EOC_SELECTION(__REG_FLAG_EOC_SELECTION__) \
( ((__REG_FLAG_EOC_SELECTION__) == LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV) \
|| ((__REG_FLAG_EOC_SELECTION__) == LL_ADC_REG_FLAG_EOC_UNITARY_CONV) \
)
#define IS_LL_ADC_REG_SEQ_SCAN_LENGTH(__REG_SEQ_SCAN_LENGTH__) \
( ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_DISABLE) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS) \
|| ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS) \
)
#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__) \
( ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_2RANKS) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_3RANKS) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_4RANKS) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_5RANKS) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_6RANKS) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_7RANKS) \
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_8RANKS) \
)
/* Check of parameters for configuration of ADC hierarchical scope: */
/* ADC group injected */
#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__) \
( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH2) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_CH1) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_CH2) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_CH3) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM5_CH4) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM5_TRGO) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH2) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH3) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4) \
|| ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \
)
#define IS_LL_ADC_INJ_TRIG_EXT_EDGE(__INJ_TRIG_EXT_EDGE__) \
( ((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_RISING) \
|| ((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_FALLING) \
|| ((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_RISINGFALLING) \
)
#define IS_LL_ADC_INJ_TRIG_AUTO(__INJ_TRIG_AUTO__) \
( ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_INDEPENDENT) \
|| ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_FROM_GRP_REGULAR) \
)
#define IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(__INJ_SEQ_SCAN_LENGTH__) \
( ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_DISABLE) \
|| ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS) \
|| ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS) \
|| ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS) \
)
#define IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(__INJ_SEQ_DISCONT_MODE__) \
( ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_DISABLE) \
|| ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_1RANK) \
)
#if defined(ADC_MULTIMODE_SUPPORT)
/* Check of parameters for configuration of ADC hierarchical scope: */
/* multimode. */
#if defined(ADC3)
#define IS_LL_ADC_MULTI_MODE(__MULTI_MODE__) \
( ((__MULTI_MODE__) == LL_ADC_MULTI_INDEPENDENT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIMULT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTERL) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_SIMULT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_ALTERN) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_SIM) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_TRIPLE_REG_SIM_INJ_ALT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_TRIPLE_INJ_SIMULT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_TRIPLE_REG_SIMULT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_TRIPLE_REG_INTERL) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_TRIPLE_INJ_ALTERN) \
)
#else
#define IS_LL_ADC_MULTI_MODE(__MULTI_MODE__) \
( ((__MULTI_MODE__) == LL_ADC_MULTI_INDEPENDENT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIMULT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTERL) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_SIMULT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_ALTERN) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT) \
|| ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM) \
)
#endif
#define IS_LL_ADC_MULTI_DMA_TRANSFER(__MULTI_DMA_TRANSFER__) \
( ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_EACH_ADC) \
|| ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_LIMIT_1) \
|| ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_LIMIT_2) \
|| ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_LIMIT_3) \
|| ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_UNLMT_1) \
|| ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_UNLMT_2) \
|| ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_UNLMT_3) \
)
#define IS_LL_ADC_MULTI_TWOSMP_DELAY(__MULTI_TWOSMP_DELAY__) \
( ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_13CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_14CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_15CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_16CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_17CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_18CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_19CYCLES) \
|| ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_20CYCLES) \
)
#define IS_LL_ADC_MULTI_MASTER_SLAVE(__MULTI_MASTER_SLAVE__) \
( ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER) \
|| ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_SLAVE) \
|| ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER_SLAVE) \
)
#endif /* ADC_MULTIMODE_SUPPORT */
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup ADC_LL_Exported_Functions
* @{
*/
/** @addtogroup ADC_LL_EF_Init
* @{
*/
/**
* @brief De-initialize registers of all ADC instances belonging to
* the same ADC common instance to their default reset values.
* @param ADCxy_COMMON ADC common instance
* (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() )
* @retval An ErrorStatus enumeration value:
* - SUCCESS: ADC common registers are de-initialized
* - ERROR: not applicable
*/
ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON)
{
/* Check the parameters */
assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
/* Force reset of ADC clock (core clock) */
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_ADC);
/* Release reset of ADC clock (core clock) */
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_ADC);
return SUCCESS;
}
/**
* @brief Initialize some features of ADC common parameters
* (all ADC instances belonging to the same ADC common instance)
* and multimode (for devices with several ADC instances available).
* @note The setting of ADC common parameters is conditioned to
* ADC instances state:
* All ADC instances belonging to the same ADC common instance
* must be disabled.
* @param ADCxy_COMMON ADC common instance
* (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() )
* @param ADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure
* @retval An ErrorStatus enumeration value:
* - SUCCESS: ADC common registers are initialized
* - ERROR: ADC common registers are not initialized
*/
ErrorStatus LL_ADC_CommonInit(ADC_Common_TypeDef *ADCxy_COMMON, LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
{
ErrorStatus status = SUCCESS;
/* Check the parameters */
assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
assert_param(IS_LL_ADC_COMMON_CLOCK(ADC_CommonInitStruct->CommonClock));
#if defined(ADC_MULTIMODE_SUPPORT)
assert_param(IS_LL_ADC_MULTI_MODE(ADC_CommonInitStruct->Multimode));
if(ADC_CommonInitStruct->Multimode != LL_ADC_MULTI_INDEPENDENT)
{
assert_param(IS_LL_ADC_MULTI_DMA_TRANSFER(ADC_CommonInitStruct->MultiDMATransfer));
assert_param(IS_LL_ADC_MULTI_TWOSMP_DELAY(ADC_CommonInitStruct->MultiTwoSamplingDelay));
}
#endif /* ADC_MULTIMODE_SUPPORT */
/* Note: Hardware constraint (refer to description of functions */
/* "LL_ADC_SetCommonXXX()" and "LL_ADC_SetMultiXXX()"): */
/* On this STM32 series, setting of these features is conditioned to */
/* ADC state: */
/* All ADC instances of the ADC common group must be disabled. */
if(__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(ADCxy_COMMON) == 0UL)
{
/* Configuration of ADC hierarchical scope: */
/* - common to several ADC */
/* (all ADC instances belonging to the same ADC common instance) */
/* - Set ADC clock (conversion clock) */
/* - multimode (if several ADC instances available on the */
/* selected device) */
/* - Set ADC multimode configuration */
/* - Set ADC multimode DMA transfer */
/* - Set ADC multimode: delay between 2 sampling phases */
#if defined(ADC_MULTIMODE_SUPPORT)
if(ADC_CommonInitStruct->Multimode != LL_ADC_MULTI_INDEPENDENT)
{
MODIFY_REG(ADCxy_COMMON->CCR,
ADC_CCR_ADCPRE
| ADC_CCR_MULTI
| ADC_CCR_DMA
| ADC_CCR_DDS
| ADC_CCR_DELAY
,
ADC_CommonInitStruct->CommonClock
| ADC_CommonInitStruct->Multimode
| ADC_CommonInitStruct->MultiDMATransfer
| ADC_CommonInitStruct->MultiTwoSamplingDelay
);
}
else
{
MODIFY_REG(ADCxy_COMMON->CCR,
ADC_CCR_ADCPRE
| ADC_CCR_MULTI
| ADC_CCR_DMA
| ADC_CCR_DDS
| ADC_CCR_DELAY
,
ADC_CommonInitStruct->CommonClock
| LL_ADC_MULTI_INDEPENDENT
);
}
#else
LL_ADC_SetCommonClock(ADCxy_COMMON, ADC_CommonInitStruct->CommonClock);
#endif
}
else
{
/* Initialization error: One or several ADC instances belonging to */
/* the same ADC common instance are not disabled. */
status = ERROR;
}
return status;
}
/**
* @brief Set each @ref LL_ADC_CommonInitTypeDef field to default value.
* @param ADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure
* whose fields will be set to default values.
* @retval None
*/
void LL_ADC_CommonStructInit(LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
{
/* Set ADC_CommonInitStruct fields to default values */
/* Set fields of ADC common */
/* (all ADC instances belonging to the same ADC common instance) */
ADC_CommonInitStruct->CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV2;
#if defined(ADC_MULTIMODE_SUPPORT)
/* Set fields of ADC multimode */
ADC_CommonInitStruct->Multimode = LL_ADC_MULTI_INDEPENDENT;
ADC_CommonInitStruct->MultiDMATransfer = LL_ADC_MULTI_REG_DMA_EACH_ADC;
ADC_CommonInitStruct->MultiTwoSamplingDelay = LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES;
#endif /* ADC_MULTIMODE_SUPPORT */
}
/**
* @brief De-initialize registers of the selected ADC instance
* to their default reset values.
* @note To reset all ADC instances quickly (perform a hard reset),
* use function @ref LL_ADC_CommonDeInit().
* @param ADCx ADC instance
* @retval An ErrorStatus enumeration value:
* - SUCCESS: ADC registers are de-initialized
* - ERROR: ADC registers are not de-initialized
*/
ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx)
{
ErrorStatus status = SUCCESS;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(ADCx));
/* Disable ADC instance if not already disabled. */
if(LL_ADC_IsEnabled(ADCx) == 1UL)
{
/* Set ADC group regular trigger source to SW start to ensure to not */
/* have an external trigger event occurring during the conversion stop */
/* ADC disable process. */
LL_ADC_REG_SetTriggerSource(ADCx, LL_ADC_REG_TRIG_SOFTWARE);
/* Set ADC group injected trigger source to SW start to ensure to not */
/* have an external trigger event occurring during the conversion stop */
/* ADC disable process. */
LL_ADC_INJ_SetTriggerSource(ADCx, LL_ADC_INJ_TRIG_SOFTWARE);
/* Disable the ADC instance */
LL_ADC_Disable(ADCx);
}
/* Check whether ADC state is compliant with expected state */
/* (hardware requirements of bits state to reset registers below) */
if(READ_BIT(ADCx->CR2, ADC_CR2_ADON) == 0UL)
{
/* ========== Reset ADC registers ========== */
/* Reset register SR */
CLEAR_BIT(ADCx->SR,
( LL_ADC_FLAG_STRT
| LL_ADC_FLAG_JSTRT
| LL_ADC_FLAG_EOCS
| LL_ADC_FLAG_OVR
| LL_ADC_FLAG_JEOS
| LL_ADC_FLAG_AWD1 )
);
/* Reset register CR1 */
CLEAR_BIT(ADCx->CR1,
( ADC_CR1_OVRIE | ADC_CR1_RES | ADC_CR1_AWDEN
| ADC_CR1_JAWDEN
| ADC_CR1_DISCNUM | ADC_CR1_JDISCEN | ADC_CR1_DISCEN
| ADC_CR1_JAUTO | ADC_CR1_AWDSGL | ADC_CR1_SCAN
| ADC_CR1_JEOCIE | ADC_CR1_AWDIE | ADC_CR1_EOCIE
| ADC_CR1_AWDCH )
);
/* Reset register CR2 */
CLEAR_BIT(ADCx->CR2,
( ADC_CR2_SWSTART | ADC_CR2_EXTEN | ADC_CR2_EXTSEL
| ADC_CR2_JSWSTART | ADC_CR2_JEXTEN | ADC_CR2_JEXTSEL
| ADC_CR2_ALIGN | ADC_CR2_EOCS
| ADC_CR2_DDS | ADC_CR2_DMA
| ADC_CR2_CONT | ADC_CR2_ADON )
);
/* Reset register SMPR1 */
CLEAR_BIT(ADCx->SMPR1,
( ADC_SMPR1_SMP18 | ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16
| ADC_SMPR1_SMP15 | ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13
| ADC_SMPR1_SMP12 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10)
);
/* Reset register SMPR2 */
CLEAR_BIT(ADCx->SMPR2,
( ADC_SMPR2_SMP9
| ADC_SMPR2_SMP8 | ADC_SMPR2_SMP7 | ADC_SMPR2_SMP6
| ADC_SMPR2_SMP5 | ADC_SMPR2_SMP4 | ADC_SMPR2_SMP3
| ADC_SMPR2_SMP2 | ADC_SMPR2_SMP1 | ADC_SMPR2_SMP0)
);
/* Reset register JOFR1 */
CLEAR_BIT(ADCx->JOFR1, ADC_JOFR1_JOFFSET1);
/* Reset register JOFR2 */
CLEAR_BIT(ADCx->JOFR2, ADC_JOFR2_JOFFSET2);
/* Reset register JOFR3 */
CLEAR_BIT(ADCx->JOFR3, ADC_JOFR3_JOFFSET3);
/* Reset register JOFR4 */
CLEAR_BIT(ADCx->JOFR4, ADC_JOFR4_JOFFSET4);
/* Reset register HTR */
SET_BIT(ADCx->HTR, ADC_HTR_HT);
/* Reset register LTR */
CLEAR_BIT(ADCx->LTR, ADC_LTR_LT);
/* Reset register SQR1 */
CLEAR_BIT(ADCx->SQR1,
( ADC_SQR1_L
| ADC_SQR1_SQ16
| ADC_SQR1_SQ15 | ADC_SQR1_SQ14 | ADC_SQR1_SQ13)
);
/* Reset register SQR2 */
CLEAR_BIT(ADCx->SQR2,
( ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10
| ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7)
);
/* Reset register SQR3 */
CLEAR_BIT(ADCx->SQR3,
( ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4
| ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1)
);
/* Reset register JSQR */
CLEAR_BIT(ADCx->JSQR,
( ADC_JSQR_JL
| ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3
| ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 )
);
/* Reset register DR */
/* bits in access mode read only, no direct reset applicable */
/* Reset registers JDR1, JDR2, JDR3, JDR4 */
/* bits in access mode read only, no direct reset applicable */
/* Reset register CCR */
CLEAR_BIT(ADC->CCR, ADC_CCR_TSVREFE | ADC_CCR_ADCPRE);
}
return status;
}
/**
* @brief Initialize some features of ADC instance.
* @note These parameters have an impact on ADC scope: ADC instance.
* Affects both group regular and group injected (availability
* of ADC group injected depends on STM32 families).
* Refer to corresponding unitary functions into
* @ref ADC_LL_EF_Configuration_ADC_Instance .
* @note The setting of these parameters by function @ref LL_ADC_Init()
* is conditioned to ADC state:
* ADC instance must be disabled.
* This condition is applied to all ADC features, for efficiency
* and compatibility over all STM32 families. However, the different
* features can be set under different ADC state conditions
* (setting possible with ADC enabled without conversion on going,
* ADC enabled with conversion on going, ...)
* Each feature can be updated afterwards with a unitary function
* and potentially with ADC in a different state than disabled,
* refer to description of each function for setting
* conditioned to ADC state.
* @note After using this function, some other features must be configured
* using LL unitary functions.
* The minimum configuration remaining to be done is:
* - Set ADC group regular or group injected sequencer:
* map channel on the selected sequencer rank.
* Refer to function @ref LL_ADC_REG_SetSequencerRanks().
* - Set ADC channel sampling time
* Refer to function LL_ADC_SetChannelSamplingTime();
* @param ADCx ADC instance
* @param ADC_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
* @retval An ErrorStatus enumeration value:
* - SUCCESS: ADC registers are initialized
* - ERROR: ADC registers are not initialized
*/
ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct)
{
ErrorStatus status = SUCCESS;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(ADCx));
assert_param(IS_LL_ADC_RESOLUTION(ADC_InitStruct->Resolution));
assert_param(IS_LL_ADC_DATA_ALIGN(ADC_InitStruct->DataAlignment));
assert_param(IS_LL_ADC_SCAN_SELECTION(ADC_InitStruct->SequencersScanMode));
/* Note: Hardware constraint (refer to description of this function): */
/* ADC instance must be disabled. */
if(LL_ADC_IsEnabled(ADCx) == 0UL)
{
/* Configuration of ADC hierarchical scope: */
/* - ADC instance */
/* - Set ADC data resolution */
/* - Set ADC conversion data alignment */
MODIFY_REG(ADCx->CR1,
ADC_CR1_RES
| ADC_CR1_SCAN
,
ADC_InitStruct->Resolution
| ADC_InitStruct->SequencersScanMode
);
MODIFY_REG(ADCx->CR2,
ADC_CR2_ALIGN
,
ADC_InitStruct->DataAlignment
);
}
else
{
/* Initialization error: ADC instance is not disabled. */
status = ERROR;
}
return status;
}
/**
* @brief Set each @ref LL_ADC_InitTypeDef field to default value.
* @param ADC_InitStruct Pointer to a @ref LL_ADC_InitTypeDef structure
* whose fields will be set to default values.
* @retval None
*/
void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct)
{
/* Set ADC_InitStruct fields to default values */
/* Set fields of ADC instance */
ADC_InitStruct->Resolution = LL_ADC_RESOLUTION_12B;
ADC_InitStruct->DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
/* Enable scan mode to have a generic behavior with ADC of other */
/* STM32 families, without this setting available: */
/* ADC group regular sequencer and ADC group injected sequencer depend */
/* only of their own configuration. */
ADC_InitStruct->SequencersScanMode = LL_ADC_SEQ_SCAN_ENABLE;
}
/**
* @brief Initialize some features of ADC group regular.
* @note These parameters have an impact on ADC scope: ADC group regular.
* Refer to corresponding unitary functions into
* @ref ADC_LL_EF_Configuration_ADC_Group_Regular
* (functions with prefix "REG").
* @note The setting of these parameters by function @ref LL_ADC_Init()
* is conditioned to ADC state:
* ADC instance must be disabled.
* This condition is applied to all ADC features, for efficiency
* and compatibility over all STM32 families. However, the different
* features can be set under different ADC state conditions
* (setting possible with ADC enabled without conversion on going,
* ADC enabled with conversion on going, ...)
* Each feature can be updated afterwards with a unitary function
* and potentially with ADC in a different state than disabled,
* refer to description of each function for setting
* conditioned to ADC state.
* @note After using this function, other features must be configured
* using LL unitary functions.
* The minimum configuration remaining to be done is:
* - Set ADC group regular or group injected sequencer:
* map channel on the selected sequencer rank.
* Refer to function @ref LL_ADC_REG_SetSequencerRanks().
* - Set ADC channel sampling time
* Refer to function LL_ADC_SetChannelSamplingTime();
* @param ADCx ADC instance
* @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
* @retval An ErrorStatus enumeration value:
* - SUCCESS: ADC registers are initialized
* - ERROR: ADC registers are not initialized
*/
ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
{
ErrorStatus status = SUCCESS;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(ADCx));
assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource));
assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(ADC_REG_InitStruct->SequencerLength));
if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
{
assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont));
}
assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode));
assert_param(IS_LL_ADC_REG_DMA_TRANSFER(ADC_REG_InitStruct->DMATransfer));
/* ADC group regular continuous mode and discontinuous mode */
/* can not be enabled simultenaeously */
assert_param((ADC_REG_InitStruct->ContinuousMode == LL_ADC_REG_CONV_SINGLE)
|| (ADC_REG_InitStruct->SequencerDiscont == LL_ADC_REG_SEQ_DISCONT_DISABLE));
/* Note: Hardware constraint (refer to description of this function): */
/* ADC instance must be disabled. */
if(LL_ADC_IsEnabled(ADCx) == 0UL)
{
/* Configuration of ADC hierarchical scope: */
/* - ADC group regular */
/* - Set ADC group regular trigger source */
/* - Set ADC group regular sequencer length */
/* - Set ADC group regular sequencer discontinuous mode */
/* - Set ADC group regular continuous mode */
/* - Set ADC group regular conversion data transfer: no transfer or */
/* transfer by DMA, and DMA requests mode */
/* Note: On this STM32 series, ADC trigger edge is set when starting */
/* ADC conversion. */
/* Refer to function @ref LL_ADC_REG_StartConversionExtTrig(). */
if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
{
MODIFY_REG(ADCx->CR1,
ADC_CR1_DISCEN
| ADC_CR1_DISCNUM
,
ADC_REG_InitStruct->SequencerDiscont
);
}
else
{
MODIFY_REG(ADCx->CR1,
ADC_CR1_DISCEN
| ADC_CR1_DISCNUM
,
LL_ADC_REG_SEQ_DISCONT_DISABLE
);
}
MODIFY_REG(ADCx->CR2,
ADC_CR2_EXTSEL
| ADC_CR2_EXTEN
| ADC_CR2_CONT
| ADC_CR2_DMA
| ADC_CR2_DDS
,
(ADC_REG_InitStruct->TriggerSource & ADC_CR2_EXTSEL)
| ADC_REG_InitStruct->ContinuousMode
| ADC_REG_InitStruct->DMATransfer
);
/* Set ADC group regular sequencer length and scan direction */
/* Note: Hardware constraint (refer to description of this function): */
/* Note: If ADC instance feature scan mode is disabled */
/* (refer to ADC instance initialization structure */
/* parameter @ref SequencersScanMode */
/* or function @ref LL_ADC_SetSequencersScanMode() ), */
/* this parameter is discarded. */
LL_ADC_REG_SetSequencerLength(ADCx, ADC_REG_InitStruct->SequencerLength);
}
else
{
/* Initialization error: ADC instance is not disabled. */
status = ERROR;
}
return status;
}
/**
* @brief Set each @ref LL_ADC_REG_InitTypeDef field to default value.
* @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
* whose fields will be set to default values.
* @retval None
*/
void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
{
/* Set ADC_REG_InitStruct fields to default values */
/* Set fields of ADC group regular */
/* Note: On this STM32 series, ADC trigger edge is set when starting */
/* ADC conversion. */
/* Refer to function @ref LL_ADC_REG_StartConversionExtTrig(). */
ADC_REG_InitStruct->TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct->SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
ADC_REG_InitStruct->SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
ADC_REG_InitStruct->ContinuousMode = LL_ADC_REG_CONV_SINGLE;
ADC_REG_InitStruct->DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE;
}
/**
* @brief Initialize some features of ADC group injected.
* @note These parameters have an impact on ADC scope: ADC group injected.
* Refer to corresponding unitary functions into
* @ref ADC_LL_EF_Configuration_ADC_Group_Regular
* (functions with prefix "INJ").
* @note The setting of these parameters by function @ref LL_ADC_Init()
* is conditioned to ADC state:
* ADC instance must be disabled.
* This condition is applied to all ADC features, for efficiency
* and compatibility over all STM32 families. However, the different
* features can be set under different ADC state conditions
* (setting possible with ADC enabled without conversion on going,
* ADC enabled with conversion on going, ...)
* Each feature can be updated afterwards with a unitary function
* and potentially with ADC in a different state than disabled,
* refer to description of each function for setting
* conditioned to ADC state.
* @note After using this function, other features must be configured
* using LL unitary functions.
* The minimum configuration remaining to be done is:
* - Set ADC group injected sequencer:
* map channel on the selected sequencer rank.
* Refer to function @ref LL_ADC_INJ_SetSequencerRanks().
* - Set ADC channel sampling time
* Refer to function LL_ADC_SetChannelSamplingTime();
* @param ADCx ADC instance
* @param ADC_INJ_InitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure
* @retval An ErrorStatus enumeration value:
* - SUCCESS: ADC registers are initialized
* - ERROR: ADC registers are not initialized
*/
ErrorStatus LL_ADC_INJ_Init(ADC_TypeDef *ADCx, LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct)
{
ErrorStatus status = SUCCESS;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(ADCx));
assert_param(IS_LL_ADC_INJ_TRIG_SOURCE(ADC_INJ_InitStruct->TriggerSource));
assert_param(IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(ADC_INJ_InitStruct->SequencerLength));
if(ADC_INJ_InitStruct->SequencerLength != LL_ADC_INJ_SEQ_SCAN_DISABLE)
{
assert_param(IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(ADC_INJ_InitStruct->SequencerDiscont));
}
assert_param(IS_LL_ADC_INJ_TRIG_AUTO(ADC_INJ_InitStruct->TrigAuto));
/* Note: Hardware constraint (refer to description of this function): */
/* ADC instance must be disabled. */
if(LL_ADC_IsEnabled(ADCx) == 0UL)
{
/* Configuration of ADC hierarchical scope: */
/* - ADC group injected */
/* - Set ADC group injected trigger source */
/* - Set ADC group injected sequencer length */
/* - Set ADC group injected sequencer discontinuous mode */
/* - Set ADC group injected conversion trigger: independent or */
/* from ADC group regular */
/* Note: On this STM32 series, ADC trigger edge is set when starting */
/* ADC conversion. */
/* Refer to function @ref LL_ADC_INJ_StartConversionExtTrig(). */
if(ADC_INJ_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
{
MODIFY_REG(ADCx->CR1,
ADC_CR1_JDISCEN
| ADC_CR1_JAUTO
,
ADC_INJ_InitStruct->SequencerDiscont
| ADC_INJ_InitStruct->TrigAuto
);
}
else
{
MODIFY_REG(ADCx->CR1,
ADC_CR1_JDISCEN
| ADC_CR1_JAUTO
,
LL_ADC_REG_SEQ_DISCONT_DISABLE
| ADC_INJ_InitStruct->TrigAuto
);
}
MODIFY_REG(ADCx->CR2,
ADC_CR2_JEXTSEL
| ADC_CR2_JEXTEN
,
(ADC_INJ_InitStruct->TriggerSource & ADC_CR2_JEXTSEL)
);
/* Note: Hardware constraint (refer to description of this function): */
/* Note: If ADC instance feature scan mode is disabled */
/* (refer to ADC instance initialization structure */
/* parameter @ref SequencersScanMode */
/* or function @ref LL_ADC_SetSequencersScanMode() ), */
/* this parameter is discarded. */
LL_ADC_INJ_SetSequencerLength(ADCx, ADC_INJ_InitStruct->SequencerLength);
}
else
{
/* Initialization error: ADC instance is not disabled. */
status = ERROR;
}
return status;
}
/**
* @brief Set each @ref LL_ADC_INJ_InitTypeDef field to default value.
* @param ADC_INJ_InitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure
* whose fields will be set to default values.
* @retval None
*/
void LL_ADC_INJ_StructInit(LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct)
{
/* Set ADC_INJ_InitStruct fields to default values */
/* Set fields of ADC group injected */
ADC_INJ_InitStruct->TriggerSource = LL_ADC_INJ_TRIG_SOFTWARE;
ADC_INJ_InitStruct->SequencerLength = LL_ADC_INJ_SEQ_SCAN_DISABLE;
ADC_INJ_InitStruct->SequencerDiscont = LL_ADC_INJ_SEQ_DISCONT_DISABLE;
ADC_INJ_InitStruct->TrigAuto = LL_ADC_INJ_TRIG_INDEPENDENT;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* ADC1 || ADC2 || ADC3 */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */

50
Inc/adc.h Normal file
View File

@ -0,0 +1,50 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc.h
* @brief This file contains all the function prototypes for
* the adc.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 __ADC_H__
#define __ADC_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_ADC1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __ADC_H__ */

52
Inc/dma.h Normal file
View File

@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.h
* @brief This file contains all the function prototypes for
* the dma.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 __DMA_H__
#define __DMA_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* DMA memory to memory transfer handles -------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_DMA_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __DMA_H__ */

View File

@ -23,12 +23,13 @@
#define __MAIN_H #define __MAIN_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C" {
{
#endif #endif
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_ll_adc.h"
#include "stm32f4xx_ll_dma.h"
#include "stm32f4xx_ll_rcc.h" #include "stm32f4xx_ll_rcc.h"
#include "stm32f4xx_ll_bus.h" #include "stm32f4xx_ll_bus.h"
#include "stm32f4xx_ll_system.h" #include "stm32f4xx_ll_system.h"
@ -36,7 +37,6 @@ extern "C"
#include "stm32f4xx_ll_cortex.h" #include "stm32f4xx_ll_cortex.h"
#include "stm32f4xx_ll_utils.h" #include "stm32f4xx_ll_utils.h"
#include "stm32f4xx_ll_pwr.h" #include "stm32f4xx_ll_pwr.h"
#include "stm32f4xx_ll_dma.h"
#include "stm32f4xx_ll_tim.h" #include "stm32f4xx_ll_tim.h"
#include "stm32f4xx_ll_gpio.h" #include "stm32f4xx_ll_gpio.h"
@ -50,25 +50,25 @@ extern "C"
#include "delay.h" #include "delay.h"
#include "lib.h" #include "lib.h"
#include "bsp.h" #include "bsp.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/ /* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */ /* USER CODE BEGIN ET */
/* USER CODE END ET */ /* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */ /* USER CODE BEGIN EC */
/* USER CODE END EC */ /* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */ /* USER CODE BEGIN EM */
/* USER CODE END EM */ /* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/ /* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void); void Error_Handler(void);
/* USER CODE BEGIN EFP */ /* USER CODE BEGIN EFP */
@ -80,21 +80,21 @@ extern "C"
#define LED_GREEN_Pin LL_GPIO_PIN_1 #define LED_GREEN_Pin LL_GPIO_PIN_1
#define LED_GREEN_GPIO_Port GPIOE #define LED_GREEN_GPIO_Port GPIOE
#ifndef NVIC_PRIORITYGROUP_0 #ifndef NVIC_PRIORITYGROUP_0
#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority, \ #define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
4 bits for subpriority */ 4 bits for subpriority */
#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bit for pre-emption priority, \ #define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bit for pre-emption priority,
3 bits for subpriority */ 3 bits for subpriority */
#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority, \ #define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority,
2 bits for subpriority */ 2 bits for subpriority */
#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority, \ #define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority,
1 bit for subpriority */ 1 bit for subpriority */
#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority, \ #define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority,
0 bit for subpriority */ 0 bit for subpriority */
#endif #endif
/* USER CODE BEGIN Private defines */ /* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */ /* USER CODE END Private defines */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -55,7 +55,9 @@ void SVC_Handler(void);
void DebugMon_Handler(void); void DebugMon_Handler(void);
void PendSV_Handler(void); void PendSV_Handler(void);
void SysTick_Handler(void); void SysTick_Handler(void);
void ADC_IRQHandler(void);
void TIM6_DAC_IRQHandler(void); void TIM6_DAC_IRQHandler(void);
void DMA2_Stream0_IRQHandler(void);
/* USER CODE BEGIN EFP */ /* USER CODE BEGIN EFP */
/* USER CODE END EFP */ /* USER CODE END EFP */

44
MDK-ARM/JLinkSettings.ini Normal file
View File

@ -0,0 +1,44 @@
[BREAKPOINTS]
ForceImpTypeAny = 0
ShowInfoWin = 1
EnableFlashBP = 2
BPDuringExecution = 0
[CFI]
CFISize = 0x00
CFIAddr = 0x00
[CPU]
MonModeVTableAddr = 0xFFFFFFFF
MonModeDebug = 0
MaxNumAPs = 0
LowPowerHandlingMode = 0
OverrideMemMap = 0
AllowSimulation = 1
ScriptFile=""
[FLASH]
RMWThreshold = 0x400
Loaders=""
EraseType = 0x00
CacheExcludeSize = 0x00
CacheExcludeAddr = 0x00
MinNumBytesFlashDL = 0
SkipProgOnCRCMatch = 1
VerifyDownload = 1
AllowCaching = 1
EnableFlashDL = 2
Override = 0
Device="ARM7"
[GENERAL]
WorkRAMSize = 0x00
WorkRAMAddr = 0x00
RAMUsageLimit = 0x00
[SWO]
SWOLogFile=""
[MEM]
RdOverrideOrMask = 0x00
RdOverrideAndMask = 0xFFFFFFFF
RdOverrideAddr = 0xFFFFFFFF
WrOverrideOrMask = 0x00
WrOverrideAndMask = 0xFFFFFFFF
WrOverrideAddr = 0xFFFFFFFF
[RAM]
VerifyDownload = 0x00

View File

@ -103,7 +103,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>3</nTsel> <nTsel>4</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>
@ -114,9 +114,19 @@
<tDlgDll></tDlgDll> <tDlgDll></tDlgDll>
<tDlgPa></tDlgPa> <tDlgPa></tDlgPa>
<tIfile></tIfile> <tIfile></tIfile>
<pMon>BIN\CMSIS_AGDI.dll</pMon> <pMon>Segger\JL2CM3.dll</pMon>
</DebugOpt> </DebugOpt>
<TargetDriverDllRegistry> <TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name>
</Name> </SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>JL2CM3</Key>
<Name>-U601012352 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407IGTx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name>
</SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key> <Key>ARMRTXEVENTFLAGS</Key>
@ -137,11 +147,6 @@
<Key>CMSIS_AGDI</Key> <Key>CMSIS_AGDI</Key>
<Name>-X"" -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407IGTx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name> <Name>-X"" -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407IGTx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name>
</SetRegEntry> </SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>UL2CM3</Key> <Key>UL2CM3</Key>
@ -154,6 +159,46 @@
</SetRegEntry> </SetRegEntry>
</TargetDriverDllRegistry> </TargetDriverDllRegistry>
<Breakpoint/> <Breakpoint/>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
<ItemText>p,0x0A</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>adcs</ItemText>
</Ww>
<Ww>
<count>2</count>
<WinNumber>1</WinNumber>
<ItemText>app</ItemText>
</Ww>
<Ww>
<count>3</count>
<WinNumber>1</WinNumber>
<ItemText>board,0x0A</ItemText>
</Ww>
<Ww>
<count>4</count>
<WinNumber>1</WinNumber>
<ItemText>0x000020CF,0x0A</ItemText>
</Ww>
<Ww>
<count>5</count>
<WinNumber>1</WinNumber>
<ItemText>0x0063,0x0A</ItemText>
</Ww>
</WatchWindow1>
<MemoryWindow1>
<Mm>
<WinNumber>1</WinNumber>
<SubType>0</SubType>
<ItemText>0x2001C9C0</ItemText>
<AccSizeX>0</AccSizeX>
</Mm>
</MemoryWindow1>
<Tracepoint> <Tracepoint>
<THDelay>0</THDelay> <THDelay>0</THDelay>
</Tracepoint> </Tracepoint>
@ -196,6 +241,12 @@
<pszMrulep></pszMrulep> <pszMrulep></pszMrulep>
<pSingCmdsp></pSingCmdsp> <pSingCmdsp></pSingCmdsp>
<pMultCmdsp></pMultCmdsp> <pMultCmdsp></pMultCmdsp>
<SystemViewers>
<Entry>
<Name>System Viewer\TIM6</Name>
<WinId>35905</WinId>
</Entry>
</SystemViewers>
<DebugDescription> <DebugDescription>
<Enable>1</Enable> <Enable>1</Enable>
<EnableFlashSeq>1</EnableFlashSeq> <EnableFlashSeq>1</EnableFlashSeq>
@ -228,7 +279,7 @@
<Group> <Group>
<GroupName>Application/User</GroupName> <GroupName>Application/User</GroupName>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@ -263,6 +314,30 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>../Src/adc.c</PathWithFileName>
<FilenameWithoutPath>adc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>5</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Src/dma.c</PathWithFileName>
<FilenameWithoutPath>dma.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>6</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Src/tim.c</PathWithFileName> <PathWithFileName>../Src/tim.c</PathWithFileName>
<FilenameWithoutPath>tim.c</FilenameWithoutPath> <FilenameWithoutPath>tim.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@ -270,7 +345,7 @@
</File> </File>
<File> <File>
<GroupNumber>2</GroupNumber> <GroupNumber>2</GroupNumber>
<FileNumber>5</FileNumber> <FileNumber>7</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -290,7 +365,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>6</FileNumber> <FileNumber>8</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -302,19 +377,19 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>7</FileNumber> <FileNumber>9</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_tim.c</PathWithFileName> <PathWithFileName>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c</PathWithFileName>
<FilenameWithoutPath>stm32f4xx_ll_tim.c</FilenameWithoutPath> <FilenameWithoutPath>stm32f4xx_ll_adc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>8</FileNumber> <FileNumber>10</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -326,7 +401,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>9</FileNumber> <FileNumber>11</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -338,7 +413,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>10</FileNumber> <FileNumber>12</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -350,7 +425,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>11</FileNumber> <FileNumber>13</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -360,6 +435,18 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>14</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_tim.c</PathWithFileName>
<FilenameWithoutPath>stm32f4xx_ll_tim.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group> </Group>
<Group> <Group>
@ -370,7 +457,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>12</FileNumber> <FileNumber>15</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -390,7 +477,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>5</GroupNumber> <GroupNumber>5</GroupNumber>
<FileNumber>13</FileNumber> <FileNumber>16</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -410,7 +497,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>14</FileNumber> <FileNumber>17</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -423,47 +510,11 @@
</Group> </Group>
<Group> <Group>
<GroupName>User/lib</GroupName> <GroupName>User/system</GroupName>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>15</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\aes.c</PathWithFileName>
<FilenameWithoutPath>aes.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>16</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\clist.c</PathWithFileName>
<FilenameWithoutPath>clist.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>17</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\cmac.c</PathWithFileName>
<FilenameWithoutPath>cmac.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>18</FileNumber> <FileNumber>18</FileNumber>
@ -471,8 +522,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\cmd.c</PathWithFileName> <PathWithFileName>..\User\system\btn.c</PathWithFileName>
<FilenameWithoutPath>cmd.c</FilenameWithoutPath> <FilenameWithoutPath>btn.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -483,8 +534,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\data_analysis.c</PathWithFileName> <PathWithFileName>..\User\system\delay.c</PathWithFileName>
<FilenameWithoutPath>data_analysis.c</FilenameWithoutPath> <FilenameWithoutPath>delay.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -495,103 +546,103 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\debug.c</PathWithFileName> <PathWithFileName>..\User\system\sys.c</PathWithFileName>
<FilenameWithoutPath>debug.c</FilenameWithoutPath> <FilenameWithoutPath>sys.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\filter.c</PathWithFileName>
<FilenameWithoutPath>filter.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\lib.c</PathWithFileName>
<FilenameWithoutPath>lib.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\malloc.c</PathWithFileName>
<FilenameWithoutPath>malloc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\mlist.c</PathWithFileName>
<FilenameWithoutPath>mlist.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\pbuf.c</PathWithFileName>
<FilenameWithoutPath>pbuf.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\src\sqqueue.c</PathWithFileName>
<FilenameWithoutPath>sqqueue.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\lib\flow\flow_core.c</PathWithFileName>
<FilenameWithoutPath>flow_core.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
</Group> </Group>
<Group> <Group>
<GroupName>User/system</GroupName> <GroupName>User/lib</GroupName>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\lib\src\aes.c</PathWithFileName>
<FilenameWithoutPath>aes.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\lib\src\clist.c</PathWithFileName>
<FilenameWithoutPath>clist.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\lib\src\cmac.c</PathWithFileName>
<FilenameWithoutPath>cmac.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\lib\src\cmd.c</PathWithFileName>
<FilenameWithoutPath>cmd.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\lib\src\data_analysis.c</PathWithFileName>
<FilenameWithoutPath>data_analysis.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\lib\src\debug.c</PathWithFileName>
<FilenameWithoutPath>debug.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\lib\src\filter.c</PathWithFileName>
<FilenameWithoutPath>filter.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File> <File>
<GroupNumber>8</GroupNumber> <GroupNumber>8</GroupNumber>
<FileNumber>28</FileNumber> <FileNumber>28</FileNumber>
@ -599,8 +650,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\src\btn.c</PathWithFileName> <PathWithFileName>..\User\system\lib\src\lib.c</PathWithFileName>
<FilenameWithoutPath>btn.c</FilenameWithoutPath> <FilenameWithoutPath>lib.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -611,8 +662,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\src\delay.c</PathWithFileName> <PathWithFileName>..\User\system\lib\src\malloc.c</PathWithFileName>
<FilenameWithoutPath>delay.c</FilenameWithoutPath> <FilenameWithoutPath>malloc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -623,8 +674,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\src\sys.c</PathWithFileName> <PathWithFileName>..\User\system\lib\src\mlist.c</PathWithFileName>
<FilenameWithoutPath>sys.c</FilenameWithoutPath> <FilenameWithoutPath>mlist.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -635,8 +686,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\adcs.c</PathWithFileName> <PathWithFileName>..\User\system\lib\src\pbuf.c</PathWithFileName>
<FilenameWithoutPath>adcs.c</FilenameWithoutPath> <FilenameWithoutPath>pbuf.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -647,8 +698,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\bsp.c</PathWithFileName> <PathWithFileName>..\User\system\lib\src\sqqueue.c</PathWithFileName>
<FilenameWithoutPath>bsp.c</FilenameWithoutPath> <FilenameWithoutPath>sqqueue.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -659,8 +710,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\gpios.c</PathWithFileName> <PathWithFileName>..\User\system\lib\src\storage.c</PathWithFileName>
<FilenameWithoutPath>gpios.c</FilenameWithoutPath> <FilenameWithoutPath>storage.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -671,8 +722,8 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\i2cs.c</PathWithFileName> <PathWithFileName>..\User\system\lib\src\wl_flash.c</PathWithFileName>
<FilenameWithoutPath>i2cs.c</FilenameWithoutPath> <FilenameWithoutPath>wl_flash.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
@ -683,59 +734,67 @@
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\iwdgs.c</PathWithFileName> <PathWithFileName>..\User\system\lib\flow\flow_core.c</PathWithFileName>
<FilenameWithoutPath>iwdgs.c</FilenameWithoutPath> <FilenameWithoutPath>flow_core.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
</Group>
<Group>
<GroupName>User/system/bsp</GroupName>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>8</GroupNumber> <GroupNumber>9</GroupNumber>
<FileNumber>36</FileNumber> <FileNumber>36</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\pwms.c</PathWithFileName> <PathWithFileName>..\User\system\bsp\adcs.c</PathWithFileName>
<FilenameWithoutPath>pwms.c</FilenameWithoutPath> <FilenameWithoutPath>adcs.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
<File> <File>
<GroupNumber>8</GroupNumber> <GroupNumber>9</GroupNumber>
<FileNumber>37</FileNumber> <FileNumber>37</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\spis.c</PathWithFileName> <PathWithFileName>..\User\system\bsp\bsp.c</PathWithFileName>
<FilenameWithoutPath>spis.c</FilenameWithoutPath> <FilenameWithoutPath>bsp.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
<File> <File>
<GroupNumber>8</GroupNumber> <GroupNumber>9</GroupNumber>
<FileNumber>38</FileNumber> <FileNumber>38</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\gpios.c</PathWithFileName>
<FilenameWithoutPath>gpios.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>39</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\tims.c</PathWithFileName> <PathWithFileName>..\User\system\bsp\tims.c</PathWithFileName>
<FilenameWithoutPath>tims.c</FilenameWithoutPath> <FilenameWithoutPath>tims.c</FilenameWithoutPath>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>39</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\system\bsp\uarts.c</PathWithFileName>
<FilenameWithoutPath>uarts.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group> </Group>
<Group> <Group>

View File

@ -53,8 +53,8 @@
<CreateExecutable>1</CreateExecutable> <CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib> <CreateLib>0</CreateLib>
<CreateHexFile>1</CreateHexFile> <CreateHexFile>1</CreateHexFile>
<DebugInformation>0</DebugInformation> <DebugInformation>1</DebugInformation>
<BrowseInformation>1</BrowseInformation> <BrowseInformation>0</BrowseInformation>
<ListingPath></ListingPath> <ListingPath></ListingPath>
<HexFormatSelection>1</HexFormatSelection> <HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K> <Merge32K>0</Merge32K>
@ -339,7 +339,7 @@
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>STM32,USE_FULL_LL_DRIVER,HSE_VALUE=8000000,HSE_STARTUP_TIMEOUT=100,LSE_STARTUP_TIMEOUT=5000,LSE_VALUE=32768,EXTERNAL_CLOCK_VALUE=12288000,HSI_VALUE=16000000,LSI_VALUE=32000,VDD_VALUE=3300,PREFETCH_ENABLE=1,INSTRUCTION_CACHE_ENABLE=1,DATA_CACHE_ENABLE=1,STM32F407xx</Define> <Define>STM32,USE_FULL_LL_DRIVER,HSE_VALUE=8000000,HSE_STARTUP_TIMEOUT=100,LSE_STARTUP_TIMEOUT=5000,LSE_VALUE=32768,EXTERNAL_CLOCK_VALUE=12288000,HSI_VALUE=16000000,LSI_VALUE=32000,VDD_VALUE=3300,PREFETCH_ENABLE=1,INSTRUCTION_CACHE_ENABLE=1,DATA_CACHE_ENABLE=1,STM32F407xx</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../User;../User/application;../User/board;../User/system/inc;../User/system/bsp;../User/lib/inc;../User/lib/flow;../User/lib/control/inc</IncludePath> <IncludePath>../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../User;../User/application;../User/board;../User/system;../User/system/bsp;../User/system/lib/inc;../User/system/lib/flow;../User/system/lib/control/inc</IncludePath>
</VariousControls> </VariousControls>
</Cads> </Cads>
<Aads> <Aads>
@ -403,6 +403,118 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>../Src/gpio.c</FilePath> <FilePath>../Src/gpio.c</FilePath>
</File> </File>
<File>
<FileName>adc.c</FileName>
<FileType>1</FileType>
<FilePath>../Src/adc.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>dma.c</FileName>
<FileType>1</FileType>
<FilePath>../Src/dma.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File> <File>
<FileName>tim.c</FileName> <FileName>tim.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
@ -475,9 +587,9 @@
<FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c</FilePath> <FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c</FilePath>
</File> </File>
<File> <File>
<FileName>stm32f4xx_ll_tim.c</FileName> <FileName>stm32f4xx_ll_adc.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_tim.c</FilePath> <FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_adc.c</FilePath>
<FileOption> <FileOption>
<CommonProperty> <CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler> <UseCPPCompiler>2</UseCPPCompiler>
@ -601,6 +713,62 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_exti.c</FilePath> <FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_exti.c</FilePath>
</File> </File>
<File>
<FileName>stm32f4xx_ll_tim.c</FileName>
<FileType>1</FileType>
<FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_tim.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -633,149 +801,113 @@
</File> </File>
</Files> </Files>
</Group> </Group>
<Group>
<GroupName>User/lib</GroupName>
<Files>
<File>
<FileName>aes.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\aes.c</FilePath>
</File>
<File>
<FileName>clist.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\clist.c</FilePath>
</File>
<File>
<FileName>cmac.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\cmac.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\cmd.c</FilePath>
</File>
<File>
<FileName>data_analysis.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\data_analysis.c</FilePath>
</File>
<File>
<FileName>debug.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\debug.c</FilePath>
</File>
<File>
<FileName>filter.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\filter.c</FilePath>
</File>
<File>
<FileName>lib.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\lib.c</FilePath>
</File>
<File>
<FileName>malloc.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\malloc.c</FilePath>
</File>
<File>
<FileName>mlist.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\mlist.c</FilePath>
</File>
<File>
<FileName>pbuf.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\pbuf.c</FilePath>
</File>
<File>
<FileName>sqqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\src\sqqueue.c</FilePath>
</File>
<File>
<FileName>flow_core.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\lib\flow\flow_core.c</FilePath>
</File>
</Files>
</Group>
<Group> <Group>
<GroupName>User/system</GroupName> <GroupName>User/system</GroupName>
<Files> <Files>
<File> <File>
<FileName>btn.c</FileName> <FileName>btn.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\system\src\btn.c</FilePath> <FilePath>..\User\system\btn.c</FilePath>
</File> </File>
<File> <File>
<FileName>delay.c</FileName> <FileName>delay.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\system\src\delay.c</FilePath> <FilePath>..\User\system\delay.c</FilePath>
</File> </File>
<File> <File>
<FileName>sys.c</FileName> <FileName>sys.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\system\src\sys.c</FilePath> <FilePath>..\User\system\sys.c</FilePath>
</File> </File>
</Files>
</Group>
<Group>
<GroupName>User/lib</GroupName>
<Files>
<File>
<FileName>aes.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\aes.c</FilePath>
</File>
<File>
<FileName>clist.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\clist.c</FilePath>
</File>
<File>
<FileName>cmac.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\cmac.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\cmd.c</FilePath>
</File>
<File>
<FileName>data_analysis.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\data_analysis.c</FilePath>
</File>
<File>
<FileName>debug.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\debug.c</FilePath>
</File>
<File>
<FileName>filter.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\filter.c</FilePath>
</File>
<File>
<FileName>lib.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\lib.c</FilePath>
</File>
<File>
<FileName>malloc.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\malloc.c</FilePath>
</File>
<File>
<FileName>mlist.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\mlist.c</FilePath>
</File>
<File>
<FileName>pbuf.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\pbuf.c</FilePath>
</File>
<File>
<FileName>sqqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\sqqueue.c</FilePath>
</File>
<File>
<FileName>storage.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\storage.c</FilePath>
</File>
<File>
<FileName>wl_flash.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\src\wl_flash.c</FilePath>
</File>
<File>
<FileName>flow_core.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\lib\flow\flow_core.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>User/system/bsp</GroupName>
<Files>
<File> <File>
<FileName>adcs.c</FileName> <FileName>adcs.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\system\bsp\adcs.c</FilePath> <FilePath>..\User\system\bsp\adcs.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File> </File>
<File> <File>
<FileName>bsp.c</FileName> <FileName>bsp.c</FileName>
@ -787,240 +919,11 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\system\bsp\gpios.c</FilePath> <FilePath>..\User\system\bsp\gpios.c</FilePath>
</File> </File>
<File>
<FileName>i2cs.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\bsp\i2cs.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>iwdgs.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\bsp\iwdgs.c</FilePath>
</File>
<File>
<FileName>pwms.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\bsp\pwms.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>spis.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\bsp\spis.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File> <File>
<FileName>tims.c</FileName> <FileName>tims.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\system\bsp\tims.c</FilePath> <FilePath>..\User\system\bsp\tims.c</FilePath>
</File> </File>
<File>
<FileName>uarts.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\system\bsp\uarts.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>

View File

@ -1,13 +1,13 @@
:020000040800F2 :020000040800F2
:1000000080180020A101000815070008130200084D :10000000F0E50020A1010008AD0C00087D02000809
:10001000110700080D020008550900080000000043 :10001000A90C000851020008ED0E000800000000C5
:100020000000000000000000000000001B070008A6 :10002000000000000000000000000000B30C000809
:100030001102000800000000190700081D07000851 :100030007B02000800000000B10C0008B50C0008AD
:10004000BB010008BB010008BB010008BB010008A0 :10004000BB010008BB010008BB010008BB010008A0
:10005000BB010008BB010008BB010008BB01000890 :10005000BB010008BB010008BB010008BB01000890
:10006000BB010008BB010008BB010008BB01000880 :10006000BB010008BB010008BB010008BB01000880
:10007000BB010008BB010008BB010008BB01000870 :10007000BB010008BB010008BB010008BB01000870
:10008000BB010008BB010008BB010008BB01000860 :10008000BB010008BB01000847020008BB010008D3
:10009000BB010008BB010008BB010008BB01000850 :10009000BB010008BB010008BB010008BB01000850
:1000A000BB010008BB010008BB010008BB01000840 :1000A000BB010008BB010008BB010008BB01000840
:1000B000BB010008BB010008BB010008BB01000830 :1000B000BB010008BB010008BB010008BB01000830
@ -16,200 +16,407 @@
:1000E000BB010008BB010008BB010008BB01000800 :1000E000BB010008BB010008BB010008BB01000800
:1000F000BB010008BB010008BB010008BB010008F0 :1000F000BB010008BB010008BB010008BB010008F0
:10010000BB010008BB010008BB010008BB010008DF :10010000BB010008BB010008BB010008BB010008DF
:10011000BB010008BB0100086D080008BB01000816 :10011000BB010008BB010008050E0008BB01000878
:10012000BB010008BB010008BB010008BB010008BF :1001200071020008BB010008BB010008BB01000808
:10013000BB010008BB010008BB010008BB010008AF :10013000BB010008BB010008BB010008BB010008AF
:10014000BB010008BB010008BB010008BB0100089F :10014000BB010008BB010008BB010008BB0100089F
:10015000BB010008BB010008BB010008BB0100088F :10015000BB010008BB010008BB010008BB0100088F
:10016000BB010008BB010008BB010008BB0100087F :10016000BB010008BB010008BB010008BB0100087F
:10017000BB010008BB010008BB0100080000000033 :10017000BB010008BB010008BB0100080000000033
:10018000BB010008BB010008DFF810D000F02CF81C :10018000BB010008BB010008DFF810D000F02CF81C
:1001900000480047C90A0008AFF30080801800201B :1001900000480047D1150008AFF30080F0E50020CB
:1001A0000648804706480047FEE7FEE7FEE7FEE711 :1001A0000648804706480047FEE7FEE7FEE7FEE711
:1001B000FEE7FEE7FEE7FEE7FEE7FEE75908000878 :1001B000FEE7FEE7FEE7FEE7FEE7FEE7F10D0008DB
:1001C00089010008D2B201E000F8012B491EFBD2E0 :1001C00089010008D2B201E000F8012B491EFBD2E0
:1001D00070470022F6E710B513460A460446194652 :1001D00070470022F6E710B513460A460446194652
:1001E000FFF7F0FF204610BD064C074D06E0E06823 :1001E000FFF7F0FF204610BD064C074D06E0E06823
:1001F00040F0010394E8070098471034AC42F6D36E :1001F00040F0010394E8070098471034AC42F6D36E
:10020000FFF7C6FFB00C0008D00C000800BFFEE7E7 :10020000FFF7C6FF341900085419000830B58C18E0
:10021000704700BFFEE7000008B5054909680143C3 :1002100010F8012B12F00F0301D110F8013B120965
:10022000034A1160114609680140009100BF08BDF2 :1002200006D110F8012B03E010F8015B01F8015B27
:1002300030380240F0B502460B4600240021186811 :100230005B1EF9D101E001F8013B521EFBD1A14246
:1002400090FAA0F0B0FA80F48AE00125A540186881 :10024000E6D3002030BD10B5002000F0B5FE10BD93
:1002500000EA050100297DD05868012802D05868BD :1002500000BFFEE770B504460D4600BF2CB901F0A3
:1002600002281CD19868956891FAA1F6B6FA86F62C :1002600003FB01E000BF00BFFCE700BF012070BD41
:1002700077000326BE40B54391FAA1F6B6FA86F69A :1002700010B5002000F076FE10BD704700BFFEE70D
:10028000760000FA06F63543956000BFD8685568D9 :100280002DE9F04105460C460026606800B100BF2C
:100290008D4301FB00F63543556000BF00BF186970 :10029000134800F049F80746124800F045F80743B4
:1002A000D56891FAA1F6B6FA86F677000326BE4025 :1002A000114800F041F80743AFB9606860B1D4E984
:1002B000B54391FAA1F6B6FA86F6760000FA06F68C :1002B00000010843A1680843E168084369680B4AE4
:1002C0003543D56000BF5868022831D191FAA1F0BA :1002C00011400843686007E06868084908402168F1
:1002D000B0FA80F0082814D25869156A91FAA1F68C :1002D0000843686000E001263046BDE8F081000078
:1002E000B6FA86F6B7000F26BE40B54391FAA1F6DE :1002E000002001400021014000220140E010FCFFFD
:1002F000B6FA86F6B60000FA06F63543156200BF78 :1002F00070B504460D460026204600F015F870B98A
:1003000016E05869556A0E0A96FAA6F6B6FA86F607 :10030000A968286808436168064A1140084360608C
:10031000B7000F26BE40B5430E0A96FAA6F6B6FA07 :10031000A06820F4006069680843A06000E001263E
:1003200086F6B60000FA06F63543556200BF00BFF8 :10032000304670BDFFFEFFFC0146886800F001000A
:100330005868156891FAA1F6B6FA86F67700032692 :100330007047000070B504460D460026686800B19D
:10034000BE40B54391FAA1F6B6FA86F6760000FAF9 :1003400000BF2046FFF7F0FF00BB686830B160686F
:1003500006F600E003E03543156000BF00BF641CF3 :1003500020F46840A9680843606003E0606820F406
:100360001868E04000287FF470AFF0BD02480068D4 :1003600068406060286800F07060E96808432969A7
:10037000401C014908607047480000204FF47A7122 :100370000843A168074A11400843A0606868E16A21
:10038000B0FBF1F2521E4FF0E0235A6100229A6155 :1003800021F470010143E16200BF00E00126304624
:1003900005221A6100BF70470149086070470000DC :1003900070BD0000FDFCFFC070B501F440744FF467
:1003A0000000002010B5024613682C4882420ED08F :1003A000407595FAA5F5B5FA85F5EC4000F12C05F8
:1003B000B2F1804F0BD02A48824208D029488242AD :1003B00005EB84031C6801F01F061F25B540AC4304
:1003C00005D02948824202D02848824204D123F035 :1003C00002F01F0501F01F06B5402C431C6070BDF4
:1003D00070004C6840EA04032048824220D0B2F109 :1003D00070B501F000744FF0007595FAA5F5B5FA07
:1003E000804F1DD01E4882421AD01E48824217D02C :1003E00085F5EC4000F10C0505EB84031C6801F079
:1003F0001D48824214D01D48824211D01C488242BE :1003F000F8754FF0F87696FAA6F6B6FA86F6F54056
:100400000ED01C4882420BD01B48824208D01B48A9 :100400000726AE40B44301F0F8754FF0F87696FA3F
:10041000824205D01A48824202D01A48824204D150 :10041000A6F6B6FA86F6F54002FA05F52C431C60FE
:1004200023F44070CC6840EA040313608868D0620B :1004200070BD426822F440020A434260704742684D
:1004300000BF0888906200BF0848824202D00B4883 :1004300022F440020A4342607047000008B50549B3
:10044000824203D10869106300BF00BF00BF50693A :1004400009680143034A116011460968014000919F
:1004500040F00100506100BF002010BD00000140CD :1004500000BF08BD30380240F0B502460B4600240C
:100460000004004000080040000C0040000401406F :100460000021186890FAA0F0B0FA80F48AE0012523
:100470000040014000440140004801400018004095 :10047000A540186800EA050100297DD058680128C8
:10048000001C0040002000400146086900F0010007 :1004800002D0586802281CD19868956891FAA1F6A4
:100490007047000000B587B0182101A8FFF799FE4A :10049000B6FA86F677000326BE40B54391FAA1F678
:1004A0001020FFF7B9FE4FF48070FFF7B5FE04206F :1004A000B6FA86F6760000FA06F63543956000BF88
:1004B000FFF7B2FE2020FFF7AFFE8020FFF7ACFE73 :1004B000D86855688D4301FB00F63543556000BF91
:1004C0000120FFF7A9FE0220FFF7A6FE4020FFF75C :1004C00000BF1869D56891FAA1F6B6FA86F67700EA
:1004D000A3FE0820FFF7A0FE03203A49886100BF71 :1004D0000326BE40B54391FAA1F6B6FA86F6760039
:1004E0004FF6FC700190032002900020059001A9B6 :1004E00000FA06F63543D56000BF5868022831D1BE
:1004F0003448FFF79FFE40F6FF7001900320029002 :1004F00091FAA1F0B0FA80F0082814D25869156A70
:100500000020059001A93048FFF794FE43F6FF70E4 :1005000091FAA1F6B6FA86F6B7000F26BE40B543BB
:100510000190032002900020059001A92B48FFF7CD :1005100091FAA1F6B6FA86F6B60000FA06F6354369
:1005200089FE4FF6FF700190032002900020059095 :10052000156200BF16E05869556A0E0A96FAA6F6DB
:1005300001A92748FFF77EFE49F6FF7001900320CE :10053000B6FA86F6B7000F26BE40B5430E0A96FA05
:1005400002900020059001A92248FFF773FE4FF6A4 :10054000A6F6B6FA86F6B60000FA06F63543556208
:10055000FC700190032002900020059001A91E4824 :1005500000BF00BF5868156891FAA1F6B6FA86F692
:10056000FFF768FE4FF6FF70019003200290002015 :1005600077000326BE40B54391FAA1F6B6FA86F6A7
:10057000059001A91948FFF75DFE4FF6FF70019045 :10057000760000FA06F600E003E03543156000BFA0
:10058000032002900020059001A91548FFF752FEB4 :1005800000BF641C1868E04000287FF470AFF0BD25
:100590004FF6FF700190032002900020059001A902 :1005900010B5426921EA020302EA010443EA044376
:1005A0001048FFF747FE032001900120029002202F :1005A000836110BD02480068401C01490860704723
:1005B000039000200490059001A90248FFF73AFE3D :1005B000240000204FF47A71B0FBF1F2521E4FF08C
:1005C00007B000BD001002400020024000080240B9 :1005C000E0235A6100229A6105221A6100BF704738
:1005D0000014024000000240001C024000040240DF :1005D00001490860704700000000002010B5024685
:1005E00000180240000C02402DE9F04186B01421B1 :1005E00013682C4882420ED0B2F1804F0BD02A48BB
:1005F00001A8FFF7EEFD1020414909680143404A78 :1005F000824208D02948824205D02948824202D04E
:100600001160114609680140009100BF00BF36210A :100600002848824204D123F070004C6840EA040379
:100610003C4B1B68C3F30220062400250346C3F1AC :100610002048824220D0B2F1804F1DD01E48824235
:10062000070CBCF1040F02D94FF0040C01E0C3F138 :100620001AD01E48824217D01D48824214D01D485D
:10063000070C674603F1040CBCF1070F02D24FF020 :10063000824211D01C4882420ED01C4882420BD00C
:10064000000C01E0A3F1030C66464FF0010C0CFA1C :100640001B48824208D01B48824205D01A48824289
:1006500007FCACF1010C0CEA040C0CFA06FC4FF0A0 :1006500002D01A48824204D123F44070CC6840EAA8
:10066000010808FA06F8A8F1010808EA05084CEAAA :10066000040313608868D06200BF0888906200BFEE
:10067000080200BF002904DB1007030E2248435480 :100670000848824202D00B48824203D108691063C5
:1006800007E01007040E1F480C3001F00F031B1F7A :1006800000BF00BF00BF506940F00100506100BFD3
:10069000C45400BF3620002809DB00F01F020121EE :10069000002010BD000001400004004000080040A0
:1006A00091404209920002F1E022C2F8001100BF1D :1006A000000C0040000401400040014000440140B3
:1006B00044F29F10ADF804000020029063200390E4 :1006B0000048014000180040001C0040002000409D
:1006C00001A91248FFF76EFE00BF1048006820F035 :1006C0000146086900F00100704708B54FF0E021CD
:1006D00080000E49086000BF0020496821F07001C9 :1006D0000969009100BF411C01B1401C06E04FF0C8
:1006E00001430A4A516000BF00BF1046806820F0F5 :1006E000E021096901F4803101B1401E0028F6D1F2
:1006F00080001146886000BF06B0BDE8F0810000B0 :1006F00008BD00002DE9F0418EB000200B900C9059
:10070000403802400CED00E000E400E00010004042 :100700000D90142106A8FFF764FD002002900390CD
:1007100000BFFEE700BFFEE770477047704700006C :10071000049005904FF48070874909680143864A28
:1007200070B505204749096821F007010143454A92 :100720001160114609680140019100BF00BF834874
:10073000116000BF00BF00BF4248006800F0070022 :1007300000210A46824B5B5CC35823F0606313437D
:100740000528F8D14FF480403F49096821F48041E1 :100740007F4C645C035100BF00BF7D4B5B5CC358B2
:1007500001433D4A116000BF00BF3C48006840F4BF :1007500023F0C00313437A4C645C035100BF00BF15
:1007600080303A49086000BF00BF00BF37480068CA :10076000774B5B5CC35823F440331343744C645C95
:10077000C0F340400028F8D04FF480000421A822A4 :10077000035100BF8215724B5B5CC35823F4907326
:10078000002340EA010444EA8214304D2D1D2D68F7 :1007800013436F4C645C035100BF0A466C4B5B5CC7
:100790002F4E35402C432D4D2D1D2C602C462468AA :10079000C35823F400731343694C645C035100BFD6
:1007A00024F440341C432C6000BF00BF281F0068A5 :1007A0000215674B5B5CC35823F480631343644CAE
:1007B00040F08070291F086000BF00BF00BF2348C1 :1007B000645C035100BFC214614B5B5CC35823F4FB
:1007C0000068C0F340600028F8D000BF00BF1E489A :1007C000C05313435E4C645C035100BF92005C4B0A
:1007D0004068C0F380300028F8D000201B49083161 :1007D0005B5CC35823F4C0431343594C645C03511E
:1007E000096821F0F0010143184A0832116000BF86 :1007E00000BF00BF564A525C0244526922F0040224
:1007F0004FF4A0501146096821F4E0510143116003 :1007F000534B5B5C03445A6100BF1221514B1B6891
:1008000000BF4FF400401146096821F460410143E4 :10080000C3F30220002425460346C3F1070CBCF1C4
:10081000116000BF02201146096821F00301014365 :10081000040F02D94FF0040C01E0C3F1070C674646
:10082000116000BF00BF00BF08480830006800F03A :1008200003F1040CBCF1070F02D24FF0000C01E001
:100830000C000828F7D10748FFF7A0FD0548FFF78F :10083000A3F1030C66464FF0010C0CFA07FCACF177
:10084000ABFD70BD003C024000700040003802402B :10084000010C0CEA040C0CFA06FC4FF0010808FA43
:100850000080BFFF007A030A0348006840F470007C :1008500006F8A8F1010808EA05084CEA080200BFFA
:10086000014908607047000088ED00E010B5374886 :10086000002904DB1007030E3748435407E0100744
:10087000FFF70AFE012868D100BF00BF33480069B6 :10087000040E34480C3001F00F031B1FC45400BF9A
:10088000C0F3400060B100BF3048C068C0F3400012 :100880001220002809DB00F01F02012191404209DB
:1008900030B100BF6FF002002C49086100BF00BFFB :10089000920002F1E022C2F8001100BF00200B908C
:1008A00000BF2A480069C0F3800060B100BF27483C :1008A0000C904FF480700D900BA92848FFF720FDA5
:1008B000C068C0F3800030B100BF6FF0040023496E :1008B000002006904FF4801007900020089002203E
:1008C000086100BF00BF00BF20480069C0F3C0003E :1008C00009904FF440700A9006A92048FFF732FDC6
:1008D00060B100BF1D48C068C0F3C00030B100BFA8 :1008D00000201E49896821F4806101431B4A916010
:1008E0006FF008001949086100BF00BF00BF17483A :1008E00000BF4FF4803002900020039002A9184806
:1008F0000069C0F3001060B100BF1448C068C0F3C5 :1008F000FFF7C6FC174A4FF400711448FFF74CFD90
:10090000001030B100BF6FF010001049086100BF47 :10090000022214491148FFF763FD4FF4000110481B
:1009100000BF0E48FFF7B8FD01280CD100BF0B48FF :10091000FFF787FD104A910D0C48FFF73DFD0222BD
:10092000C06800F0010030B100BF6FF0010007495E :100920000D490A48FFF754FD4FF400010848FFF74E
:10093000086100BF00BF00BFFFF718FD00BF0448FB :1009300078FD0EB0BDE8F08144380240006402400A
:100940000068401C0249086000BF10BD0010004054 :10094000AC1800080CED00E000E400E000200140DD
:100950004000002000BFFEE702E008C8121F08C1E7 :100950000023014010002081110050812DE9F84151
:10096000002AFAD170477047002001E001C1121F30 :100960004FF480002E49096801432D4A1160114659
:10097000002AFBD170470000014601F1100000E0A1 :1009700009680140009100BF00BF3821294B1B6866
:10098000001D02681AB9024A12689042F8D37047F3 :10098000C3F30220002425460346C3F1070CBCF143
:100990001C00002010B50648046803E02046FFF75D :10099000040F02D94FF0040C01E0C3F1070C6746C5
:1009A000EBFF0446034800688442F7D310BD000003 :1009A00003F1040CBCF1070F02D24FF0000C01E080
:1009B000180000201C00002000200B4908600B4993 :1009B000A3F1030C66464FF0010C0CFA07FCACF1F6
:1009C000086000BF00BF0A48006840F00100084905 :1009C000010C0CEA040C0CFA06FC4FF0010808FAC2
:1009D000086000BF00BF0846C06840F00100C86062 :1009D00006F8A8F1010808EA05084CEA080200BF79
:1009E00000BF00BF70470000040000200C00002082 :1009E000002904DB1007030E0F48435407E01007EB
:1009F0000010004010B5034800F00AF8024800F06B :1009F000040E0C480C3001F00F031B1FC45400BF41
:100A000031F810BD040000200C00002070470000E9 :100A00003820002809DB00F01F0201219140420933
:100A100008B5014600200090086810B1112813D1D4 :100A1000920002F1E022C2F8001100BFBDE8F881A7
:100A200008E000BF00BF0B480068486000BF11200D :100A2000303802400CED00E000E400E000B587B093
:100A3000086000BF074A48681268101A0A2801D2E5 :100A3000182101A8FFF7CDFB1020FFF7FFFC4FF4B2
:100A4000002008BD00BFEDE70020086000900320F3 :100A40008070FFF7FBFC0420FFF7F8FC2020FFF785
:100A5000F7E70000400000200149086070470000EF :100A5000F5FC8020FFF7F2FC0120FFF7EFFC0220FD
:100A60004400002018B5014600200090086810B12D :100A6000FFF7ECFC4020FFF7E9FC0820FFF7E6FC6D
:100A700024281FD114E000BF0220114B5A6920EA3C :100A700003203A49886100BF4FF6FC7001900320C3
:100A8000020302EA000443EA04430D4CA36100BFE1 :100A800002900020059001A93448FFF7E5FC40F6EC
:100A900000BF0C480068486000BF2420086000BF09 :100A9000FF700190032002900020059001A93048CA
:100AA000084A48681268101A642801D2002018BD4C :100AA000FFF7DAFC43F6FF7001900320029000206C
:100AB00000BFE1E70020086000900320F7E7000096 :100AB000059001A92B48FFF7CFFC4FF6FF7001907E
:100AC000001002404000002008B54FF4804040492B :100AC000032002900020059001A92748FFF7C4FCED
:100AD000096801433E4A11601146096801400091CE :100AD00049F6FF700190032002900020059001A9C3
:100AE00000BF00BF8003111F09680143121F11607E :100AE0002248FFF7B9FC4FF6FC70019003200290FA
:100AF000114609680140009100BF00BF0320024673 :100AF0000020059001A91E48FFF7AEFC4FF6FF70DD
:100B0000344B19684FF6FF031940334B0B4343EA4C :100B00000190032002900020059001A91948FFF7E9
:100B10000221304B196000BF011F1B68C3F3022084 :100B1000A3FC4FF6FF700190032002900020059087
:100B20000F2400250346C3F1070CBCF1040F02D9C2 :100B200001A91548FFF798FC4FF6FF7001900320CC
:100B30004FF0040C01E0C3F1070C674603F1040C0D :100B300002900020059001A91048FFF78DFC0320CA
:100B4000BCF1070F02D24FF0000C01E0A3F1030C3F :100B40000190012002900220039000200490059063
:100B500066464FF0010C0CFA07FCACF1010C0CEAF4 :100B500001A90248FFF780FC07B000BD0010024069
:100B6000040C0CFA06FC4FF0010808FA06F8A8F18C :100B60000020024000080240001402400000024041
:100B7000010808EA05084CEA080200BF002904DB66 :100B7000001C02400004024000180240000C024029
:100B80001007030E1548435407E01007040E1148E0 :100B80002DE9F04186B0142101A8FFF722FB1020C7
:100B90000C3001F00F031B1FC45400BFFFF7C0FD52 :100B9000414909680143404A116011460968014012
:100BA0000F4800680F49B0FBF1F084B22046FFF710 :100BA000009100BF00BF36213C4B1B68C3F30220FD
:100BB00053FFFFF76FFCFFF717FD002000F014F85C :100BB000062400250346C3F1070CBCF1040F02D93B
:100BC000FFF724FFFFF7F8FE01E0FFF713FFFCE754 :100BC0004FF0040C01E0C3F1070C674603F1040C7D
:100BD000443802400CED00E00000FA0500E400E0BB :100BD000BCF1070F02D24FF0000C01E0A3F1030CAF
:100BE0000000002040420F0010B504460C4951F8A7 :100BE00066464FF0010C0CFA07FCACF1010C0CEA64
:100BF00024104A000B4951F82400002100F036F877 :100BF000040C0CFA06FC4FF0010808FA06F8A8F1FC
:100C0000094951F824200749083951F824000021E6 :100C0000010808EA05084CEA080200BF002904DBD5
:100C100000F02CF8012103480830015510BD0000F8 :100C10001007030E2248435407E01007040E1F4834
:100C2000980C000834000020A80C000810B50146FC :100C20000C3001F00F031B1FC45400BF36200028F6
:100C30000023002207E00B4850F8210030F8120092 :100C300009DB00F01F02012191404209920002F1FC
:100C400000B15B1C521C084850F821009042F2D8B9 :100C4000E022C2F8001100BF42F2CF00ADF804006C
:100C500064205843044C54F82140B0FBF4F0C0B277 :100C5000002002906320039001A91248FFF7BEFC18
:100C600010BD000034000020980C000830B5034689 :100C600000BF1048006820F080000E49086000BFF7
:100C700001E003F8011B141EA2F10102F9D130BDFD :100C70000020496821F0700101430A4A516000BF19
:100C80005F6C697374006C69737420616C6C2063B1 :100C800000BF1046806820F080001146886000BFD9
:100C90006F6D6D616E6400000002000000000000D6 :100C900006B0BDE8F0810000403802400CED00E0F5
:100CA0000800000008000000001000000000000024 :100CA00000E400E00010004000BFFEE700BFFEE7E8
:100CB000D00C00080000002068000000580900085F :100CB000704770477047000070B5052047490968C4
:100CC000380D0008680000201818000068090008A6 :100CC00021F007010143454A116000BF00BF00BF8A
:100CD0000024F400000000000000000000000000FC :100CD0004248006800F007000528F8D14FF4804032
:100CE0000000000000000000000000000000000004 :100CE0003F49096821F4804101433D4A116000BF3A
:100CF00000000000E90B00082D0C00088000002017 :100CF00000BF3C48006840F480303A49086000BFBB
:100D000020000020801000202200002000000000B1 :100D000000BF00BF37480068C0F340400028F8D05B
:100D100000000000000000000000000000000000D3 :100D10004FF480000421A822002340EA010444EAA1
:100D20000000000000000000800C0008860C000895 :100D20008214304D2D1D2D682F4E35402C432D4DF6
:080D3000C6E533B49509000883 :100D30002D1D2C602C46246824F440341C432C6068
:100D400000BF00BF281F006840F08070291F0860A6
:100D500000BF00BF00BF23480068C0F34060002808
:100D6000F8D000BF00BF1E484068C0F380300028A4
:100D7000F8D000201B490831096821F0F001014337
:100D8000184A0832116000BF4FF4A050114609689C
:100D900021F4E0510143116000BF4FF400401146BF
:100DA000096821F460410143116000BF022011462F
:100DB000096821F003010143116000BF00BF00BFBB
:100DC00008480830006800F00C000828F7D10748F0
:100DD000FFF7F0FB0548FFF7FBFB70BD003C02404E
:100DE00000700040003802400080BFFF007A030A14
:100DF0000348006840F47000014908607047000033
:100E000088ED00E010B53748FFF75AFC012868D19B
:100E100000BF00BF33480069C0F3400060B100BFAD
:100E20003048C068C0F3400030B100BF6FF002002E
:100E30002C49086100BF00BF00BF2A480069C0F309
:100E4000800060B100BF2748C068C0F3800030B1A7
:100E500000BF6FF004002349086100BF00BF00BF5E
:100E600020480069C0F3C00060B100BF1D48C068E1
:100E7000C0F3C00030B100BF6FF00800194908612D
:100E800000BF00BF00BF17480069C0F3001060B189
:100E900000BF1448C068C0F3001030B100BF6FF04D
:100EA00010001049086100BF00BF0E48FFF708FCA2
:100EB00001280CD100BF0B48C06800F0010030B120
:100EC00000BF6FF001000749086100BF00BF00BF0D
:100ED000FFF768FB00BF04480068401C0249086037
:100EE00000BF10BD001000405800002000BFFEE70A
:100EF00002E008C8121F08C1002AFAD170477047E3
:100F0000002001E001C1121F002AFBD17047000040
:100F1000014601F1100000E0001D02681AB9024A02
:100F200012689042F8D370473800002010B5064888
:100F3000046803E02046FFF7EBFF0446034800681F
:100F40008442F7D310BD0000340000203800002098
:100F500010B501E000F8011B131EA2F10104A2B2BA
:100F6000F8D110BD70B5054605EBC500114901EB80
:100F700080040CB1012100E00021084640F2291153
:100F8000FFF768F960680168C1F3C02129B16068A2
:100F90004FF40061816000BF00BF60680168C1F369
:100FA000402129B160684FF40071816000BF00BF2B
:100FB00070BD000080E1002070B5054605EBC5005E
:100FC0000D4901EB80040CB1012100E0002108462D
:100FD0004FF49F71FFF73EF920680168C1F340119B
:100FE00041B16069401C606120686FF020010160C0
:100FF00000BF00BF70BD000080E10020014600205E
:1010000001F001020AB1421CD0B201F002020AB1A1
:10101000421CD0B201F004020AB1421CD0B201F06D
:1010200008020AB1421CD0B201F010020AB1421CFF
:10103000D0B201F020020AB1421CD0B201F040024D
:101040000AB1421CD0B201F080020AB1421CD0B2F7
:1010500001F480720AB1421CD0B201F400720AB1EC
:10106000421CD0B201F480620AB1421CD0B201F439
:1010700000620AB1421CD0B201F480520AB1421C93
:10108000D0B201F400520AB1421CD0B201F4804245
:101090000AB1421CD0B201F400420AB1421CD0B2E3
:1010A00001F480320AB1421CD0B201F400220AB12C
:1010B000421CD0B201F480220AB1421CD0B201F429
:1010C00000320AB1421CD0B2704700002DE9FF4F38
:1010D00081B006460F469046DDE90F95032E01DAF2
:1010E000012100E0002108461C21FFF7B3F80FB1F1
:1010F000012100E0002108461D21FFF7ABF8B8F1FF
:10110000000F01D0012100E0002108461E21FFF759
:10111000A1F8B9F1000F01DD012100E0002108462E
:101120001F21FFF797F806EBC600744901EB800416
:10113000242200212046FFF70BFF2760C4F804801B
:101140000498A0600E98E0602561A4F818902846E5
:10115000FFF754FFA076A07E00FB09F0A083A08BD0
:101160004FEA400A5146012000F060FB2062216AEC
:1011700009B1012100E0002108463221FFF76AF899
:10118000A18B49040A0C0021206AFFF7E1FE201D13
:1011900007C85B4B5B5CC35823F060631343DFF805
:1011A00060C11CF801C040F80C3000BF554AD4E9BA
:1011B0000101534B5B5CC358DFF84CC103EA0C03DD
:1011C0001343DFF83CC11CF801C040F80C3000BFED
:1011D0004FF0000BD4E900A0A1684FF0000ECDF84D
:1011E00000E0BBF1000F04D10AF14C0ECDF800E095
:1011F00003E0DFF818E1CDF800E0009AD4E901AB94
:10120000236ADFF8FCE01EF80BE05AF80EE00EF05F
:10121000C00C00BFBCF1400F0ED1DFF8E4A01AF8FB
:1012200001A08244CAF80C20DFF8D4A01AF801A06B
:101230008244CAF808300DE0DFF8C4A01AF801A013
:101240008244CAF80820DFF8B8A01AF801A0824446
:10125000CAF80C3000BFA28BD4E90101284B5B5CBB
:1012600003445B686FF30F031343DFF894C01CF86B
:1012700001C08444CCF8043000BFD4E90101204A05
:10128000525C825842F001021D4B5B5CC25000BFB1
:1012900002212068826822F002020A43826000BFB5
:1012A0004FF440712068826822F440720A438260E1
:1012B00000BF05F4002028B14FF40001134808389E
:1012C000FFF7B5F805F4003028B14FF400010F48DE
:1012D0000838FFF7ACF80A20FFF7F7F920688168B3
:1012E00041F00101816000BF2068816841F08041C8
:1012F000816000BF05B0BDE8F08F000080E10020F4
:1013000008190008002D02001F80FCFF082301407F
:101310002DE9F04705468846032D01DA012100E05A
:1013200000210846EE21FEF795FF4FF00009002648
:1013300005EBC500104901EB80040CB1012100E070
:1013400000210846F221FEF785FF206A00EB4807DE
:10135000002006E039880E44411C88B2A17E07EBCC
:101360004107218B8142F5DC208BB6FBF0F01FFAA0
:1013700080F94846BDE8F08780E100200C4B1988D1
:101380009B1C1A88431A00EE903AF8EEE01A531AA2
:1013900000EE903AF8EEE00A81EEA01ADFED051AB1
:1013A000F3EE0E0A41EE210AB0EE600A704700002B
:1013B0002C7AFF1F0000A0420E49098840F6E44243
:1013C000514340F6FF72B1FBF2F100EE101AB8EE95
:1013D000400AF0EE400A00EE100AB8EE400A80EE35
:1013E000801A9FED050A21EE001ADFED041A81EE46
:1013F000210A70472A7AFF1F00F07F4500007A44D7
:1014000000200B4908600B49086000BF00BF0A4874
:10141000006840F001000849086000BF00BF0846AE
:10142000C06840F00100C86000BF00BF7047000006
:1014300008000020100000200010004010B50348F4
:1014400000F01CF8024800F087F810BD08000020EA
:10145000100000200EB54FF420204FF4C871002278
:101460001346CDE900210290024A03490020FFF70C
:101470002DFE0EBD006402400020014038B5044638
:1014800000200090206810B112281DD112E000BF8A
:1014900000F02AF80F4880ED000A00F041F80D48EE
:1014A00080ED010A00BF0C480068606000BF122098
:1014B000206000BF084960680968081A642801D2E2
:1014C000002038BD00BFE3E700202060009003202B
:1014D000F7E70000180000205800002001490860CC
:1014E000704700002000002010B52DED028B9FED0D
:1014F0000A0AB0EE408A00210846FFF709FF0749B3
:1015000008800888FFF73AFFB0EE408AB0EE480A3C
:10151000BDEC028B10BD00000000000004000020A4
:1015200010B52DED028B9FED0A0AB0EE408A012125
:101530000020FFF7EDFE074948804888FFF73CFF91
:10154000B0EE408AB0EE480ABDEC028B10BD000040
:10155000000000000400002038B504460020009080
:10156000206810B1252816D10BE000BF012000F043
:1015700019F800BF0A480068606000BF252020609D
:1015800000BF074960680968081A642801D2002072
:1015900038BD00BFEAE70020206000900320F7E795
:1015A0005800002010B5044614B1012C0AD104E003
:1015B00001210648FEF7ECFF05E002210348FEF793
:1015C000E7FF00E000BF00BF10BD000000100240B8
:1015D00008B54FF48040444909680143424A11600C
:1015E000114609680140009100BF00BF8003111F30
:1015F00009680143121F11601146096801400091FA
:1016000000BF00BF03200246384B19684FF6FF03A6
:101610001940374B0B4343EA0221344B196000BF9A
:10162000011F1B68C3F302200F2400250346C3F1EA
:10163000070CBCF1040F02D94FF0040C01E0C3F118
:10164000070C674603F1040CBCF1070F02D24FF000
:10165000000C01E0A3F1030C66464FF0010C0CFAFC
:1016600007FCACF1010C0CEA040C0CFA06FC4FF080
:10167000010808FA06F8A8F1010808EA05084CEA8A
:10168000080200BF002904DB1007030E1948435469
:1016900007E01007040E15480C3001F00F031B1F64
:1016A000C45400BFFFF708FB134800681349B0FBA0
:1016B000F1F084B22046FFF711FFFFF7B7F9FFF70B
:1016C0004DF9FFF75DFAFFF715F8002000F018F864
:1016D000012000F015F8FFF7BDFEFFF791FE01E0D5
:1016E000FFF7ACFEFCE70000443802400CED00E0E0
:1016F0000000FA0500E400E00000002040420F0076
:1017000010B504460C4951F824104A000B4951F811
:101710002400002100F09EF8094951F824200749CF
:10172000083951F82400002100F094F80121034801
:101730000830015510BD0000F01800084C000020D2
:10174000001900082DE9F04704460F460025A94678
:101750002348005D20B92248183801682046884790
:101760001FB94FF0FF30BDE8F0871E4850F8240045
:10177000B7FBF0F61B4850F82400B7FBF0F100FB74
:10178000117000B1761C184850F82400451E22E064
:101790001348083850F8240030F8150010B909F142
:1017A000010901E04FF00009B14513D14FF00008E5
:1017B00009E00B48083850F8240005EB080220F82F
:1017C000126008F10108B045F3D3064850F8240030
:1017D0006843C8E76D1E002DDADA4FF0FF30C2E72C
:1017E00054000020F8180008F018000810B5014651
:1017F0000023002207E00B4850F8210030F81200C7
:1018000000B15B1C521C084850F821009042F2D8ED
:1018100064205843044C54F82140B0FBF4F0C0B2AB
:1018200010BD00004C000020F018000870B5044600
:101830000E4631462046FFF785FF0546681C08B96D
:10184000002070BD024850F824002844F9E7000049
:101850004400002030B5034601E003F8011B141ECC
:10186000A2F10102F9D130BD00BF00BF00BF00BF2F
:1018700000BFBFF34F8F00BF00BF00BF0948006823
:1018800000F4E06008490843001D0649086000BFF5
:1018900000BF00BFBFF34F8F00BF00BF00BF00BF3E
:1018A00000BFFDE70CED00E00000FA0510284058ED
:1018B0007088A0B8000000000404040000080000C4
:1018C00000080000080000000800020406080A0CD6
:1018D000000102030405065F6C697374006C697390
:1018E0007420616C6C20636F6D6D616E640000002C
:1018F000800C0000000A0000080000000800000042
:101900000064000000500000102840587088A0B803
:1019100000000000040404000008000000080000AB
:10192000080000000800020406080A0C0001020377
:101930000405060054190008000000207050000043
:101940000C020008241A0008705000208095000046
:10195000000F0008043A0024F43E01170008ED17B8
:10196000000880500020600AFF2080B4002080CD55
:10197000002001FF01FF01FF01FF01FF01FF01FF47
:1019800001FF01FF01FF01FF01FF01FF01FF01FF57
:1019900001FF01FF01FF01FF01FF01FF01FF01FF47
:1019A00001FF01FF01FF01FF01FF01FF01FF01FF37
:1019B00001FF01FF01FF01FF01FF01FF01FF01FF27
:1019C00001FF01FF01FF01FF01FF01FF01FF01FF17
:1019D00001FF01FF01FF01FF01FF01FF01FF01FF07
:1019E00001FF01FF01FF01FF01FF01FF01FF01FFF7
:1019F00001FF01FF01FF01FF01FF01FF01FF01FFE7
:101A000001FF01FF01FF01FF01FF01FF01FF01FFD6
:101A100001AD2FD7180008DD180008C6E533B42D36
:041A20000F12080099
:040000050800018965 :040000050800018965
:00000001FF :00000001FF

Binary file not shown.

Binary file not shown.

107
Src/adc.c Normal file
View File

@ -0,0 +1,107 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc.c
* @brief This file provides code for the configuration
* of the ADC 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 "adc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* ADC1 init function */
void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
/* Peripheral clock enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);
/* ADC1 DMA Init */
/* ADC1 Init */
LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_0, LL_DMA_CHANNEL_0);
LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_0, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_0, LL_DMA_PRIORITY_LOW);
LL_DMA_SetMode(DMA2, LL_DMA_STREAM_0, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_0, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_0, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_0, LL_DMA_MDATAALIGN_HALFWORD);
LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_0);
/* ADC1 interrupt Init */
NVIC_SetPriority(ADC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(ADC_IRQn);
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
ADC_InitStruct.SequencersScanMode = LL_ADC_SEQ_SCAN_ENABLE;
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_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;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
LL_ADC_REG_SetFlagEndOfConversion(ADC1, LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV);
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV4;
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_TEMPSENSOR);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_TEMPSENSOR, LL_ADC_SAMPLINGTIME_28CYCLES);
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_TEMPSENSOR);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_VREFINT);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_VREFINT, LL_ADC_SAMPLINGTIME_28CYCLES);
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_VREFINT);
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

56
Src/dma.c Normal file
View File

@ -0,0 +1,56 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.c
* @brief This file provides code for the configuration
* of all the requested memory to memory DMA transfers.
******************************************************************************
* @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 "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure DMA */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{
/* Init with LL driver */
/* DMA controller clock enable */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
/* DMA interrupt init */
/* DMA2_Stream0_IRQn interrupt configuration */
NVIC_SetPriority(DMA2_Stream0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */

View File

@ -18,6 +18,8 @@
/* USER CODE END Header */ /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "main.h" #include "main.h"
#include "adc.h"
#include "dma.h"
#include "tim.h" #include "tim.h"
#include "gpio.h" #include "gpio.h"
@ -94,9 +96,12 @@ int main(void)
/* Initialize all configured peripherals */ /* Initialize all configured peripherals */
MX_GPIO_Init(); MX_GPIO_Init();
MX_DMA_Init();
MX_TIM6_Init(); MX_TIM6_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
my_mem_init(SRAMIN); // Initialize internal memory pool 1 my_mem_init(SRAMIN); // Initialize internal memory pool 1
my_mem_init(SRAMEX); // Initialize external memory pool 2
board_init(); board_init();
app_init(); app_init();
/* USER CODE END 2 */ /* USER CODE END 2 */

View File

@ -202,6 +202,20 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f4xx.s). */ /* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/ /******************************************************************************/
/**
* @brief This function handles ADC1, ADC2 and ADC3 global interrupts.
*/
void ADC_IRQHandler(void)
{
/* USER CODE BEGIN ADC_IRQn 0 */
/* USER CODE END ADC_IRQn 0 */
/* USER CODE BEGIN ADC_IRQn 1 */
adc_env_callback(ADCS_1);
/* USER CODE END ADC_IRQn 1 */
}
/** /**
* @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts. * @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
*/ */
@ -221,6 +235,20 @@ void TIM6_DAC_IRQHandler(void)
/* USER CODE END TIM6_DAC_IRQn 1 */ /* USER CODE END TIM6_DAC_IRQn 1 */
} }
/**
* @brief This function handles DMA2 stream0 global interrupt.
*/
void DMA2_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
/* USER CODE END DMA2_Stream0_IRQn 0 */
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
adc_dma_callback(ADCS_1);
/* USER CODE END DMA2_Stream0_IRQn 1 */
}
/* USER CODE BEGIN 1 */ /* USER CODE BEGIN 1 */
/* USER CODE END 1 */ /* USER CODE END 1 */

View File

@ -44,7 +44,7 @@ void MX_TIM6_Init(void)
/* USER CODE BEGIN TIM6_Init 1 */ /* USER CODE BEGIN TIM6_Init 1 */
/* USER CODE END TIM6_Init 1 */ /* USER CODE END TIM6_Init 1 */
TIM_InitStruct.Prescaler = 16799; TIM_InitStruct.Prescaler = 8399;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 99; TIM_InitStruct.Autoreload = 99;
LL_TIM_Init(TIM6, &TIM_InitStruct); LL_TIM_Init(TIM6, &TIM_InitStruct);

View File

@ -13,8 +13,9 @@ static uint8_t business_inspection(struct flow *fl)
FL_HEAD(fl); FL_HEAD(fl);
for (;;) for (;;)
{ {
app.cpu_temperature = get_cpu_temperature();
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); app.cpu_volt = get_cpu_voltage();
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
} }
FL_TAIL(fl); FL_TAIL(fl);
} }

View File

@ -11,7 +11,8 @@
typedef struct typedef struct
{ {
float32 cpu_temperature;
float32 cpu_volt;
} app_t; } app_t;
extern app_t app; extern app_t app;

View File

@ -1,281 +1,13 @@
#include "work.h" #include "work.h"
#include "board.h" #include "board.h"
#define OUTPUT_INFORMATION_CYCLE_BASE 100
#define DISTANCE 1000
#define SPEED 80
#define TARGET_POS 500
#define TARGET_SPEED 20
work_t work;
/**
* @brief
*
*
*/
static void output_information(void)
{
char data[128];
uint8_t len = 0;
int32_t rst = 0;
osel_memset((uint8_t *)data, 0, ARRAY_LEN(data));
if (work.type == WORK_MOTOR_POS)
{
rst = snprintf(data, ARRAY_LEN(data), "%d,%d,%f\r\n", work.target_pos, work.encoder_cnt, work.pwm_percent);
}
else if (work.type == WORK_MOTOR_SPEED)
{
rst = snprintf(data, ARRAY_LEN(data), "%d,%d,%f\r\n", work.target_speed, work.encoder_show, work.pwm_percent);
}
else
{
return;
}
if (rst == 0 || rst > ARRAY_LEN(data))
{
return;
}
len = osel_mstrlen((uint8_t *)data);
uart_send((uint8_t *)data, len);
}
static void pwm_map(void)
{
set_motor_pwm(work.pwm_percent);
}
static void pwm_s_curve(void)
{
}
static void motor_pos(void)
{
int32_t code = work.encoder_cnt;
work.pwm_percent = work.pid.pid_u.fuzzy.execute(&work.pid.pid_u.fuzzy, work.target_pos, code);
set_motor_pwm(work.pwm_percent);
}
static void motor_speed(void)
{
int32_t code = work.encoder_cnt;
work.target_speed_filter = lpf_update(&work.target_speed_lpf, work.target_speed);
work.encoder_show = lpf_update(&work.encoder_lpf, work.encoder_cnt);
work.encoder_cnt = 0;
work.pwm_percent = work.pid.pid_u.fuzzy.execute(&work.pid.pid_u.fuzzy, work.target_speed_filter + 1, code); // 补偿1
set_motor_pwm(work.pwm_percent);
}
static void pwm_map_key_handle(button_id_e id)
{
int8_t min = -100, max = 100;
int8_t step = 10;
switch (id)
{
case KEY_ADD:
if (work.pwm_percent < max)
{
work.pwm_percent += step;
}
break;
case KEY_SUB:
if (work.pwm_percent > min)
{
work.pwm_percent -= step;
}
break;
case KEY_S:
work.pwm_percent = 10;
work.encoder_cnt = 0;
break;
default:
break;
}
}
static void motot_pos_key_handle(button_id_e id)
{
int16_t min = 0, max = DISTANCE;
int16_t step = 100;
switch (id)
{
case KEY_ADD:
if (work.target_pos < max)
{
work.target_pos += step;
}
break;
case KEY_SUB:
if (work.target_pos > min)
{
work.target_pos -= step;
}
break;
case KEY_S:
work.target_pos = TARGET_POS;
break;
default:
break;
}
}
static void motor_speed_key_handle(button_id_e id)
{
int16_t min = TARGET_SPEED, max = SPEED;
int16_t step = 5;
switch (id)
{
case KEY_ADD:
if (work.target_speed < max)
{
work.target_speed += step;
}
break;
case KEY_SUB:
if (work.target_speed > min)
{
work.target_speed -= step;
}
break;
case KEY_S:
work.target_speed = TARGET_SPEED;
break;
default:
break;
}
}
void work_key_handle_cb(button_id_e id)
{
switch (work.type)
{
case WORK_PWM_MAP:
pwm_map_key_handle(id);
break;
case WORK_MOTOR_POS:
motot_pos_key_handle(id);
break;
case WORK_MOTOR_SPEED:
motor_speed_key_handle(id);
break;
default:
DBG_ASSERT(FALSE __DBG_LINE);
break;
}
}
static void work_data_update(void)
{
work.pid.pid_u.fuzzy.set_kp(&work.pid.pid_u.fuzzy, work.pid_params.kp);
work.pid.pid_u.fuzzy.set_ki(&work.pid.pid_u.fuzzy, work.pid_params.ki);
work.pid.pid_u.fuzzy.set_kd(&work.pid.pid_u.fuzzy, work.pid_params.kd);
}
void work_process(void) void work_process(void)
{ {
switch (work.type)
{
case WORK_PWM_MAP:
pwm_map();
break;
case WORK_MOTOR_POS:
motor_pos();
break;
case WORK_MOTOR_SPEED:
motor_speed();
break;
case WORK_S_CURVE:
pwm_s_curve();
break;
default:
break;
}
if (work.enter_cnt++ % (OUTPUT_INFORMATION_CYCLE_BASE / work.timer_cycle) == 0)
{
output_information();
}
work_data_update();
}
void work_encoder_exti(void)
{
if (GPIO_READ(MOTOR_B_GPIO_Port, MOTOR_B_Pin) == 1)
{
work.encoder_cnt++;
}
else
{
work.encoder_cnt--;
}
} }
void work_init(void) void work_init(void)
{ {
osel_memset((uint8_t *)&work, 0, sizeof(work_t)); osel_memset((uint8_t *)&work, 0, sizeof(work_t));
PWM_START(PWM_TIM, PWM_CHANNEL);
PWM_SET_DUTY(PWM_TIM, PWM_CHANNEL, 0);
work.pwm_feq = PWM_GET_FREQ(PWM_TIM);
work.pwm_arr = PWM_GET_ARR(PWM_TIM);
work.type = WORK_PWM_MAP;
// PID初始化
{
work.pid.type = PID_TYPE_FUZZY;
work.pid.pid_u.fuzzy.deadzone_dir = DEAD_ZONE_BOTH;
work.pid_params.dead_zone = 1;
if (work.type == WORK_MOTOR_POS)
{
work.pid_params.kp = 1;
work.pid_params.ki = 0.01f;
work.pid_params.kd = 10;
work.pid.sub_type = PID_SUB_TYPE_POSITION;
}
else
{
work.pid_params.kp = 0.01;
work.pid_params.ki = 0.1f;
work.pid_params.kd = 0;
work.pid.sub_type = PID_SUB_TYPE_INCREMENT;
}
pid_constructor(&work.pid);
if (work.type == WORK_MOTOR_POS)
{
work.pid.pid_u.fuzzy.set_ctrl_prm(&work.pid.pid_u.fuzzy, work.pid_params.kp, work.pid_params.ki,
work.pid_params.kd, work.pid_params.dead_zone, 0, -90, 90); // 电机输出不要超过90
work.pid.pid_u.fuzzy.set_kd_enable(&work.pid.pid_u.fuzzy, TRUE);
work.position = &work.pid.pid_u.fuzzy.pri_u.position;
}
else
{
work.pid.pid_u.fuzzy.set_ctrl_prm(&work.pid.pid_u.fuzzy, work.pid_params.kp, work.pid_params.ki,
work.pid_params.kd, work.pid_params.dead_zone, 0, -1 * ((int32_t)SPEED), SPEED);
work.pid.pid_u.fuzzy.set_kd_enable(&work.pid.pid_u.fuzzy, FALSE);
work.increment = &work.pid.pid_u.fuzzy.pri_u.increment;
work.encoder_lpf.alpha = work.pid_params.ki * 1.5f;
lpf_init(&work.encoder_lpf);
work.target_speed_lpf.alpha = work.pid_params.ki * 1.5f;
lpf_init(&work.target_speed_lpf);
// 改变定时器周期
uint16_t arr = LL_TIM_GetAutoReload(WORK_TIM);
LL_TIM_SetAutoReload(WORK_TIM, arr * 10 - 1);
}
}
work.target_pos = TARGET_POS;
work.target_speed = TARGET_SPEED;
work.timer_cycle = TIM_CYCLE(WORK_TIM);
if (work.type == WORK_PWM_MAP)
{
work.pwm_percent = 10;
}
return; return;
} }

View File

@ -7,47 +7,17 @@
#include "filter.h" #include "filter.h"
typedef enum typedef enum
{ {
// PWM占空比映射到电机
WORK_PWM_MAP = 0,
// 电机位置控制
WORK_MOTOR_POS = 1,
// 电机速度控制
WORK_MOTOR_SPEED = 2,
// S曲线
WORK_S_CURVE = 3,
} work_e; } work_e;
typedef struct typedef struct
{ {
work_e type; work_e type;
uint8_t timer_cycle; // 定时器周期
uint32_t enter_cnt; // 进入次数
int32_t encoder_cnt; // 编码器位置
int32_t encoder_show; // 滤波后的编码器位置
float32 pwm_percent; // PWM占空比
uint32_t pwm_feq; // PWM频率
uint16_t pwm_arr; // PWM自动重装载值
pid_t pid;
pid_common_position_t *position;
pid_common_increment_t *increment;
struct
{
float32 kp;
float32 ki;
float32 kd;
float32 dead_zone;
} pid_params;
int32_t target_pos; // 目标位置
int32_t target_speed; // 目标速度
int32_t target_speed_filter;
lpf_t encoder_lpf;
lpf_t target_speed_lpf;
} work_t; } work_t;
extern work_t work; extern work_t work;
void work_init(void); void work_init(void);
void work_process(void); void work_process(void);
void work_key_handle_cb(button_id_e id);
void work_encoder_exti(void);
#endif // __WORK_H__ #endif // __WORK_H__

View File

@ -1,5 +1,7 @@
#include "board.h" #include "board.h"
board_t board;
void led_open(led_e led) void led_open(led_e led)
{ {
switch (led) switch (led)
@ -51,4 +53,32 @@ void led_toggle(led_e led)
*/ */
void board_init(void) void board_init(void)
{ {
adc_init(ADCS_1, ADC1, DMA2, LL_DMA_STREAM_0, LL_DMA_CHANNEL_0, 400,
INTEMP | INVREF); // 初始化ADC1通道默认采集AD
}
/**
* @brief CPU温度
* @return {float32} CPU温度
* @note
*/
float32 get_cpu_temperature(void)
{
float32 tmp = 0.0f;
board.adc_raw[ADC_TEMP_CHANNEL] = adc_result_average(ADCS_1, ADC_TEMP_CHANNEL);
tmp = adc_result_temperature(board.adc_raw[ADC_TEMP_CHANNEL]);
return tmp;
}
/**
* @brief CPU电压
* @return {float32} CPU电压
* @note
*/
float32 get_cpu_voltage(void)
{
float32 tmp = 0.0f;
board.adc_raw[ADC_INVREF_CHANNEL] = adc_result_average(ADCS_1, ADC_INVREF_CHANNEL);
tmp = adc_result_value_local(board.adc_raw[ADC_INVREF_CHANNEL]);
return tmp;
} }

View File

@ -13,9 +13,29 @@ typedef enum
LED_GREEN, LED_GREEN,
} led_e; } led_e;
/**
* ADC通道定义: 48 TCONV() = ( + 12.5 )/(/ADC分频系数)
*/
typedef enum
{
ADC_TEMP_CHANNEL, ///< 内部参考温度
ADC_INVREF_CHANNEL, ///< 内部参考电压
ADC1_MAX, ///< ADC1通道最大数量
} adc1_channel_e;
typedef struct
{
uint16_t adc_raw[ADC1_MAX];
} board_t;
extern board_t board;
void board_init(void); void board_init(void);
void led_open(led_e led); void led_open(led_e led);
void led_close(led_e led); void led_close(led_e led);
void led_toggle(led_e led); void led_toggle(led_e led);
float32 get_cpu_temperature(void);
float32 get_cpu_voltage(void);
#endif #endif

View File

@ -1,737 +0,0 @@
/**
* @file ssd1306_oled.c
* @author xushenghao
* @brief SSD1306 OLED display driver
* @version 0.1
* @note PB13-SCK PB12-SDA
*/
#include "ssd1306_oled.h"
#include "ssd1306_oled.h"
/************************************6*8的点阵************************************/
const uint8_t F6x8[][6] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // horiz lines
};
/****************************************8*16的点阵************************************/
const uint8_t F8X16[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 1
0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 2
0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 3
0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 4
0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 5
0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 6
0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 7
0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 8
0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 9
0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 10
0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 11
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 12
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 13
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 14
0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 15
0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16
0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17
0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18
0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19
0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20
0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21
0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22
0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23
0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24
0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25
0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 26
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 27
0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 28
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 29
0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 30
0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 31
0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 32
0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33
0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34
0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35
0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36
0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37
0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38
0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39
0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40
0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41
0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42
0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43
0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44
0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45
0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46
0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47
0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48
0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49
0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50
0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51
0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52
0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53
0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54
0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55
0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56
0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57
0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58
0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 59
0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 60
0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 61
0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 62
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 63
0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 64
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65
0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67
0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71
0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72
0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73
0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74
0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75
0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77
0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79
0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81
0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83
0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84
0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85
0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86
0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87
0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88
0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90
0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 91
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 92
0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 93
0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
};
static uint8_t _buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8]; // 定义屏幕缓冲区
static void i2c_start(void)
{
SDA_OUT();
GPIO_SET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
GPIO_SET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
delay_us(4);
GPIO_RESET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
delay_us(4);
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
}
static void i2c_stop(void)
{
SDA_OUT();
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
GPIO_RESET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
delay_us(4);
GPIO_SET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
GPIO_SET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
delay_us(4);
}
static BOOL i2c_wait_ack(void)
{
uint8_t count = 0;
SDA_IN();
GPIO_SET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
delay_us(4);
GPIO_SET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
delay_us(4);
while (GPIO_READ(SSD1306_SDA_PORT, SSD1306_SDA_PIN))
{
count++;
if (count > 250)
{
i2c_stop();
return FALSE;
}
}
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
return TRUE;
}
static void i2c_ack(void)
{
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
SDA_OUT();
GPIO_RESET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
delay_us(2);
GPIO_SET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
delay_us(2);
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
}
static void i2c_nack(void)
{
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
SDA_OUT();
GPIO_SET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
delay_us(2);
GPIO_SET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
delay_us(2);
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
}
uint8_t i2c_read_byte(BOOL ack)
{
uint8_t i = 0, receive = 0;
SDA_IN();
for (i = 0; i < 8; i++)
{
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
delay_us(2);
GPIO_SET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
receive <<= 1;
if (GPIO_READ(SSD1306_SDA_PORT, SSD1306_SDA_PIN))
{
receive++;
}
delay_us(1);
}
if (!ack)
{
i2c_nack();
}
else
{
i2c_ack();
}
return receive;
}
void i2c_write_byte(uint8_t data)
{
uint8_t i = 0;
SDA_OUT();
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
for (i = 0; i < 8; i++)
{
// IIC_SDA=(txd&0x80)>>7;
if ((data & 0x80) >> 7)
GPIO_SET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
else
GPIO_RESET(SSD1306_SDA_PORT, SSD1306_SDA_PIN);
data <<= 1;
delay_us(2);
GPIO_SET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
delay_us(2);
GPIO_RESET(SSD1306_SCK_PORT, SSD1306_SCK_PIN);
delay_us(2);
}
}
static void i2c_write_command(uint8_t command)
{
uint8_t dd[2];
dd[0] = SSD1306_CMD_SET_LOW_COLUMN; // Co = 0, D/C# = 0
dd[1] = command;
i2c_start();
i2c_write_byte(SSD1306_I2C_ADDRESS);
i2c_wait_ack();
i2c_write_byte(dd[0]);
i2c_wait_ack();
i2c_write_byte(dd[1]);
i2c_wait_ack();
i2c_stop();
}
static void i2c_write_data(uint8_t data)
{
uint8_t dd[2];
dd[0] = SSD1306_CMD_SET_START_LINE; // Co = 0, D/C# = 1
dd[1] = data;
i2c_start();
i2c_write_byte(SSD1306_I2C_ADDRESS);
i2c_wait_ack();
i2c_write_byte(dd[0]);
i2c_wait_ack();
i2c_write_byte(dd[1]);
i2c_wait_ack();
}
/**
* @brief SSD1306 OLED显示屏上的显示位置
*
* SSD1306 OLED显示屏上的显示位置x和y坐标确定显示位置
*
* @param x 0-127
* @param y 0-7SSD1306 OLED的8个页面
*/
void set_position(uint8_t x, uint8_t y)
{
i2c_write_command(0xb0 + y);
i2c_write_command(((x & 0xf0) >> 4) | 0x10);
i2c_write_command((x & 0x0f) | 0x01);
}
void ssd1306_test(void)
{
ssd1306_f8x16_string(0, 0, " TEST");
ssd1306_f8x16_number(40, 0, -15.26, 2);
ssd1306_f6x8_string_number(0, 3, " @ADC1:", 'V', 24);
ssd1306_update_screen();
}
void ssd1306_init(void)
{
i2c_write_command(SSD1306_CMD_DISPLAY_OFF); // display off
i2c_write_command(SSD1306_CMD_MEMORY_MODE); // Set Memory Addressing Mode
i2c_write_command(SSD1306_CMD_SET_HIGH_COLUMN); // 00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
i2c_write_command(SSD1306_CMD_COM_SCAN_DEC); // Set COM Output Scan Direction
i2c_write_command(SSD1306_CMD_SET_LOW_COLUMN); //---set low column address
i2c_write_command(SSD1306_CMD_SET_HIGH_COLUMN); //---set high column address
i2c_write_command(SSD1306_CMD_SET_START_LINE); //--set start line address
i2c_write_command(SSD1306_CMD_SET_CONTRAST); //--set contrast control register
i2c_write_command(0xff); // 亮度调节 0x00~0xff
i2c_write_command(0xa1); //--set segment re-map 0 to 127
i2c_write_command(SSD1306_CMD_NORMAL_DISPLAY); //--set normal display
i2c_write_command(SSD1306_CMD_SET_MULTIPLEX); //--set multiplex ratio(1 to 64)
i2c_write_command(0x3f); //
i2c_write_command(SSD1306_CMD_DISPLAY_ALL_ON_RESUME); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content
i2c_write_command(SSD1306_CMD_SET_DISPLAY_OFFSET); //-set display offset
i2c_write_command(SSD1306_CMD_SET_LOW_COLUMN); //-not offset
i2c_write_command(SSD1306_CMD_SET_DISPLAY_CLOCK_DIV); //--set display clock divide ratio/oscillator frequency
i2c_write_command(0xf0); //--set divide ratio
i2c_write_command(SSD1306_CMD_SET_PRECHARGE); //--set pre-charge period
i2c_write_command(SSD1306_CMD_PAGE_ADDR); //
i2c_write_command(SSD1306_CMD_SET_COM_PINS); //--set com pins hardware configuration
i2c_write_command(0x12);
i2c_write_command(SSD1306_CMD_SET_VCOM_DETECT); //--set vcomh
i2c_write_command(SSD1306_CMD_MEMORY_MODE); // 0x20,0.77xVcc
i2c_write_command(SSD1306_CMD_CHARGE_PUMP); //--set DC-DC enable
i2c_write_command(SSD1306_CMD_SET_DC_DC_ENABLE); //
i2c_write_command(SSD1306_CMD_DISPLAY_ON); //--turn on oled panel
ssd1306_fill(0);
// ssd1306_test();
}
void ssd1306_display_on(void)
{
i2c_write_command(SSD1306_CMD_CHARGE_PUMP); // 设置电荷泵
i2c_write_command(SSD1306_CMD_SET_DC_DC_ENABLE); // 开启电荷泵
i2c_write_command(SSD1306_CMD_DISPLAY_ON); // OLED唤醒
}
void ssd1306_display_off(void)
{
i2c_write_command(SSD1306_CMD_CHARGE_PUMP); // 设置电荷泵
i2c_write_command(SSD1306_CMD_SET_HIGH_COLUMN); // 关闭电荷泵
i2c_write_command(SSD1306_CMD_DISPLAY_OFF); // OLED休眠
}
/**
* @brief SSD1306 OLED显示屏的内容
*
* SSD1306 OLED显示屏
*
*
*
* @note
*/
void ssd1306_update_screen(void)
{
for (uint8_t i = 0; i < SSD1306_HEIGHT / 8; i++)
{
i2c_write_command(0xb0 + i);
i2c_write_command(0x01);
i2c_write_command(0x10);
for (uint8_t j = 0; j < SSD1306_WIDTH; j++)
{
i2c_write_data(_buffer[j + i * SSD1306_WIDTH]);
}
}
}
/**
* @brief
*
* SSD1306 OLED
*
* @param color 0x00 0xFF
*/
void ssd1306_fill(uint8_t color)
{
osel_memset(_buffer, color, ARRAY_LEN(_buffer));
ssd1306_update_screen();
}
/**
* @brief SSD1306显示屏
*
* SSD1306显示屏发送一系列命令来清空显示内容
*
* SSD1306显示屏有8个页面
*
* 1. 0xb0 + yy为当前页面索引
* 2. 0x01
* 3. 0x10
* 4. SSD1306显示屏的宽度
* 0x00
*/
void ssd1306_clear(void)
{
osel_memset(_buffer, 0, ARRAY_LEN(_buffer));
ssd1306_update_screen();
}
void ssd1306_clear_buffer(void)
{
osel_memset(_buffer, 0, ARRAY_LEN(_buffer));
}
/**
* @brief BMP
*
* BMP使SSD1306 OLED显示屏
* ssd1306_draw_bmp(0, 0, SSD1306_WIDTH, 2);
* @param x0 BMP绘制的起始X坐标
* @param y0 BMP绘制的起始Y坐标
* @param x1 BMP绘制的结束X坐标
* @param y1 BMP绘制的结束Y坐标
*/
void ssd1306_draw_bmp(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *bmp)
{
uint8_t j = 0;
uint8_t x, y;
osel_memset(_buffer, 0, ARRAY_LEN(_buffer));
if (y1 % 8 == 0)
y = y1 / 8;
else
y = y1 / 8 + 1;
for (y = y0; y < y1; y++)
{
set_position(x0, y);
for (x = x0; x < x1; x++)
{
i2c_write_data(bmp[j++]);
}
}
}
/**
* @brief SSD1306 OLED显示屏上显示字符串
*
* SSD1306 OLED显示屏上以6x8像素的字体显示给定的字符串
*
* @param x x坐标
* @param y y坐标
* @param str
*/
void ssd1306_f6x8_string(uint8_t x, uint8_t y, const uint8_t *ch)
{
uint8_t c = 0, i = 0, j = 0;
while (ch[j] != '\0')
{
c = ch[j] - 32;
if (x > 126)
{
x = 0;
y++;
}
for (i = 0; i < 6; i++)
_buffer[(y * SSD1306_WIDTH) + x + i] = F6x8[c][i];
x += 6;
j++;
}
}
/**
* @brief SSD1306 OLED屏幕上显示字符串和数字
*
* SSD1306 OLED屏幕上显示字符串和数字
*
*
* @param x x坐标
* @param y y坐标
* @param ch
* @param unit 'm'
* @param num
*/
void ssd1306_f6x8_string_number(uint8_t x, uint8_t y, const uint8_t *ch, uint8_t unit, float32 num)
{
uint8_t c = 0, i = 0, j = 0;
int8_t a, number[7] = {0, 0, 0, -2, 0, 0, 0};
uint32_t d;
while (ch[j] != '\0')
{
c = ch[j] - 32;
if (x > 126)
{
x = 0;
y++;
}
for (i = 0; i < 6; i++)
_buffer[(y * SSD1306_WIDTH) + x + i] = F6x8[c][i];
x += 6;
j++;
}
d = 1000 * num;
for (a = 0; a < 3; a++)
{
number[6 - a] = d % 10;
d = d / 10;
}
for (a = 4; a < 7; a++)
{
number[6 - a] = d % 10;
d = d / 10;
}
if (num >= 100)
{
a = 0;
}
else if (num >= 10)
{
a = 1;
}
else if (num >= 0)
{
a = 2;
}
for (; a < 7; a++)
{
c = number[a] + 16;
if (x > 126)
{
x = 0;
y++;
}
for (i = 0; i < 6; i++)
_buffer[(y * SSD1306_WIDTH) + x + i] = F6x8[c][i];
x += 6;
j++;
}
for (int h = 0; h < 7; h++)
{
c = unit - 32;
for (i = 0; i < 6; i++)
_buffer[(y * SSD1306_WIDTH) + x + i] = F6x8[c][i];
}
}
/**
* @brief SSD1306 OLED显示屏上显示8x16大小的字符串
*
* 使8x16字体在SSD1306 OLED显示屏上显示指定的字符串x和y参数指定
*
* @param x x坐标
* @param y y坐标
* @param str
*/
void ssd1306_f8x16_string(uint8_t x, uint8_t y, const uint8_t *ch)
{
uint8_t c = 0, i = 0, j = 0;
while (ch[j] != '\0')
{
c = ch[j] - 32;
if (x > 120)
{
x = 0;
y++;
}
for (i = 0; i < 8; i++)
_buffer[(y * SSD1306_WIDTH) + x + i] = F8X16[c * 16 + i];
for (i = 0; i < 8; i++)
_buffer[((y + 1) * SSD1306_WIDTH) + x + i] = F8X16[c * 16 + i + 8];
x += 8;
j++;
}
}
/**
* @brief SSD1306 OLED显示屏上以8x16像素字体显示浮点数
*
* (x, y) 使8x16像素大小的字体显示浮点数 num dot_num
*
* @param x x坐标
* @param y y坐标
* @param num
* @param dot_num
*/
void ssd1306_f8x16_number(uint8_t x, uint8_t y, float32 num, uint8_t dot_num)
{
uint8_t ch[9] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};
uint8_t c = 0, i = 0, j = 0;
if (num < 0)
{
ch[i++] = '-';
num = -num;
}
if (num > 32000)
return;
c = 8 - i;
if (num >= 10000)
{
ch[i++] = num / 10000 + 48;
ch[i++] = (int32_t)(num) % 10000 / 1000 + 48;
ch[i++] = (int32_t)(num) % 1000 / 100 + 48;
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 1000)
{
ch[i++] = (int32_t)(num) % 10000 / 1000 + 48;
ch[i++] = (int32_t)(num) % 1000 / 100 + 48;
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 100)
{
ch[i++] = (int32_t)(num) % 1000 / 100 + 48;
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 10)
{
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 0)
{
ch[i++] = (int32_t)(num) % 10 + 48;
}
if (dot_num > 0 && i < 7)
{
ch[i++] = '.';
num = num - (int32_t)num;
if (dot_num == 1 && i < 8)
{
num = num * 10;
ch[i++] = (int32_t)(num + 0.5) % 10 + 48;
}
if (dot_num >= 2 && i < 8)
{
num = num * 100;
ch[i++] = (int32_t)num % 100 / 10 + 48;
if (i < 8)
ch[i++] = (int32_t)(num + 0.5) % 10 + 48;
}
}
while (ch[j] != '\0')
{
c = ch[j] - 32;
if (x > 120)
{
x = 0;
y++;
}
for (i = 0; i < 8; i++)
_buffer[(y * SSD1306_WIDTH) + x + i] = F8X16[c * 16 + i];
for (i = 0; i < 8; i++)
_buffer[((y + 1) * SSD1306_WIDTH) + x + i] = F8X16[c * 16 + i + 8];
x += 8;
j++;
}
}

View File

@ -1,68 +0,0 @@
#ifndef __SSD1306_OLED_H
#define __SSD1306_OLED_H
#include "main.h"
// OLED引脚定义
#define SSD1306_SDA_PORT OLED_SDA_GPIO_Port
#define SSD1306_SDA_PIN OLED_SDA_Pin
#define SSD1306_SCK_PORT OLDE_SCK_GPIO_Port
#define SSD1306_SCK_PIN OLDE_SCK_Pin
// I2C地址
#define SSD1306_I2C_ADDRESS 0x78
// OLED显示参数
#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
// OLED命令定义
#define SSD1306_CMD_DISPLAY_OFF 0xAE
#define SSD1306_CMD_DISPLAY_ON 0xAF
#define SSD1306_CMD_SET_CONTRAST 0x81
#define SSD1306_CMD_DISPLAY_ALL_ON_RESUME 0xA4
#define SSD1306_CMD_DISPLAY_ALL_ON 0xA5
#define SSD1306_CMD_NORMAL_DISPLAY 0xA6
#define SSD1306_CMD_INVERT_DISPLAY 0xA7
#define SSD1306_CMD_SET_DISPLAY_OFFSET 0xD3
#define SSD1306_CMD_SET_COM_PINS 0xDA
#define SSD1306_CMD_SET_VCOM_DETECT 0xDB
#define SSD1306_CMD_SET_DISPLAY_CLOCK_DIV 0xD5
#define SSD1306_CMD_SET_PRECHARGE 0xD9
#define SSD1306_CMD_SET_MULTIPLEX 0xA8
#define SSD1306_CMD_SET_LOW_COLUMN 0x00
#define SSD1306_CMD_SET_HIGH_COLUMN 0x10
#define SSD1306_CMD_SET_START_LINE 0x40
#define SSD1306_CMD_MEMORY_MODE 0x20
#define SSD1306_CMD_COLUMN_ADDR 0x21
#define SSD1306_CMD_PAGE_ADDR 0x22
#define SSD1306_CMD_COM_SCAN_INC 0xC0
#define SSD1306_CMD_COM_SCAN_DEC 0xC8
#define SSD1306_CMD_SEG_REMAP 0xA0
#define SSD1306_CMD_CHARGE_PUMP 0x8D
#define SSD1306_CMD_SET_DC_DC_ENABLE 0x14
#define SDA_OUT() \
{ \
GPIO_SET_OUTPUT(SSD1306_SDA_PORT, SSD1306_SDA_PIN); \
}
#define SDA_IN() \
{ \
GPIO_SET_INPUT(SSD1306_SDA_PORT, SSD1306_SDA_PIN); \
}
// 函数声明
void ssd1306_init(void);
void ssd1306_display_on(void);
void ssd1306_display_off(void);
void ssd1306_update_screen(void);
void ssd1306_fill(uint8_t color);
void ssd1306_clear(void);
void ssd1306_clear_buffer(void);
void ssd1306_draw_bmp(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *bmp);
void ssd1306_f6x8_string(uint8_t x, uint8_t y, const uint8_t *ch);
void ssd1306_f6x8_string_number(uint8_t x, uint8_t y, const uint8_t *ch, uint8_t unit, float32 num);
void ssd1306_f8x16_string(uint8_t x, uint8_t y, const uint8_t *ch);
void ssd1306_f8x16_number(uint8_t x, uint8_t y, float32 num, uint8_t dot_num);
#endif // __SSD1306_OLED_H

View File

@ -1,30 +0,0 @@
#ifndef __S_CURVE_H
#define __S_CURVE_H
#include "lib.h"
typedef struct
{
// 起始频率
float32 f0;
// 加加速段斜率
float32 faa;
// 减减速段斜率
float32 frr;
// 加加速段时间
float32 taa;
// 匀加速段时间
float32 tua;
// 减加速段时间
float32 tra;
// 匀速段时间
float32 tuu;
// 加减速段时间
float32 tar;
// 匀减速段时间
float32 tur;
// 减减速段时间
float32 trr;
} s_curve_t;
void s_curve_table_gen(uint16_t tmin, uint16_t tmax);
#endif // __S_CURVE_H

View File

@ -1,171 +0,0 @@
#include "s_curve.h"
// s曲线加速度各段参数定义
// 起始速度
#define F0 0.0f
// 加加速度与减减速度
#define FAA 0.0f
#define FRR 0.0f
// 加速段三个时间
#define TAA 0.1f
#define TUA 0.2f
#define TRA 0.1f
// 匀速段
#define TUU 5.0f
// 减速段
#define TAR 0.1f
#define TUR 0.2f
#define TRR 0.1f
// 表格长度
#define S_CURVE_TABLE_LEN 400
int16_t s_curve_table[S_CURVE_TABLE_LEN] = {0};
static int16_t s_curve_func(s_curve_t *s, float32 t, float32 *freq, float32 *acc)
{
// 辅助常数项
float32 A, B, C, D, E, F;
// 表达式中间值
float32 f3, f4, f5;
// 加速段,匀速段,减速段时间
float32 Ta, Tu, Tr;
// 减加速与加减速段斜率
float32 fra, far;
// 起始频率与加加速频率,减减速频率
float32 f0, faa, frr;
float32 taa, tua, tra, tuu, tar, tur, trr;
// 获取参数
faa = s->faa;
frr = s->frr;
taa = s->taa;
tua = s->tua;
tra = s->tra;
tuu = s->tuu;
tar = s->tar;
tur = s->tur;
trr = s->trr;
f0 = s->f0;
fra = faa * taa / tra;
far = frr * trr / tar;
Ta = taa + tua + tra;
Tu = tuu;
Tr = tar + tur + trr;
A = f0;
B = f0 - 0.5 * faa * taa * taa;
C = f0 + 0.5 * faa * taa * taa + faa * taa * tua + 0.5 * fra * (taa + tua) * (taa + tua) - fra * Ta * (taa + tua);
// f1 = f0 + 0.5 * faa * taa * taa;
// f2 = f0 + 0.5 * faa * taa * taa + faa * taa * tua;
f3 = 0.5 * fra * Ta * Ta + C;
D = f3 - 0.5 * far * (Ta + Tu) * (Ta + Tu);
f4 = -far * 0.5 * (Ta + Tu + tar) * (Ta + Tu + tar) + far * (Ta + Tu) * (Ta + Tu + tar) + D;
E = f4 + far * tar * (Ta + Tu + tar);
f5 = -far * tar * (Ta + Tu + Tr - trr) + E;
F = f5 + frr * (Ta + Tu + Tr) * (Ta + Tu + Tr - trr) - 0.5 * frr * (Ta + Tu + Tr - trr) * (Ta + Tu + Tr - trr);
// 如果时间点在全行程规定的时间段内
if ((t >= 0) && (t <= Ta + Tu + Tr))
{
// 加加速段
if ((t >= 0) && (t <= taa))
{
*freq = 0.5 * faa * t * t + A;
*acc = faa * t;
}
// 匀加速段
else if ((t >= taa) && (t <= taa + tua))
{
*freq = faa * taa * t + B;
*acc = faa * taa;
}
// 加减速段
else if ((t >= taa + tua) && (t <= taa + tua + tra))
{
*freq = -0.5 * fra * t * t + fra * Ta * t + C;
*acc = -fra * t + fra * Ta;
}
// 匀速段
else if ((t >= Ta) && (t <= Ta + tuu))
{
*freq = f3;
*acc = 0;
}
// 加减速段
else if ((t >= Ta + Tu) && (t <= Ta + Tu + tar))
{
*freq = -0.5 * far * t * t + far * (Ta + Tu) * t + D;
*acc = -far * t + far * (Ta + Tu);
}
// 匀减速
else if ((t >= Ta + Tu + tar) && (t <= Ta + Tu + tar + tur))
{
*freq = -far * tar * t + E;
*acc = -far * tar;
}
// 减减速
else if ((t >= Ta + Tu + Tr - trr) && (t <= Ta + Tu + Tr))
{
*freq = 0.5 * frr * t * t - frr * (Ta + Tu + Tr) * t + F;
*acc = frr * t - frr * (Ta + Tu + Tr);
}
}
else
{
return -1;
}
return 0;
}
// S型曲线初始化
void s_curve_table_gen(uint16_t tmin, uint16_t tmax)
{
uint16_t i, tint;
float32 ti;
float32 freq;
float32 acc;
float32 fi;
s_curve_t s;
osel_memset((uint8_t *)&s, 0, sizeof(s_curve_t));
s.f0 = F0;
s.taa = TAA;
s.tua = TUA;
s.tra = TRA;
s.tuu = TUU;
s.tar = TAR;
s.tur = TUR;
s.trr = TRR;
// 根据约束条件求出加加速段与减减速段斜率
s.faa = 2.0 / (s.taa * (s.taa + s.tra + 2 * s.tua));
s.frr = 2.0 / (s.trr * (s.tar + s.trr + 2 * s.tur));
for (i = 0; i < S_CURVE_TABLE_LEN; i++)
{
// 求出每个时间点对应的频率以及加速度
fi = i * (TAA + TUA + TRA + TUU + TAR + TUR + TRR) / S_CURVE_TABLE_LEN;
s_curve_func(&s, fi, &freq, &acc);
// 根据最大与最小装载值确定定时器实际值
ti = tmax - (tmax - tmin) * freq;
// 转换为整数值
tint = (uint16_t)ti;
// 存入s曲线表
s_curve_table[i] = tint;
}
}

View File

@ -8,8 +8,8 @@
"args": [], "args": [],
"stopAtEntry": false, "stopAtEntry": false,
"externalConsole": true, "externalConsole": true,
"cwd": "e:/work/stm32/epm/User/lib/flow", "cwd": "e:/work/stm32/study/motor_cs103/User/system/lib/driver",
"program": "e:/work/stm32/epm/User/lib/flow/build/Debug/outDebug", "program": "e:/work/stm32/study/motor_cs103/User/system/lib/driver/build/Debug/outDebug",
"MIMode": "gdb", "MIMode": "gdb",
"miDebuggerPath": "gdb", "miDebuggerPath": "gdb",
"setupCommands": [ "setupCommands": [

View File

@ -4,7 +4,7 @@
"C_Cpp_Runner.debuggerPath": "gdb", "C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "", "C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "", "C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat", "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat",
"C_Cpp_Runner.useMsvc": false, "C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [ "C_Cpp_Runner.warnings": [
"-Wall", "-Wall",
@ -54,5 +54,7 @@
"C_Cpp_Runner.useUndefinedSanitizer": false, "C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false, "C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false, "C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false "C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false,
"C_Cpp.errorSquiggles": "disabled"
} }

View File

@ -2,7 +2,7 @@
* @file adcs.c * @file adcs.c
* @author xxx * @author xxx
* @date 2023-09-04 15:59:16 * @date 2023-09-04 15:59:16
* @brief LL库ADC驱动 * @brief LL库ADC驱动 STM32F407
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved. * @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/ */
@ -23,7 +23,7 @@ static uint8_t adc_get_channels_count(uint32_t channnels); // 通过用户配置
* @return {*} * @return {*}
* @note TCONV() = ( + 12.5 )/(/ADC分频系数) * @note TCONV() = ( + 12.5 )/(/ADC分频系数)
*/ */
void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels) void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_stream, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels)
{ {
DBG_ASSERT(num < ADCS_MAX __DBG_LINE); DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
DBG_ASSERT(adc != NULL __DBG_LINE); DBG_ASSERT(adc != NULL __DBG_LINE);
@ -34,6 +34,7 @@ void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_chann
osel_memset((uint8_t *)p, 0, sizeof(adcs_t)); osel_memset((uint8_t *)p, 0, sizeof(adcs_t));
p->adc = adc; p->adc = adc;
p->dma = dma; p->dma = dma;
p->dma_stream = dma_stream;
p->dma_channel = dma_channel; p->dma_channel = dma_channel;
p->channels.data = channels; p->channels.data = channels;
p->adc_cct = adc_cct; p->adc_cct = adc_cct;
@ -49,36 +50,40 @@ void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_chann
DBG_ASSERT(p->adc_value != NULL __DBG_LINE); DBG_ASSERT(p->adc_value != NULL __DBG_LINE);
osel_memset((uint8_t *)p->adc_value, 0, sizeof(uint16_t) * p->adc_sum); osel_memset((uint8_t *)p->adc_value, 0, sizeof(uint16_t) * p->adc_sum);
uint32_t backup_setting_adc_dma_transfer = 0U; LL_DMA_SetChannelSelection(p->dma, p->dma_stream, p->dma_channel);
backup_setting_adc_dma_transfer = LL_ADC_REG_GetDMATransfer(p->adc); LL_DMA_ConfigTransfer(p->dma, p->dma_stream,
LL_ADC_REG_SetDMATransfer(p->adc, LL_ADC_REG_DMA_TRANSFER_NONE); LL_DMA_DIRECTION_PERIPH_TO_MEMORY |
LL_DMA_MODE_CIRCULAR |
LL_DMA_PERIPH_NOINCREMENT |
LL_DMA_MEMORY_INCREMENT |
LL_DMA_PDATAALIGN_HALFWORD |
LL_DMA_MDATAALIGN_HALFWORD |
LL_DMA_PRIORITY_HIGH);
LL_DMA_ConfigAddresses(p->dma, p->dma_stream,
LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA),
(uint32_t)p->adc_value,
LL_DMA_GetDataTransferDirection(p->dma, p->dma_stream));
// ADC开始校准 LL_DMA_SetDataLength(p->dma, p->dma_stream, p->adc_sum);
LL_ADC_StartCalibration(p->adc, LL_ADC_SINGLE_ENDED); LL_DMA_EnableStream(p->dma, p->dma_stream);
// 等待校准完成
while (LL_ADC_IsCalibrationOnGoing(p->adc)) LL_ADC_REG_SetContinuousMode(p->adc, LL_ADC_REG_CONV_CONTINUOUS);
; LL_ADC_REG_SetDMATransfer(p->adc, LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
LL_ADC_REG_SetDMATransfer(p->adc, backup_setting_adc_dma_transfer);
LL_mDelay(10);
LL_ADC_EnableIT_OVR(p->adc);
LL_ADC_Enable(p->adc);
LL_mDelay(10);
if (BIT_IS_SET(channels, INVREF)) if (BIT_IS_SET(channels, INVREF))
{ {
// 使能VREFINT // 使能VREFINT
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p->adc), LL_ADC_PATH_INTERNAL_VREFINT); LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p->adc), LL_ADC_PATH_INTERNAL_VREFINT);
} }
if (BIT_IS_SET(channels, INTEMP))
LL_DMA_SetDataLength(p->dma, p->dma_channel, p->adc_sum);
LL_DMA_SetPeriphAddress(p->dma, p->dma_channel, LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA));
LL_DMA_SetMemoryAddress(p->dma, p->dma_channel, (uint32_t)p->adc_value);
LL_DMA_EnableChannel(p->dma, p->dma_channel);
if (backup_setting_adc_dma_transfer == LL_ADC_REG_DMA_TRANSFER_UNLIMITED)
{ {
LL_ADC_REG_StartConversion(p->adc); // 开始转换 LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p->adc), LL_ADC_PATH_INTERNAL_TEMPSENSOR);
} }
LL_mDelay(10);
// 启动 ADC 转换
LL_ADC_Enable(p->adc);
LL_ADC_REG_StartConversionSWStart(p->adc);
} }
/** /**
@ -91,18 +96,7 @@ void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_chann
void start_sample(adcs_e num) void start_sample(adcs_e num)
{ {
DBG_ASSERT(num < ADCS_MAX __DBG_LINE); DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
adcs_t *p = &adcs[num]; // adcs_t *p = &adcs[num];
LL_DMA_SetDataLength(p->dma, p->dma_channel, p->adc_sum);
LL_DMA_SetPeriphAddress(p->dma, p->dma_channel, LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA));
LL_DMA_SetMemoryAddress(p->dma, p->dma_channel, (uint32_t)p->adc_value);
LL_DMA_EnableChannel(p->dma, p->dma_channel);
LL_ADC_ClearFlag_OVR(p->adc);
LL_ADC_ClearFlag_EOC(p->adc);
LL_ADC_REG_StartConversion(p->adc); // 开始转换
// ADC开始校准
LL_ADC_StartCalibration(p->adc, LL_ADC_SINGLE_ENDED);
} }
/** /**
@ -115,14 +109,7 @@ void start_sample(adcs_e num)
void stop_sample(adcs_e num) void stop_sample(adcs_e num)
{ {
DBG_ASSERT(num < ADCS_MAX __DBG_LINE); DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
adcs_t *p = &adcs[num]; // adcs_t *p = &adcs[num];
LL_ADC_REG_StopConversion(p->adc);
while (LL_ADC_REG_IsConversionOngoing(p->adc) != 0)
;
LL_DMA_DisableChannel(p->dma, p->dma_channel);
DMA_CLEAR_FLAG_TC_CHANNEL(p->dma, p->dma_channel);
DMA_CLEAR_FLAG_TE_CHANNEL(p->dma, p->dma_channel);
} }
/** /**
@ -147,8 +134,6 @@ void adc_dinit(adcs_e num)
{ {
DBG_ASSERT(num < ADCS_MAX __DBG_LINE); DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
adcs_t *p = &adcs[num]; adcs_t *p = &adcs[num];
LL_ADC_REG_StopConversion(p->adc);
LL_DMA_DisableChannel(p->dma, p->dma_channel);
LL_ADC_Disable(p->adc); LL_ADC_Disable(p->adc);
if (p->adc_value != NULL) if (p->adc_value != NULL)
{ {
@ -190,7 +175,7 @@ uint16_t adc_result_median_average(adcs_e num, uint8_t chan)
if (p->adc_cct <= 2) if (p->adc_cct <= 2)
return 0; // 如果adc_cct小于等于2直接返回0 return 0; // 如果adc_cct小于等于2直接返回0
p->median_average_ticks.uticks = sys_get_tick();
uint16_t adc_temp[p->adc_cct]; uint16_t adc_temp[p->adc_cct];
uint32_t adc_sum = 0; uint32_t adc_sum = 0;
uint16_t count = p->adc_cct >> 2; // 使用位移操作计算n的值 uint16_t count = p->adc_cct >> 2; // 使用位移操作计算n的值
@ -212,13 +197,6 @@ uint16_t adc_result_median_average(adcs_e num, uint8_t chan)
// 计算平均值确保不会除以0 // 计算平均值确保不会除以0
uint16_t res = adc_sum / (p->adc_cct - (count << 1)); uint16_t res = adc_sum / (p->adc_cct - (count << 1));
p->median_average_ticks.ticks_current = sys_get_tick() - p->median_average_ticks.uticks;
if (p->median_average_ticks.ticks_current > p->median_average_ticks.ticks_max)
{
p->median_average_ticks.ticks_max = p->median_average_ticks.ticks_current;
}
return res; return res;
} }
@ -236,8 +214,6 @@ uint16_t adc_result_median(adcs_e num, uint8_t chan)
adcs_t *p = &adcs[num]; adcs_t *p = &adcs[num];
DBG_ASSERT(p != NULL __DBG_LINE); DBG_ASSERT(p != NULL __DBG_LINE);
p->median_ticks.uticks = sys_get_tick();
uint16_t adc_temp[p->adc_cct]; uint16_t adc_temp[p->adc_cct];
// 减少重复计算,计算基础偏移量 // 减少重复计算,计算基础偏移量
uint16_t *adc_values = (uint16_t *)p->adc_value + chan; uint16_t *adc_values = (uint16_t *)p->adc_value + chan;
@ -247,12 +223,6 @@ uint16_t adc_result_median(adcs_e num, uint8_t chan)
} }
insertion_sort(adc_temp, p->adc_cct); insertion_sort(adc_temp, p->adc_cct);
res = adc_temp[p->adc_cct >> 1]; res = adc_temp[p->adc_cct >> 1];
p->median_ticks.ticks_current = sys_get_tick() - p->median_ticks.uticks;
if (p->median_ticks.ticks_current > p->median_ticks.ticks_max)
{
p->median_ticks.ticks_max = p->median_ticks.ticks_current;
}
return res; return res;
} }
@ -271,8 +241,6 @@ uint16_t adc_result_average(adcs_e num, uint8_t chan)
adcs_t *p = &adcs[num]; adcs_t *p = &adcs[num];
DBG_ASSERT(p != NULL __DBG_LINE); DBG_ASSERT(p != NULL __DBG_LINE);
p->average_ticks.uticks = sys_get_tick();
// 减少重复计算,计算基础偏移量 // 减少重复计算,计算基础偏移量
uint16_t *adc_values = (uint16_t *)p->adc_value + chan; uint16_t *adc_values = (uint16_t *)p->adc_value + chan;
for (uint16_t i = 0; i < p->adc_cct; ++i, adc_values += p->adc_chans_count) for (uint16_t i = 0; i < p->adc_cct; ++i, adc_values += p->adc_chans_count)
@ -281,12 +249,6 @@ uint16_t adc_result_average(adcs_e num, uint8_t chan)
} }
res = adc_sum / p->adc_cct; res = adc_sum / p->adc_cct;
p->average_ticks.ticks_current = sys_get_tick() - p->average_ticks.uticks;
if (p->average_ticks.ticks_current > p->average_ticks.ticks_max)
{
p->average_ticks.ticks_max = p->average_ticks.ticks_current;
}
return res; return res;
} }
@ -336,10 +298,6 @@ void adc_dma_callback(adcs_e num)
if (LL_DMA_IsActiveFlag_TC1(p->dma) != 0) if (LL_DMA_IsActiveFlag_TC1(p->dma) != 0)
{ {
LL_DMA_ClearFlag_TC1(p->dma); LL_DMA_ClearFlag_TC1(p->dma);
// 停止ADC转换
LL_ADC_REG_StopConversion(p->adc);
// 关闭ADC,可以不关闭但是校准无法清除
// LL_ADC_Disable(p->adc);
} }
// 检查DMA1的传输错误标志是否为1如果是则清除该标志 // 检查DMA1的传输错误标志是否为1如果是则清除该标志
if (LL_DMA_IsActiveFlag_TE1(p->dma) != 0) if (LL_DMA_IsActiveFlag_TE1(p->dma) != 0)
@ -361,17 +319,7 @@ void adc_env_callback(adcs_e num)
if (LL_ADC_IsActiveFlag_OVR(p->adc) != 0) if (LL_ADC_IsActiveFlag_OVR(p->adc) != 0)
{ {
p->ovr_count++; p->ovr_count++;
LL_ADC_REG_StopConversion(p->adc);
LL_DMA_DisableChannel(p->dma, p->dma_channel);
LL_DMA_SetDataLength(p->dma, p->dma_channel, p->adc_sum);
LL_DMA_SetPeriphAddress(p->dma, p->dma_channel, LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA));
LL_DMA_SetMemoryAddress(p->dma, p->dma_channel, (uint32_t)p->adc_value);
LL_DMA_EnableChannel(p->dma, p->dma_channel);
LL_ADC_ClearFlag_OVR(p->adc); LL_ADC_ClearFlag_OVR(p->adc);
LL_ADC_ClearFlag_EOC(p->adc);
LL_ADC_REG_StartConversion(p->adc); // 开始转换
} }
} }

View File

@ -17,9 +17,6 @@
#ifndef __ADCS_H__ #ifndef __ADCS_H__
#define __ADCS_H__ #define __ADCS_H__
#include "lib.h"
#include "main.h"
#include "sys.h" #include "sys.h"
#define ADC_CHANNEL_MAX 18 ///< Maximum number of ADC channels #define ADC_CHANNEL_MAX 18 ///< Maximum number of ADC channels
@ -85,6 +82,7 @@ typedef struct
{ {
ADC_TypeDef *adc; ///< ADC peripheral ADC_TypeDef *adc; ///< ADC peripheral
DMA_TypeDef *dma; ///< DMA peripheral DMA_TypeDef *dma; ///< DMA peripheral
uint32_t dma_stream; ///< DMA stream
uint32_t dma_channel; ///< DMA channel uint32_t dma_channel; ///< DMA channel
adcs_channels_u channels; ///< ADC channels adcs_channels_u channels; ///< ADC channels
uint32_t ovr_count; ///< ADC overflow count uint32_t ovr_count; ///< ADC overflow count
@ -94,9 +92,6 @@ typedef struct
uint16_t adc_sum; ///< Channel acquisition count uint16_t adc_sum; ///< Channel acquisition count
__IO uint16_t *adc_value; ///< Address to store ADC conversion results __IO uint16_t *adc_value; ///< Address to store ADC conversion results
utime_ticks_t median_average_ticks; ///< Median average filtering ticks
utime_ticks_t median_ticks; ///< Median filtering ticks
utime_ticks_t average_ticks; ///< Average filtering ticks
} adcs_t; } adcs_t;
/** /**
@ -111,7 +106,7 @@ typedef struct
* @param adc_cct The ADC continuous conversion mode. * @param adc_cct The ADC continuous conversion mode.
* @param channels The number of ADC channels to be converted. * @param channels The number of ADC channels to be converted.
*/ */
extern void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels); extern void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_stream, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels);
/** /**
* @brief Starts the ADC conversion. * @brief Starts the ADC conversion.

View File

@ -65,27 +65,27 @@ void pvd_irq_handle(void)
*/ */
void disable_debug_interface(void) void disable_debug_interface(void)
{ {
// // 使能 SYSCFG 时钟 // // 使能 SYSCFG 时钟
// LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG); // LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
// // 关闭调试接口 // // 关闭调试接口
// LL_DBGMCU_DisableDBGStopMode(); // LL_DBGMCU_DisableDBGStopMode();
// LL_DBGMCU_DisableDBGStandbyMode(); // LL_DBGMCU_DisableDBGStandbyMode();
// LL_DBGMCU_DisableDBGSleepMode(); // LL_DBGMCU_DisableDBGSleepMode();
// // 关闭 SWD 和 JTAG 接口 // // 关闭 SWD 和 JTAG 接口
// LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; // LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
// // 配置 SWDIO (PA13) 和 SWCLK (PA14) 引脚为普通 GPIO // // 配置 SWDIO (PA13) 和 SWCLK (PA14) 引脚为普通 GPIO
// GPIO_InitStruct.Pin = LL_GPIO_PIN_13 | LL_GPIO_PIN_14; // GPIO_InitStruct.Pin = LL_GPIO_PIN_13 | LL_GPIO_PIN_14;
// GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; // GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; // GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
// LL_GPIO_Init(GPIOA, &GPIO_InitStruct); // LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// // 如果使用的是 JTAG 接口,还需要配置 JTDI (PA15), JTDO (PB3), 和 NJTRST (PB4) 引脚 // // 如果使用的是 JTAG 接口,还需要配置 JTDI (PA15), JTDO (PB3), 和 NJTRST (PB4) 引脚
// GPIO_InitStruct.Pin = LL_GPIO_PIN_15; // GPIO_InitStruct.Pin = LL_GPIO_PIN_15;
// LL_GPIO_Init(GPIOA, &GPIO_InitStruct); // LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// GPIO_InitStruct.Pin = LL_GPIO_PIN_3 | LL_GPIO_PIN_4; // GPIO_InitStruct.Pin = LL_GPIO_PIN_3 | LL_GPIO_PIN_4;
// LL_GPIO_Init(GPIOB, &GPIO_InitStruct); // LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
} }

View File

@ -11,14 +11,14 @@
*/ */
#ifndef __BSP_H__ #ifndef __BSP_H__
#define __BSP_H__ #define __BSP_H__
#include "dma.h"
#include "gpios.h" #include "gpios.h"
// #include "adcs.h" #include "adcs.h"
// #include "dacs.h" // #include "dacs.h"
// #include "dmas.h"
#include "tims.h" #include "tims.h"
// #include "pwms.h" // #include "pwms.h"
// #include "uarts.h" #include "uarts.h"
// #include "eeprom.h" // #include "eeprom.h"
// #include "spis.h" // #include "spis.h"
// #include "i2cs.h" // #include "i2cs.h"
@ -29,4 +29,5 @@ typedef void (*pvd_irq_handle_cb)(void);
extern void pvd_configuration(uint32_t pwr_level, pvd_irq_handle_cb call); ///< Configures the Programmable Voltage Detector (PVD) module extern void pvd_configuration(uint32_t pwr_level, pvd_irq_handle_cb call); ///< Configures the Programmable Voltage Detector (PVD) module
extern void pvd_irq_handle(void); ///< Handles the PVD interrupt extern void pvd_irq_handle(void); ///< Handles the PVD interrupt
extern void disable_debug_interface(void); ///< Disables the debug interface extern void disable_debug_interface(void); ///< Disables the debug interface
#endif ///< __BSP_H__ #endif ///< __BSP_H__

View File

@ -1,5 +1,5 @@
#ifndef __DMAS_H__ #ifndef __DMA_H__
#define __DMAS_H__ #define __DMA_H__
/** /**
* @brief DMA传输完成标志 * @brief DMA传输完成标志
@ -132,4 +132,4 @@
} \ } \
} while (__LINE__ == -1) } while (__LINE__ == -1)
#endif // __DMAS_H__ #endif // __DMA_H__

View File

@ -44,11 +44,11 @@ static uint8_t _read(gpio_t gpio)
/** /**
* @brief GPIO对象 * @brief GPIO对象
* @param {GPIO_TypeDef} *port - GPIO寄存器指针 * @param {GPIO_TypeDef} *port - GPIO寄存器指针
* @param {uint32_t} pin - * @param {uint16_t} pin -
* @return {gpio_t *} - GPIO对象指针 * @return {gpio_t *} - GPIO对象指针
* @note: GPIO对象GPIO功能 * @note: GPIO对象GPIO功能
*/ */
gpio_t *gpio_create(GPIO_TypeDef *port, uint32_t pin) gpio_t *gpio_create(GPIO_TypeDef *port, uint16_t pin)
{ {
gpio_t *gpio = (gpio_t *)osel_mem_alloc(sizeof(gpio_t)); gpio_t *gpio = (gpio_t *)osel_mem_alloc(sizeof(gpio_t));
DBG_ASSERT(gpio != NULL __DBG_LINE); DBG_ASSERT(gpio != NULL __DBG_LINE);

View File

@ -93,7 +93,7 @@
typedef struct GPIO typedef struct GPIO
{ {
GPIO_TypeDef *port; ///< The GPIO port. GPIO_TypeDef *port; ///< The GPIO port.
uint32_t pin; ///< The GPIO pin. uint16_t pin; ///< The GPIO pin.
/** /**
* @brief Set the GPIO pin to high. * @brief Set the GPIO pin to high.
@ -132,7 +132,7 @@ typedef struct GPIO
* @param pin The GPIO pin. * @param pin The GPIO pin.
* @return The created GPIO pin. * @return The created GPIO pin.
*/ */
extern gpio_t *gpio_create(GPIO_TypeDef *port, uint32_t pin); extern gpio_t *gpio_create(GPIO_TypeDef *port, uint16_t pin);
/** /**
* @brief Free the memory allocated for a GPIO pin. * @brief Free the memory allocated for a GPIO pin.

View File

@ -1 +0,0 @@
#include "pwms.h"

View File

@ -39,9 +39,6 @@
LL_TIM_CC_DisableChannel(TIMx, CHx); \ LL_TIM_CC_DisableChannel(TIMx, CHx); \
} while (__LINE__ == -1) } while (__LINE__ == -1)
#define PWM_GET_ARR(TIMx) LL_TIM_GetAutoReload(TIMx)
#define PWM_GET_PSC(TIMx) LL_TIM_GetPrescaler(TIMx)
/** /**
* @brief Sets the PWM frequency * @brief Sets the PWM frequency
* @param TIMx: TIM instance * @param TIMx: TIM instance
@ -90,30 +87,4 @@ static inline uint32_t PWM_GET_FREQ(TIM_TypeDef *TIMx)
return SystemCoreClock / (LL_TIM_GetPrescaler(TIMx) + 1) / (LL_TIM_GetAutoReload(TIMx) + 1); return SystemCoreClock / (LL_TIM_GetPrescaler(TIMx) + 1) / (LL_TIM_GetAutoReload(TIMx) + 1);
} }
/**
* @brief PWM比较值
*
* PWM比较值
*
* @param TIMx TIM_TypeDef结构体
* @param CHx LL_TIM_CHANNEL_CH1到LL_TIM_CHANNEL_CH4
*
* @return uint16_t类型的值PWM比较值0
*/
static inline uint16_t PWM_GET_COMPARE(TIM_TypeDef *TIMx, uint32_t CHx)
{
switch (CHx)
{
case LL_TIM_CHANNEL_CH1:
return LL_TIM_OC_GetCompareCH1(TIMx);
case LL_TIM_CHANNEL_CH2:
return LL_TIM_OC_GetCompareCH2(TIMx);
case LL_TIM_CHANNEL_CH3:
return LL_TIM_OC_GetCompareCH3(TIMx);
case LL_TIM_CHANNEL_CH4:
return LL_TIM_OC_GetCompareCH4(TIMx);
default:
return 0;
}
}
#endif ///< __PWMS_H__ #endif ///< __PWMS_H__

View File

@ -19,6 +19,19 @@ Given Tclk as 84MHz, we need Tout to be 200ms or 200000us. Let's assume PSC is 8
With these calculated values, both ARR and PSC are within the range of 0 to 65535, so we can use this parameter set. With these calculated values, both ARR and PSC are within the range of 0 to 65535, so we can use this parameter set.
*/ */
#define ENABLE_TIM_COUNT(TIMx) \
do \
{ \
LL_TIM_EnableCounter(TIMx); \
} while (__LINE__ == -1);
#define RESET_TIM_COUNT(TIMx) \
do \
{ \
LL_TIM_DisableCounter(TIMx); \
LL_TIM_SetCounter(TIMx, 0); \
LL_TIM_EnableCounter(TIMx); \
} while (__LINE__ == -1);
/** /**
* @brief Enables the specified TIMx. * @brief Enables the specified TIMx.
* @param TIMx TIM instance. * @param TIMx TIM instance.
@ -112,5 +125,4 @@ With these calculated values, both ARR and PSC are within the range of 0 to 6553
* @return * @return
*/ */
#define TIM_CYCLE(TIMx) ((LL_TIM_GetAutoReload(TIMx) + 1) * 0.1) #define TIM_CYCLE(TIMx) ((LL_TIM_GetAutoReload(TIMx) + 1) * 0.1)
#endif ///< __TIMS_H__ #endif ///< __TIMS_H__

View File

@ -104,7 +104,7 @@ void uart_recv_en(uart_t *uart, BOOL rx_err_en)
LL_DMA_DisableChannel(uart->dma, uart->dma_rx_channel); LL_DMA_DisableChannel(uart->dma, uart->dma_rx_channel);
// 配置RX DMA // 配置RX DMA
LL_DMA_SetPeriphAddress(uart->dma, uart->dma_rx_channel, LL_USART_DMA_GetRegAddr(uart->huart)); LL_DMA_SetPeriphAddress(uart->dma, uart->dma_rx_channel, LL_USART_DMA_GetRegAddr(uart->huart, LL_USART_DMA_REG_DATA_RECEIVE));
LL_DMA_SetMemoryAddress(uart->dma, uart->dma_rx_channel, (uint32_t)uart->rxbuf); LL_DMA_SetMemoryAddress(uart->dma, uart->dma_rx_channel, (uint32_t)uart->rxbuf);
LL_DMA_SetDataLength(uart->dma, uart->dma_rx_channel, uart->rxsize); LL_DMA_SetDataLength(uart->dma, uart->dma_rx_channel, uart->rxsize);
LL_DMA_EnableIT_TC(uart->dma, uart->dma_rx_channel); LL_DMA_EnableIT_TC(uart->dma, uart->dma_rx_channel);
@ -113,7 +113,7 @@ void uart_recv_en(uart_t *uart, BOOL rx_err_en)
LL_USART_EnableIT_IDLE(uart->huart); LL_USART_EnableIT_IDLE(uart->huart);
// 配置TX DMA // 配置TX DMA
LL_DMA_SetPeriphAddress(uart->dma, uart->dma_tx_channel, LL_USART_DMA_GetRegAddr(uart->huart)); LL_DMA_SetPeriphAddress(uart->dma, uart->dma_tx_channel, LL_USART_DMA_GetRegAddr(uart->huart, LL_USART_DMA_REG_DATA_TRANSMIT));
// 配置内存地址 // 配置内存地址
LL_DMA_SetMemoryAddress(uart->dma, uart->dma_tx_channel, (uint32_t)uart->txbuf); LL_DMA_SetMemoryAddress(uart->dma, uart->dma_tx_channel, (uint32_t)uart->txbuf);
LL_DMA_EnableIT_TC(uart->dma, uart->dma_tx_channel); LL_DMA_EnableIT_TC(uart->dma, uart->dma_tx_channel);
@ -178,7 +178,7 @@ void uart_free(uart_t *uart)
*/ */
void uart_set_baudrate(USART_TypeDef *uart, uint32_t baudrate) void uart_set_baudrate(USART_TypeDef *uart, uint32_t baudrate)
{ {
LL_USART_SetBaudRate(uart, SystemCoreClock, LL_USART_OVERSAMPLING_16); LL_USART_SetBaudRate(uart, SystemCoreClock, LL_USART_OVERSAMPLING_16, baudrate);
} }
/** /**

View File

@ -8,7 +8,7 @@
* Copyright (c) 2023 by xxx, All Rights Reserved. * Copyright (c) 2023 by xxx, All Rights Reserved.
*/ */
#include "../inc/btn.h" #include "btn.h"
#define EVENT_CB(ev) \ #define EVENT_CB(ev) \
if (handle->cb[ev]) \ if (handle->cb[ev]) \

View File

@ -47,8 +47,8 @@ while(1) {
// 根据您的需求修改常量。 // 根据您的需求修改常量。
#define TICKS_INTERVAL 10 // 按钮扫描间隔单位ms #define TICKS_INTERVAL 10 // 按钮扫描间隔单位ms
#define DEBOUNCE_TICKS 30 / TICKS_INTERVAL // 按键去抖动时间单位ms #define DEBOUNCE_TICKS 20 / TICKS_INTERVAL // 按键去抖动时间单位ms
#define SHORT_TICKS (30 / TICKS_INTERVAL) // 短按时间阈值单位ms #define SHORT_TICKS (100 / TICKS_INTERVAL) // 短按时间阈值单位ms
#define LONG_TICKS (500 / TICKS_INTERVAL) // 长按时间阈值单位ms #define LONG_TICKS (500 / TICKS_INTERVAL) // 长按时间阈值单位ms
typedef void (*BtnCallback)(void *); typedef void (*BtnCallback)(void *);

View File

@ -9,6 +9,7 @@
*/ */
#include "delay.h" #include "delay.h"
// static uint16_t g_fac_ms = 0; // ms延时倍乘数,在os下,代表每个节拍的ms数 // static uint16_t g_fac_ms = 0; // ms延时倍乘数,在os下,代表每个节拍的ms数
static uint32_t g_fac_us = 0; /* us延时倍乘数 */ static uint32_t g_fac_us = 0; /* us延时倍乘数 */
@ -79,6 +80,13 @@ void delay_us(uint32_t nus)
} }
} }
void delay_hardware_us(TIM_TypeDef *timer_us, uint32_t us)
{
RESET_TIM_COUNT(timer_us);
while (LL_TIM_GetCounter(timer_us) < us)
; // 等待计数器达到指定值
}
/** /**
* @brief nms * @brief nms
* @param nms: ms数 (0< nms <= 65535) * @param nms: ms数 (0< nms <= 65535)

23
User/system/delay.h Normal file
View File

@ -0,0 +1,23 @@
/***
* @Author:
* @Date: 2023-04-11 18:31:07
* @LastEditors: xxx
* @LastEditTime: 2023-04-11 18:31:20
* @Description:
* @email:
* @Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
#include "tims.h"
void delay_init(uint16_t sysclk); /* 初始化延迟函数 */
void delay_ms(uint16_t nms); /* 延时nms */
void delay_us(uint32_t nus); /* 延时nus */
void delay_hardware_us(TIM_TypeDef *timer_us, uint32_t us); /* 硬件延时nus */
void delay_tick(uint32_t ticks); /* 延时ticks */
#endif

View File

@ -0,0 +1,154 @@
#include "dac161p997.h"
#include "delay.h"
static dac161p997_t _handle;
static void _delay_us(uint32_t us)
{
delay_hardware_us(_handle.timer_us, us);
}
static void dac161p997_output_0()
{
_handle.io->set(*_handle.io);
_delay_us(DUTY_CYCLE_25);
_handle.io->reset(*_handle.io);
_delay_us(DUTY_CYCLE_75);
}
static void dac161p997_output_1()
{
_handle.io->set(*_handle.io);
_delay_us(DUTY_CYCLE_75);
_handle.io->reset(*_handle.io);
_delay_us(DUTY_CYCLE_25);
}
static void dac161p997_output_d()
{
_handle.io->set(*_handle.io);
_delay_us(DUTY_CYCLE_50);
_handle.io->reset(*_handle.io);
_delay_us(DUTY_CYCLE_50);
}
/**
* @brief DAC161符号
*
* DAC161输出函数
*
* @param sym ZERO_SYMONE_SYM或其他值
*/
static void dac161p997_output_symbol(uint8_t sym)
{
switch (sym)
{
case ZERO_SYM:
dac161p997_output_0();
break;
case ONE_SYM:
dac161p997_output_1();
break;
default:
dac161p997_output_d();
break;
}
}
/**
* @brief DAC161写入寄存器
*
* DAC161写入一个16位的数据8
*
* @param data 16
* @param tag 8tag = 0DAC寄存器tag = 1
*/
void dac161p997_swif_write_reg(uint16_t data, uint8_t tag)
{
uint8_t plow, phigh;
uint16_t i, tmp;
/* compute parity low */
tmp = data & 0x00ff; // get least significant byte
for (plow = 0; tmp != 0; tmp >>= 1)
{
if (tmp & 0x1) // test if lsb is 1
plow++; // count number of bits equal to 1
}
if (plow & 0x1) // check if number of 1s is odd
plow = 0; // set even parity
else
plow = 1; // else set odd parity
/* compute parity high */
tmp = (data & 0xff00) >> 8; // get most significant byte
for (phigh = 0; tmp != 0; tmp >>= 1)
{
if (tmp & 0x1) // test if lsb is 1
phigh++; // count number of bits equal to 1
}
if (phigh & 0x1) // check if number of 1s is odd
phigh = 0; // set even parity
else
phigh = 1; // set odd parity
phigh = phigh ^ tag; // parity high is for high slice = tag + 1 byte
dac161p997_output_symbol(IDLE_SYM); // Frame start: send an idle symbol first
dac161p997_output_symbol(tag);
tmp = data;
for (i = 0; i < 16; i++) // send 16 data bits msb to lsb
{
if (tmp & 0x8000)
{
dac161p997_output_symbol(ONE_SYM); // send 1
}
else
{
dac161p997_output_symbol(ZERO_SYM); // send 0
}
tmp = tmp << 1; // move next data bit to msb
}
dac161p997_output_symbol(phigh); // send parity high bit
dac161p997_output_symbol(plow); // send parity low bit
dac161p997_output_symbol(IDLE_SYM); // send idle
}
/**
* @brief DAC161输出电流
*
* DAC161写入指定的电流值来设置其输出电流,100ms
*
* @param current
*/
void dac161p997_output_current(float32 current)
{
uint16_t adc = (uint16_t)(current * DAC161P997_CURRENT_SLOPE);
dac161p997_swif_write_reg(adc, DACCODE_WRITE);
}
/**
* @brief DAC161设备
*
* DAC161设备便
*
*
* 1. DAC161的配置寄存器
* 2. DAC161的错误下限寄存器
* 3. DAC161的配置寄存器
*/
void dac161p997_init(TIM_TypeDef *timer_us)
{
DBG_ASSERT(timer_us != NULL __DBG_LINE);
_handle.timer_us = timer_us;
ENABLE_TIM_COUNT(_handle.timer_us);
_handle.io = gpio_create(DAC161P997_IO_PORT, DAC161P997_IO_PIN);
dac161p997_swif_write_reg(DAC161P997_LCK_REG + DAC161P997_LCK_REG_UNLOCK, CONFIG_WRITE);
dac161p997_swif_write_reg(DAC161P997_CONFIG2_REG, CONFIG_WRITE);
dac161p997_swif_write_reg(DAC161P997_LCK_REG + DAC161P997_LCK_REG_LOCK, CONFIG_WRITE);
}

View File

@ -0,0 +1,83 @@
#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)
typedef enum
{
DAC161P997_IDLE_SYM,
} dac161p997_e;
typedef struct
{
TIM_TypeDef *timer_us;
gpio_t *io;
uint8_t count;
} 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(TIM_TypeDef *timer_us);
#endif

View File

@ -0,0 +1,219 @@
/**
* @file eeprom_fm24.c
* @author xxx
* @date 2023-08-29 07:58:27
* @brief FM24 EEPROM相关的读写操作
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "entity.h"
#include "board.h"
#include "eeprom_fm24.h"
#include "delay.h"
#define FM24_SPI SPI1
#define EEPROM_FM24_CS_PORT EE3_CS_GPIO_Port
#define EEPROM_FM24_CS_PIN EE3_CS_Pin
#define EEPROM_FM24_MOSI_PORT SPI_MOSI_GPIO_Port
#define EEPROM_FM24_MOSI_PIN SPI_MOSI_Pin
#define EEPROM_FM24_MISO_PORT SPI_MISO_GPIO_Port
#define EEPROM_FM24_MISO_PIN SPI_MISO_Pin
#define EEPROM_FM24_SCK_PORT SPI_CLK_GPIO_Port
#define EEPROM_FM24_SCK_PIN SPI_CLK_Pin
static fm24_t _eeprom_fm24;
void eeprom_fm24_init(void)
{
spi_gpio_group_t gpios;
spi_normal_config_t cfg;
osel_memset((uint8_t *)&cfg, 0, sizeof(spi_normal_config_t));
// 创建CS引脚
gpios.cs = gpio_create(EEPROM_FM24_CS_PORT, EEPROM_FM24_CS_PIN);
gpios.mosi = gpio_create(EEPROM_FM24_MOSI_PORT, EEPROM_FM24_MOSI_PIN);
gpios.sck = gpio_create(EEPROM_FM24_SCK_PORT, EEPROM_FM24_SCK_PIN);
gpios.miso = gpio_create(EEPROM_FM24_MISO_PORT, EEPROM_FM24_MISO_PIN);
gpios.rst = gpio_create(NULL, 0);
gpios.rdy = gpio_create(NULL, 0);
// 创建SPI对象
eeprom_fm24_get()->spi = spi_create(SPI_TYPE_NORMAL, gpios, 0);
DBG_ASSERT(eeprom_fm24_get() != NULL __DBG_LINE);
cfg.cmd_rdsr = FM24_CMD_RDSR;
cfg.cmd_wrsr = FM24_CMD_WRSR;
cfg.cmd_wren = FM24_CMD_WREN;
cfg.cmd_wrdi = FM24_CMD_WRDI;
cfg.cmd_write = FM24_CMD_WRITE;
cfg.cmd_read = FM24_CMD_READ;
cfg.dummy_byte = FM24_DUMMY_BYTE;
cfg.address_bytes = 2;
cfg.page_size = FM24_PAGE_SIZE;
cfg.total_size = FM24_SIZE;
cfg.continuous_write = FALSE;
osel_memcpy((uint8_t *)&eeprom_fm24_get()->spi->cfg, (uint8_t *)&cfg, sizeof(spi_normal_config_t));
// 使能SPI
eeprom_fm24_get()->spi->interface.hardware_enable(eeprom_fm24_get()->spi, FM24_SPI);
// 这里需要复位下SPI否则读出的数据不对
eeprom_fm24_get()->spi->interface.u.normal.spi_reset(eeprom_fm24_get()->spi);
eeprom_fm24_write_protection_close();
// eeprom_fm24_test();
}
fm24_t *eeprom_fm24_get(void)
{
return &_eeprom_fm24;
}
void eeprom_fm24_dinit(void)
{
LL_SPI_Disable(FM24_SPI);
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.mosi->port, eeprom_fm24_get()->spi->gpios.mosi->pin);
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.miso->port, eeprom_fm24_get()->spi->gpios.miso->pin);
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.sck->port, eeprom_fm24_get()->spi->gpios.sck->pin);
GPIO_SET_ANALOG(eeprom_fm24_get()->spi->gpios.cs->port, eeprom_fm24_get()->spi->gpios.cs->pin);
}
void eeprom_fm24_enable(void)
{
uint16_t count = 100;
LL_SPI_Enable(FM24_SPI);
// 判断SPI是否使能成功
while (LL_SPI_IsEnabled(FM24_SPI) != 1)
{
if (count-- == 0)
{
return;
}
else
{
__NOP();
}
}
}
void eeprom_fm24_disable(void)
{
uint16_t count = 100;
LL_SPI_Disable(FM24_SPI);
// 判断SPI是否关闭成功
while (LL_SPI_IsEnabled(FM24_SPI) != 0)
{
if (count-- == 0)
{
return;
}
else
{
__NOP();
}
}
}
/**
* @brief EEPROM FM24的写保护
*
* EEPROM FM24的写保护功能
*
* EEPROM FM24的SPI接口已正确初始化
*/
void eeprom_fm24_write_protection_close(void)
{
DBG_ASSERT(eeprom_fm24_get()->spi != NULL __DBG_LINE);
eeprom_fm24_enable();
eeprom_fm24_get()->spi->interface.u.normal.spi_write_reg(eeprom_fm24_get()->spi, eeprom_fm24_get()->spi->cfg.cmd_wrsr, 0);
eeprom_fm24_disable();
}
/**
* @brief EEPROM FM24的写保护状态
*
* EEPROM FM24的写保护状态
*
* @return BOOL TRUE表示没有写保护FALSE表示有写保护
*/
BOOL eeprom_fm24_write_protection_state(void)
{
DBG_ASSERT(eeprom_fm24_get()->spi != NULL __DBG_LINE);
eeprom_fm24_enable();
eeprom_fm24_get()->write_protection.data = eeprom_fm24_get()->spi->interface.u.normal.spi_read_reg(eeprom_fm24_get()->spi, eeprom_fm24_get()->spi->cfg.cmd_rdsr);
eeprom_fm24_disable();
if (eeprom_fm24_get()->write_protection.bits.bp0 == 1 ||
eeprom_fm24_get()->write_protection.bits.bp1 == 1 ||
eeprom_fm24_get()->write_protection.bits.wpen == 1)
{
return FALSE;
}
else
{
return TRUE;
}
}
BOOL eeprom_fm24_write(uint32_t write_addr, uint8_t *data, uint16_t length)
{
BOOL ret = FALSE;
if (length == 0)
{
return ret;
}
// 开启和关闭SPI对读写实时性有影响
eeprom_fm24_enable();
ret = eeprom_fm24_get()->spi->interface.u.normal.spi_write(eeprom_fm24_get()->spi, write_addr, data, length);
eeprom_fm24_disable();
return ret;
}
BOOL eeprom_fm24_read(uint32_t read_addr, uint8_t *data, uint16_t length)
{
BOOL ret = FALSE;
if (length == 0)
{
return ret;
}
// 开启和关闭SPI对读写实时性有影响
eeprom_fm24_enable();
ret = eeprom_fm24_get()->spi->interface.u.normal.spi_read(eeprom_fm24_get()->spi, read_addr, data, length);
eeprom_fm24_disable();
return ret;
}
BOOL eeprom_fm24_test(void)
{
const uint8_t buf_size = 5;
uint16_t test_address = FM24_TEST_PAGE * FM24_PAGE_SIZE;
uint8_t buf[buf_size];
uint8_t rbuf[buf_size];
osel_memset(buf, 0, buf_size);
osel_memset(rbuf, 0, buf_size);
buf[0] = 0xD5;
buf[1] = 0xC8;
buf[2] = 0x00;
buf[3] = 0x01;
buf[4] = 0x02;
buf[buf_size - 1] = 0xfe;
eeprom_fm24_write(test_address, buf, buf_size);
__NOP();
eeprom_fm24_read(test_address, rbuf, buf_size);
if (osel_memcmp(buf, rbuf, buf_size) == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
/**
* @brief FM24 EEPROM的状态
*
* FM24 EEPROM的当前状态TRUEEEPROM正常工作
*
* @return BOOL TRUE
*/
BOOL eeprom_fm24_status_get(void)
{
return TRUE;
}

View File

@ -0,0 +1,158 @@
/**
* @file eeprom_fm24.h
* @author xxx
* @date 2023-08-30 14:05:55
* @brief FM24系列EEPROM驱动 https://zhuanlan.zhihu.com/p/598934638
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#ifndef __EEPROM_FM24_H__
#define __EEPROM_FM24_H__
#include "main.h"
#include "spis.h"
// High-endurance 100 trillion (1014) read/writes
//========在此设定芯片地址=============
#define W_ADD_COM 0xa0 // 写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
#define R_ADD_COM 0xa1 // 读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
//=======在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
//=======在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
#define e2prom 256 //
#if e2prom == 1
#define FM24_PAGE_SIZE 16
#define FM24_SIZE (128 * 8)
#elif e2prom == 2
#define FM24_PAGE_SIZE 16
#define FM24_SIZE (256 * 8)
#elif e2prom == 4
#define FM24_PAGE_SIZE 32
#define FM24_SIZE (512 * 8)
#elif e2prom == 8
#define FM24_PAGE_SIZE 64
#define FM24_SIZE (1024 * 8)
#elif e2prom == 16
#define FM24_PAGE_SIZE 128
#define FM24_SIZE (2048 * 8)
#elif e2prom == 32
#define FM24_PAGE_SIZE 128
#define FM24_SIZE (4096 * 8)
#elif e2prom == 64
#define FM24_PAGE_SIZE 256
#define FM24_SIZE (8192 * 8)
#elif e2prom == 128
#define FM24_PAGE_SIZE 256
#define FM24_SIZE (16384)
#elif e2prom == 256
#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 ///< 无用数据
#define FM24_TEST_PAGE 0 ///< 测试页地址
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.
*/
extern void eeprom_fm24_init(void);
/**
* @brief Deinitializes the FM24 EEPROM module.
*/
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.
*/
extern void eeprom_fm24_enable(void);
/**
* @brief Disables the FM24 EEPROM module.
*/
extern void eeprom_fm24_disable(void);
/**
* @brief Reads data from the FM24 EEPROM module.
* @param read_addr The starting address to read from.
* @param data Pointer to the buffer to store the read data.
* @param length The number of bytes to read.
* @return TRUE if the read operation is successful, FALSE otherwise.
*/
extern BOOL eeprom_fm24_read(uint32_t read_addr, uint8_t *data, uint16_t length);
/**
* @brief Writes data to the FM24 EEPROM module.
* @param write_addr The starting address to write to.
* @param data Pointer to the data to be written.
* @param length The number of bytes to write.
* @return TRUE if the write operation is successful, FALSE otherwise.
*/
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.
*/
extern BOOL eeprom_fm24_test(void);
/**
* @brief Gets the status of the FM24 EEPROM module.
* @return TRUE if the FM24 EEPROM module is ready, FALSE otherwise.
*/
extern BOOL eeprom_fm24_status_get(void);
#endif // __EEPROM_FM24_H__

View File

@ -0,0 +1,171 @@
#include "eeprom_lc02b.h"
#include "delay.h"
#define W_ADD_COM 0xa8 // 写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
#define R_ADD_COM 0xa9 // 读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
#define PAGE_SIZE 8U
#define SIZE 256U
#define EEPROM_LC02B_SDA_PORT I2C1_SDA_GPIO_Port
#define EEPROM_LC02B_SDA_PIN I2C1_SDA_Pin
#define EEPROM_LC02B_SCL_PORT I2C1_SCL_GPIO_Port
#define EEPROM_LC02B_SCL_PIN I2C1_SCL_Pin
static i2c_t *_eeprom_24lc028bt_i2c;
static TIM_TypeDef *_timer_us;
static void _delay_us(uint32_t us)
{
if (_timer_us != NULL)
{
delay_hardware_us(_timer_us, us);
}
else
{
delay_us(us);
}
}
void eeprom_lc02b_test(void)
{
#define TEST_SIZE 15
uint16_t test_address = SIZE - TEST_SIZE;
uint8_t buf[TEST_SIZE];
for (uint8_t i = 0; i < TEST_SIZE; i++)
{
buf[i] = i + 1;
}
eeprom_lc02b_write(test_address, buf, TEST_SIZE);
_delay_us(10000);
osel_memset(buf, 0, ARRAY_LEN(buf));
eeprom_lc02b_read(test_address, buf, TEST_SIZE);
__NOP();
}
/**
* @brief EEPROM LC02B的状态
*
* EEPROM LC02B的当前状态
*
* @return EEPROM LC02B处于正常状态TRUEFALSE
* TRUE
*/
BOOL eeprom_lc02b_status_get(void)
{
return TRUE;
}
/**
* @brief EEPROM LC02B初始化
* @return {*}
* @note
*/
void eeprom_lc02b_init(TIM_TypeDef *timer_us)
{
if (timer_us != NULL)
{
_timer_us = timer_us;
ENABLE_TIM_COUNT(_timer_us);
}
i2c_gpio_group_t gpios;
gpios.scl = gpio_create(EEPROM_LC02B_SCL_PORT, EEPROM_LC02B_SCL_PIN);
gpios.sda = gpio_create(EEPROM_LC02B_SDA_PORT, EEPROM_LC02B_SDA_PIN);
_eeprom_24lc028bt_i2c = i2c_create(gpios, 10);
// eeprom_lc02b_test();
}
/**
* @brief EEPROM LC02B反初始化
* @return {*}
* @note
*/
void eeprom_lc02b_dinit(void)
{
GPIO_SET_ANALOG(EEPROM_LC02B_SDA_PORT, EEPROM_LC02B_SDA_PIN);
GPIO_SET_ANALOG(EEPROM_LC02B_SCL_PORT, EEPROM_LC02B_SCL_PIN);
}
/**
* @brief
* @param {uint32_t} write_addr
* @param {uint8_t} *data
* @param {uint16_t} length
* @return {*}
* @note
*/
void eeprom_lc02b_write(uint32_t write_addr, uint8_t *data, uint16_t length)
{
// 发送开始信号
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
// 发送写入地址命令
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
// 等待写入地址命令响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 发送要写入的地址
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)write_addr);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 循环写入数据
for (uint16_t i = 0; i < length; i++)
{
// 写入一个字节数据
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, *data++);
// 等待响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
write_addr++;
if (write_addr % PAGE_SIZE == 0)
{
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
_delay_us(10000); // 延时10ms等待写入完成
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)write_addr);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
}
}
// 写入完成停止I2C总线
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
}
/**
* @brief
* @param {uint32_t} read_addr
* @param {uint8_t} *data
* @param {uint16_t} length
* @return {*}
* @note
*/
void eeprom_lc02b_read(uint32_t read_addr, uint8_t *data, uint16_t length)
{
// 发送开始信号
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
// 发送写入地址命令
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
// 等待写入地址命令响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 发送要读取的地址
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)read_addr);
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 发送开始信号
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
// 发送读取地址命令
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, R_ADD_COM);
// 等待读取地址命令响应
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
// 循环读取数据
for (uint16_t i = 0; i < length - 1; i++)
{
// 读取一个字节数据
*data++ = _eeprom_24lc028bt_i2c->interface.read_byte(_eeprom_24lc028bt_i2c, TRUE);
}
*data++ = _eeprom_24lc028bt_i2c->interface.read_byte(_eeprom_24lc028bt_i2c, FALSE);
// 停止I2C总线
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
}

View File

@ -0,0 +1,56 @@
/**
* @file eeprom_lc02b.h
* @author xxx
* @date 2023-12-27 14:44:02
* @brief
* @copyright Copyright (c) 2024 by xxx, All Rights Reserved.
*/
#ifndef __EEPROM_LC02B_H
#define __EEPROM_LC02B_H
#include "main.h"
#include "entity.h"
#define PRRESSURE_CALIBRATION_ADDRESS 0x00 ///< 压力校准地址
/**
* @brief Initializes the LC02B EEPROM module.
*/
void eeprom_lc02b_init(TIM_TypeDef *timer_us);
/**
* @brief Deinitializes the LC02B EEPROM module.
*/
void eeprom_lc02b_dinit(void);
/**
* @brief Writes data to the LC02B EEPROM module.
*
* @param write_addr The starting address to write the data.
* @param data The pointer to the data to be written.
* @param length The length of the data to be written.
*/
void eeprom_lc02b_write(uint32_t write_addr, uint8_t *data, uint16_t length);
/**
* @brief Reads data from the LC02B EEPROM module.
*
* @param read_addr The starting address to read the data.
* @param data The pointer to store the read data.
* @param length The length of the data to be read.
*/
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);
/**
* @brief Gets the LC02B EEPROM status.
*
* This function is used to get the current status of the LC02B EEPROM.
*
* @return TRUE if the LC02B EEPROM is in normal status, FALSE otherwise.
*/
BOOL eeprom_lc02b_status_get(void);
#endif ///< !__EEPROM_LC02B_H

View File

@ -0,0 +1,331 @@
/**
* @file eeprom_m95.c
* @author xxx
* @date 2023-08-30 08:58:43
* @brief M95 EEPROM相关的读写操作
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "eeprom_m95.h"
#include "spis.h"
#include "delay.h"
#include "entity.h"
#include "board.h"
#include "diagnosis.h"
#include "storage.h"
#define M95_SPI SPI1
#define EEPROM_M95_1_CS_PORT EE1_CS_GPIO_Port
#define EEPROM_M95_1_CS_PIN EE1_CS_Pin
#define EEPROM_M95_2_CS_PORT EE2_CS_GPIO_Port
#define EEPROM_M95_2_CS_PIN EE2_CS_Pin
// 下面宏定义为2个EEPROM_M95的引脚定义
#define EEPROM_M95_MOSI_PORT SPI_MOSI_GPIO_Port
#define EEPROM_M95_MOSI_PIN SPI_MOSI_Pin
#define EEPROM_M95_MISO_PORT SPI_MISO_GPIO_Port
#define EEPROM_M95_MISO_PIN SPI_MISO_Pin
#define EEPROM_M95_SCK_PORT SPI_CLK_GPIO_Port
#define EEPROM_M95_SCK_PIN SPI_CLK_Pin
m95_number_t eeprom_m95s[M95_MAX];
/**
* @brief EEPROM_M95eeprom_m95s
* @param {m95_number_e} num
* @return {*}
* @note
*/
void eeprom_m95_init(m95_number_e num)
{
DBG_ASSERT(num < M95_MAX __DBG_LINE);
spi_gpio_group_t gpios;
spi_t *eeprom_m95_spi;
spi_normal_config_t cfg;
osel_memset((uint8_t *)&cfg, 0, sizeof(spi_normal_config_t));
cfg.cmd_rdsr = M95_CMD_RDSR;
cfg.cmd_wrsr = M95_CMD_WRSR;
cfg.cmd_wren = M95_CMD_WREN;
cfg.cmd_wrdi = M95_CMD_WRDI;
cfg.cmd_write = M95_CMD_WRITE;
cfg.cmd_read = M95_CMD_READ;
cfg.dummy_byte = M95_DUMMY_BYTE;
cfg.continuous_write = FALSE;
// 128 byte
if (num == M95_1)
{
// 创建CS引脚
gpios.cs = gpio_create(EEPROM_M95_1_CS_PORT, EEPROM_M95_1_CS_PIN);
cfg.address_bytes = 3;
cfg.page_size = M95_PAGE_SIZE_256;
cfg.total_size = _M95M02_;
}
// 256 byte
else if (num == M95_2)
{
// 创建CS引脚
gpios.cs = gpio_create(EEPROM_M95_2_CS_PORT, EEPROM_M95_2_CS_PIN);
cfg.address_bytes = 3;
cfg.page_size = M95_PAGE_SIZE_256;
cfg.total_size = _M95M02_;
}
else
{
DBG_ASSERT(FALSE __DBG_LINE);
}
gpios.mosi = gpio_create(EEPROM_M95_MOSI_PORT, EEPROM_M95_MOSI_PIN);
gpios.sck = gpio_create(EEPROM_M95_SCK_PORT, EEPROM_M95_SCK_PIN);
gpios.miso = gpio_create(EEPROM_M95_MISO_PORT, EEPROM_M95_MISO_PIN);
gpios.rst = gpio_create(NULL, 0);
gpios.rdy = gpio_create(NULL, 0);
// 创建SPI对象
eeprom_m95_spi = spi_create(SPI_TYPE_NORMAL, gpios, 10);
DBG_ASSERT(eeprom_m95_spi != NULL __DBG_LINE);
osel_memcpy((uint8_t *)&eeprom_m95_spi->cfg, (uint8_t *)&cfg, sizeof(spi_normal_config_t));
// 使能SPI
eeprom_m95_spi->interface.hardware_enable(eeprom_m95_spi, M95_SPI);
eeprom_m95s[num].num = num;
eeprom_m95s[num].spi = eeprom_m95_spi;
// 这里需要设置,否则读出的数据不对
eeprom_m95_spi->interface.u.normal.spi_reset(eeprom_m95_spi);
eeprom_m95_write_protection_close(num); // 关闭写保护
// eeprom_m95_test(num);
}
/**
* @brief EEPROM_M95
* @param {m95_number_e} num
* @return {*}
* @note
*/
void eeprom_m95_dinit(m95_number_e num)
{
LL_SPI_Disable(M95_SPI);
GPIO_SET_ANALOG(eeprom_m95s[num].spi->gpios.mosi->port, eeprom_m95s[num].spi->gpios.mosi->pin);
GPIO_SET_ANALOG(eeprom_m95s[num].spi->gpios.miso->port, eeprom_m95s[num].spi->gpios.miso->pin);
GPIO_SET_ANALOG(eeprom_m95s[num].spi->gpios.sck->port, eeprom_m95s[num].spi->gpios.sck->pin);
GPIO_SET_ANALOG(eeprom_m95s[num].spi->gpios.cs->port, eeprom_m95s[num].spi->gpios.cs->pin);
}
/**
* @brief M95 EEPROM使能
* @return {*}
* @note
*/
void eeprom_m95_enable(void)
{
uint16_t count = 100;
LL_SPI_Enable(M95_SPI);
// 判断SPI是否使能成功
while (LL_SPI_IsEnabled(M95_SPI) != 1)
{
if (count-- == 0)
{
return;
}
else
{
__NOP();
}
}
}
/**
* @brief M95 EEPROM失能
* @return {*}
* @note
*/
void eeprom_m95_disable(void)
{
uint16_t count = 100;
LL_SPI_Disable(M95_SPI);
// 判断SPI是否关闭成功
while (LL_SPI_IsEnabled(M95_SPI) != 0)
{
if (count-- == 0)
{
return;
}
else
{
__NOP();
}
}
}
/**
* @brief EEPROM M95写保护
*
* M95 EEPROM的写保护功能
*
* @param num M95 EEPROM的编号
*/
void eeprom_m95_write_protection_close(m95_number_e num)
{
spi_t *handle = eeprom_m95s[num].spi;
DBG_ASSERT(handle != NULL __DBG_LINE);
eeprom_m95_enable();
handle->interface.u.normal.spi_write_reg(handle, handle->cfg.cmd_wrsr, 0);
eeprom_m95_disable();
}
/**
* @brief M95 EEPROM写保护状态()
*
* M95编号获取其写保护状态
*
* @param num M95编号
* @return M95 EEPROM处于写保护状态FALSETRUE
*/
BOOL eeprom_m95_write_protection_state(m95_number_e num)
{
spi_t *handle = eeprom_m95s[num].spi;
DBG_ASSERT(handle != NULL __DBG_LINE);
eeprom_m95_enable();
eeprom_m95s[num].write_protection.data = handle->interface.u.normal.spi_read_reg(handle, handle->cfg.cmd_rdsr);
eeprom_m95_disable();
if (eeprom_m95s[num].write_protection.bits.bp0 == 1 ||
eeprom_m95s[num].write_protection.bits.bp1 == 1 ||
eeprom_m95s[num].write_protection.bits.srwd == 1)
{
return FALSE;
}
else
{
return TRUE;
}
}
/**
* @brief M95 EEPROM内存数据
* @param num EEPROM模块编号01
* @param read_addr
* @param data
* @param length
* @return {*}
*/
BOOL eeprom_m95_read(m95_number_e num, uint32_t read_addr, uint8_t *data, uint16_t length)
{
BOOL ret = FALSE;
if (length == 0)
{
return ret;
}
spi_t *eeprom_m95_spi = eeprom_m95s[num].spi; // 获取EEPROM模块的SPI配置
DBG_ASSERT(eeprom_m95_spi != NULL __DBG_LINE);
// 开启和关闭SPI对读写实时性有影响
eeprom_m95_enable();
ret = eeprom_m95_spi->interface.u.normal.spi_read(eeprom_m95_spi, read_addr, data, length);
eeprom_m95_disable();
return ret;
}
/**
* @brief M95 EEPROM内存写入数据
* @param num EEPROM模块编号01
* @param write_addr
* @param data
* @param length
* @return {*}
*/
BOOL eeprom_m95_write(m95_number_e num, uint32_t write_addr, uint8_t *data, uint16_t length)
{
BOOL ret = FALSE;
if (length == 0)
{
return ret;
}
spi_t *eeprom_m95_spi = eeprom_m95s[num].spi;
DBG_ASSERT(eeprom_m95_spi != NULL __DBG_LINE);
// 开启和关闭SPI对读写实时性有影响
eeprom_m95_enable();
ret = eeprom_m95_spi->interface.u.normal.spi_write(eeprom_m95_spi, write_addr, data, length);
eeprom_m95_disable();
return ret;
}
BOOL eeprom_m95_1_read(uint32_t addr, uint8_t *buf, uint16_t size)
{
return eeprom_m95_read(M95_1, addr, buf, size);
}
BOOL eeprom_m95_1_write(uint32_t addr, uint8_t *buf, uint16_t size)
{
return eeprom_m95_write(M95_1, addr, (uint8_t *)buf, size);
}
BOOL eeprom_m95_2_read(uint32_t addr, uint8_t *buf, uint16_t size)
{
return eeprom_m95_read(M95_2, addr, buf, size);
}
BOOL eeprom_m95_2_write(uint32_t addr, uint8_t *buf, uint16_t size)
{
return eeprom_m95_write(M95_2, addr, (uint8_t *)buf, size);
}
/**
* @brief M95 EEPROM测试
* @param {m95_number_e} num
* @return {*}
* @note
*/
BOOL eeprom_m95_test(m95_number_e num)
{
const uint8_t buf_size = 5;
storage_t *st = storage_init(M95_TEST_PAGE * M95_PAGE_SIZE_256, M95_PAGE_SIZE_256);
DBG_ASSERT(st != NULL __DBG_LINE);
if (num == M95_1)
{
st->ops.read = eeprom_m95_1_read;
st->ops.write = eeprom_m95_1_write;
}
else
{
st->ops.read = eeprom_m95_2_read;
st->ops.write = eeprom_m95_2_write;
}
uint8_t buf[buf_size];
uint8_t rbuf[buf_size];
storage_add_node(st, 0, buf_size);
osel_memset(buf, 0, buf_size);
buf[0] = 0xD5;
buf[1] = 0xC8;
buf[2] = num;
buf[3] = 0xaa;
buf[4] = 0xbb;
storage_write(st, 0, buf);
__NOP();
storage_read(st, 0, rbuf);
storage_destroy(st);
if (osel_memcmp(buf, rbuf, buf_size) == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
/**
* @brief EEPROM M95状态
*
* EEPROM M95设备的工作状态
*
* @param num EEPROM M95设备编号
*
* @return EEPROM M95设备正常工作TRUEFALSE
*/
BOOL eeprom_m95_status_get(m95_number_e num)
{
return TRUE;
}

View File

@ -0,0 +1,166 @@
/**
* @file eeprom_m95.h
* @author xxx
* @date 2023-08-30 14:05:55
* @brief eeprom_m95.h
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#ifndef __EEPROM_M95_H
#define __EEPROM_M95_H
#include "main.h"
#include "spis.h"
#define _M95010_ 128
#define _M95020_ 256
#define _M95040_ 512
#define _M95080_ 1024
#define _M95160_ 2048
#define _M95320_ 4096
#define _M95640_ 8192
#define _M95128_ 16384
#define _M95256_ 32768
#define _M95512_ 65536 ///< 65K
#define _M95M02_ 262144 ///< 256K
#define _M95_SIZE _M95512_
#define M95_CMD_RDSR 0x05 /*!< Read Status Register instruction */
#define M95_CMD_WRSR 0x01 /*!< Write Status Register instruction */
#define M95_CMD_WREN 0x06 /*!< Write enable instruction */
#define M95_CMD_WRDI 0x04 /*!< Write disable instruction */
#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.
#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_TEST_PAGE 0 ///< 测试页地址
///< 定义存储器大小(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_e;
typedef enum
{
M95_1,
M95_2,
M95_MAX,
} 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;
m95_write_protection_u write_protection;
spi_t *spi;
} m95_number_t;
extern m95_number_t eeprom_m95s[M95_MAX]; ///< m95芯片数组
/**
* @brief Initializes the M95 EEPROM module.
*
* @param num The M95 EEPROM number.
*/
extern void eeprom_m95_init(m95_number_e num);
/**
* @brief Deinitializes the M95 EEPROM module.
*
* @param num The M95 EEPROM number.
*/
extern void eeprom_m95_dinit(m95_number_e num);
/**
* @brief Enables the M95 EEPROM module.
*/
extern void eeprom_m95_enable(void);
/**
* @brief Disables the M95 EEPROM module.
*/
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.
*
* @param num The M95 EEPROM number.
* @param read_addr The address to read from.
* @param data The buffer to store the read data.
* @param length The number of bytes to read.
*/
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.
*
* @param num The M95 EEPROM number.
* @param write_addr The address to write to.
* @param data The data to write.
* @param length The number of bytes to write.
*/
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.
*
* @param num The M95 EEPROM number.
*/
extern BOOL eeprom_m95_test(m95_number_e num);
/**
* @brief Gets the status of the M95 EEPROM module.
*
* @param num The M95 EEPROM number.
*/
extern BOOL eeprom_m95_status_get(m95_number_e num);
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

@ -0,0 +1,107 @@
/**
* @file ntc_3950.c
* @author xxx
* @date 2023-08-30 08:58:43
* @brief NTC的应用功能
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "ntc_3950.h"
#define CPU_VREF 2.5
#define NTC_VREF 2.5
#define TABLE_SIZE 185
#define NTC_SERIES_RESISTOR 200000 ///< 200K
#define BASE_TEMP -55
const uint32_t _table[TABLE_SIZE] = {
8989000, 8242680, 7592960, 7021380, 6513750, // -55,-54,-53,-52,-51
6059060, 5648680, 5275800, 4935020, 4621990, 4333220, 4065840, 3817520, 3586310, 3370600, // -50,-49,-48,-47,-46,-45,-44,-43,-42,-41
3169000, 2980330, 2803600, 2637910, 2482470, 2336580, 2199620, 2071020, 1950230, 1836790, // -40,-39,-38,-37,-36,-35,-34,-33,-32,-31
1730230, 1630150, 1536140, 1447840, 1364900, 1287000, 1213820, 1145090, 1080530, 1019890, // -30,-29,-28,-27,-26,-25,-24,-23,-22,-21
962912, 909379, 859074, 811797, 767359, 725581, 686296, 649348, 614590, 581883, // -20,-19,-18,-17,-16,-15,-14,-13,-12,-11
551100, 522117, 494824, 469113, 444886, 422050, 400518, 380209, 361048, 342963, // -10,-9,-8,-7,-6,-5,-4,-3,-2,-1
326560, 309764, 294529, 280131, 266520, 253647, 241470, 229946, 219036, 208706, // 0,1, 2, 3,4,5,6,7,8,9
198920, 189647, 180857, 172523, 164618, 157118, 150000, 143243, 136827, 130731, // 10,11 ,12, 13,14,15,16,17,18,19
124940, 119435, 114202, 109225, 104491, 100000, 95699, 91617, 87731, 84028, // 20,21, 22, 23,24,25,26,27,28,29
80501, 77140, 73936, 70881, 67968, 65188, 62537, 60006, 57590, 55283, // 30,31, 32, 33,34,35,36,37,38,39
53080, 50976, 48965, 47044, 45207, 43451, 41771, 40165, 38628, 37157, // 40,41, 42, 43,34,35,36,37,38,39
35750, 34402, 33112, 31876, 30692, 29558, 28471, 27429, 26430, 25472, // 50,51, 52, 53,54,55,56,57,58,59
24554, 23672, 22827, 22016, 21237, 20489, 19771, 19082, 18420, 17784, // 60,61, 62, 63,64,65,66,67,68,69
17172, 16585, 16020, 15477, 14955, 14453, 13970, 13505, 13058, 12628, // 70,71, 72, 73,74,75,76,77,78,79
12213, 11815, 11431, 11061, 10705, 10362, 10031, 9712, 9405, 9110, // 80,81, 82, 83,84,85,86,87,88,89
8824, 8549, 8284, 8028, 7782, 7544, 7314, 7093, 6879, 6673, // 90,91, 92, 93,94,95,96,97,98,99
6474, 6281, 6096, 5916, 5743, 5576, 5415, 5259, 5108, 4963, // 101,102, 103,104,105,106,107,108,109
4822, 4687, 4555, 4428, 4306, 4187, 4073, 3962, 3855, 3751, // 111,112, 113,114,115,116,117,118,119
3651, 3555, 3461, 3371, 3283, 3199, 3100, 3099, 2899, 2799, // 121,122, 123,124,125,126,127,128,129
};
/**
* @brief
* @param {uint32_t} *list
* @param {uint32_t} rt
* @return {*}
* @note
*/
static uint8_t ntc_lookup(const uint32_t *list, uint32_t rt)
{
uint8_t middle = 0;
uint8_t indexL = 0;
uint8_t indexR = TABLE_SIZE - 1;
if (rt >= *(list + 0))
return 0;
if (rt <= *(list + TABLE_SIZE - 1))
return TABLE_SIZE - 1;
while ((indexR - indexL) > 1)
{
middle = (indexL + indexR) >> 1;
if (rt == *(list + middle))
return middle;
else if (rt > *(list + middle))
indexR = middle;
else if (rt < *(list + middle))
indexL = middle;
}
return indexL;
}
/**
* @brief 0.1
* @param {uint16_t} adc采集值
* @return {float32_u}
* @note
*/
float32_u ntc_get_temp(uint16_t adc)
{
uint8_t index = 0;
int16_t data = 0;
int16_t t = 0;
int16_t result = 0;
uint32_t rt = 0;
const int16_t base = BASE_TEMP * 10;
float32_u res;
res.f = BASE_TEMP;
/**
* ad = (4095*rt)/(rt+10000)
*
* rt = (ad*NTC_SERIES_RESISTOR*CPU_VREF)/(NTC_VREF*4095-CPU_VREF*ad)
*/
rt = (adc * NTC_SERIES_RESISTOR * CPU_VREF) / (NTC_VREF * 4095 - CPU_VREF * adc);
index = ntc_lookup(_table, rt);
if (rt >= _table[0])
return res;
if (rt <= *(_table + TABLE_SIZE - 1))
{
result = (TABLE_SIZE - 1) * 10 + base;
}
else
{
data = _table[index] - _table[index + 1];
t = 10 * (_table[index] - rt) / data;
result = base + index * 10 + t;
}
res.f = result / 10.0;
return res;
}

View File

@ -0,0 +1,15 @@
/**
* @file ntc_3950.h
* @author xxx
* @date 2023-08-30 14:05:55
* @brief ntc_3950.h
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#ifndef __NTC_B3950_H__
#define __NTC_B3950_H__
#include "main.h"
extern float32_u ntc_get_temp(uint16_t adc); ///< 获取温度值
#endif ///< __NTC_B3950_H__

View File

@ -0,0 +1,560 @@
/**
* @file rtc_rx8010.c
* @author xxx
* @date 2023-08-30 08:58:43
* @brief RTC芯片RX8010的应用功能
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "rtc_rx8010.h"
#include "i2cs.h"
#include "delay.h"
#define RTC_RX8010_SDA_PORT RTC_SDA_GPIO_Port
#define RTC_RX8010_SDA_PIN RTC_SDA_Pin
#define RTC_RX8010_SCL_PORT RTC_SCL_GPIO_Port
#define RTC_RX8010_SCL_PIN RTC_SCL_Pin
static i2c_t *rtc;
static TIM_TypeDef *_timer_us;
static void _delay_us(uint32_t us)
{
if (_timer_us != NULL)
{
delay_hardware_us(_timer_us, us);
}
else
{
delay_us(us);
}
}
/* sec, min, hour, week, day, month, year */
// static uint8_t calendar[7] = {0, 0, 0, 1, 29, 2, 98};
/**
* @brief RTC芯片的指定地址读取一个字节数据
* @param {uint8_t} *read_buf
* @param {uint8_t} addr
* @return {*}
*/
static BOOL rtc_read_byte(uint8_t *read_buf, uint8_t addr)
{
uint8_t *p = read_buf;
/* 发送起始信号 */
rtc->interface.start(rtc);
/* 发送从机地址 + 读写方向 */
rtc->interface.write_byte(rtc, RTC_WR_ADDR); /* 此处是写方向,因为要发送读地址 */
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 发送读地址 */
rtc->interface.write_byte(rtc, addr);
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 重新发送起始信号。前面的代码的目的向RTC传送地址下面开始读取数据 */
rtc->interface.start(rtc);
/* 发送从机地址 + 读写方向 */
rtc->interface.write_byte(rtc, RTC_RD_ADDR); /* 此处是读方向,因为要开始读数据了 */
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 读取数据 */
*p = rtc->interface.read_byte(rtc, FALSE); /* 读1个字节 */
/* 命令执行成功发送I2C总线停止信号 */
rtc->interface.stop(rtc);
return TRUE;
}
/**
* @brief RTC芯片的指定地址读取若干数据
* @param {uint8_t} *read_buf
* @param {uint8_t} addr
* @param {int} size
* @return {*}
*/
static BOOL rtc_read_bytes(uint8_t *read_buf, uint8_t addr, int size)
{
int i = 0;
/* 发送起始信号 */
rtc->interface.start(rtc);
/* 发送从机地址 + 读写方向 */
rtc->interface.write_byte(rtc, RTC_WR_ADDR); /* 此处是写方向,因为要发送读地址 */
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 发送读地址 */
rtc->interface.write_byte(rtc, addr);
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 重新发送起始信号。前面的代码的目的向RTC传送地址下面开始读取数据 */
rtc->interface.start(rtc);
/* 发送从机地址 + 读写方向 */
rtc->interface.write_byte(rtc, RTC_RD_ADDR); /* 此处是读方向,因为要开始读数据了 */
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 循环读取数据RTC芯片地址自动自增 */
for (i = 0; i < size; i++)
{
/* 每读完1个字节后需要发送Ack 最后一个字节需要发Nack */
if (i != (size - 1))
{
read_buf[i] = rtc->interface.read_byte(rtc, TRUE); /* 读1个字节 */
}
else
{
read_buf[i] = rtc->interface.read_byte(rtc, FALSE); /* 读1个字节 */
}
}
/* 命令执行成功发送I2C总线停止信号 */
rtc->interface.stop(rtc);
return TRUE;
}
/**
* @brief RTC芯片的指定地址写入一个数据
* @param {uint8_t} data
* @param {uint8_t} addr
* @return {*}
* @note
*/
static BOOL rtc_write_byte(uint8_t data, uint8_t addr)
{
int retry = 0;
/* 尝试与RTC芯片建立I2C通讯 */
for (retry = 0; retry < 100; retry++)
{
rtc->interface.start(rtc); /* 发送起始信号 */
rtc->interface.write_byte(rtc, RTC_WR_ADDR); /* 发送从机地址 + 读写方向 */
if (rtc->interface.wait_ack(rtc) == TRUE)
{
break;
}
}
if (retry == 100)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 发送起始写地址 */
rtc->interface.write_byte(rtc, addr);
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 写入数据 */
rtc->interface.write_byte(rtc, data);
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 命令执行成功发送I2C总线停止信号 */
rtc->interface.stop(rtc);
return TRUE;
}
/**
* @brief RTC芯片的指定地址写入若干数据
* @param {uint8_t} *write_buf
* @param {uint8_t} addr
* @param {int} size
* @return {*}
* @note
*/
static BOOL rtc_write_bytes(uint8_t *write_buf, uint8_t addr, int size)
{
int i = 0;
int retry = 0;
for (i = 0; i < size; i++)
{
if (i == 0)
{
/* 尝试与RTC芯片建立I2C通讯 */
for (retry = 0; retry < 100; retry++)
{
rtc->interface.start(rtc); /* 发送起始信号 */
rtc->interface.write_byte(rtc, RTC_WR_ADDR); /* 发送从机地址 + 读写方向 */
if (rtc->interface.wait_ack(rtc) == TRUE)
{
break;
}
}
if (retry == 100)
{
rtc->interface.stop(rtc);
return FALSE;
}
/* 发送起始写地址 */
rtc->interface.write_byte(rtc, addr);
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
}
/* 循环写入数据RTC芯片地址自动自增 */
rtc->interface.write_byte(rtc, write_buf[i]);
if (rtc->interface.wait_ack(rtc) != TRUE)
{
rtc->interface.stop(rtc);
return FALSE;
}
}
/* 命令执行成功发送I2C总线停止信号 */
rtc->interface.stop(rtc);
return TRUE;
}
/**
* @brief RTC芯片RTC响应
* @return {*}
* @note
*/
static void rtc_dummy_read(void)
{
rtc->interface.start(rtc);
rtc->interface.write_byte(rtc, RTC_WR_ADDR);
rtc->interface.write_byte(rtc, 0x20);
rtc->interface.start(rtc);
rtc->interface.write_byte(rtc, RTC_RD_ADDR);
rtc->interface.read_byte(rtc, FALSE);
rtc->interface.stop(rtc);
}
/**
* @brief VLF0x1e bit[1]
* @return {uint8_t} 0 = VLF位为01 = VLF位为1
* @note
*/
static uint8_t rtc_check_vlf(void)
{
uint8_t flag_register = 1;
uint8_t vlf = 0;
rtc_read_byte(&flag_register, RTC_FLAG_ADDR);
vlf = (flag_register & 0x02);
if (vlf == 0)
{
return 0;
}
else
{
return 1;
}
}
/**
* @brief VLF位清除0x1e bit[1]
* @return {uint8_t} 0 = 1 = 2 =
*/
static uint8_t rtc_wait_vlf_clear(void)
{
uint8_t ret = 1;
uint8_t i = 0;
uint8_t vlf;
for (i = 0; i < 10; i++)
{
vlf = rtc_check_vlf();
if (vlf == 0)
{
ret = ((i > 0) ? 0 : 2);
return ret;
}
/* 清除VLF */
rtc_write_byte(0, RTC_FLAG_ADDR);
}
return ret;
}
/**
* @brief
* @return {BOOL} FALSE = TRUE =
*/
static BOOL rtc_soft_reset(void)
{
BOOL ret = FALSE;
ret = rtc_write_byte(0x00, 0x1f);
ret = rtc_write_byte(0x80, 0x1f);
ret = rtc_write_byte(0xd3, 0x60);
ret = rtc_write_byte(0x03, 0x66);
ret = rtc_write_byte(0x02, 0x6b);
ret = rtc_write_byte(0x01, 0x6b);
if (ret == 0)
{
_delay_us(2000);
}
return ret;
}
/**
* @brief
* @return {BOOL} TRUE = FALSE =
*/
static BOOL rtc_clock_reginit(void)
{
BOOL ret = FALSE;
/* set reserve register */
ret = rtc_write_byte(RTC_REG17_DATA, RTC_REG17_ADDR);
ret = rtc_write_byte(RTC_REG30_DATA, RTC_REG30_ADDR);
ret = rtc_write_byte(RTC_REG31_DATA, RTC_REG31_ADDR);
ret = rtc_write_byte(RTC_IRQ_DATA, RTC_IRQ_ADDR);
/* write 0x04 to reg_0x1d */
ret = rtc_write_byte(0x04, 0x1d);
/* write 0x00 to reg_0x1e */
ret = rtc_write_byte(0x00, 0x1e);
/* stop clock */
ret = rtc_write_byte(0x40, RTC_CONTROL_ADDR);
/* set the present time */
// ret = rtc_write_bytes(calendar, RTC_CLOCK_ADDR, sizeof(calendar));
/* start clock */
ret = rtc_write_byte(0x00, RTC_CONTROL_ADDR);
return ret;
}
/**
* @brief RTC芯片初始化
* @return {BOOL} TRUE = FALSE =
* @note
*/
BOOL rtc_init(TIM_TypeDef *timer_us)
{
if (timer_us != NULL)
{
_timer_us = timer_us;
ENABLE_TIM_COUNT(_timer_us);
}
i2c_gpio_group_t gpios;
int ret = 1;
gpios.scl = gpio_create(RTC_RX8010_SCL_PORT, RTC_RX8010_SCL_PIN);
gpios.sda = gpio_create(RTC_RX8010_SDA_PORT, RTC_RX8010_SDA_PIN);
rtc = i2c_create(gpios, 10);
rtc_dummy_read();
/* wait for VLF bit clear */
ret = rtc_wait_vlf_clear();
if (ret == 0)
{
/* software reset */
ret = rtc_soft_reset();
if (ret == FALSE)
{
return FALSE;
}
}
else if (ret == 1)
{
return FALSE;
}
/* register initialize */
return rtc_clock_reginit();
}
/**
* @brief RTC芯片反初始化
* @return {*}
* @note
*/
BOOL rtc_dinit(void)
{
GPIO_SET_ANALOG(RTC_RX8010_SCL_PORT, RTC_RX8010_SCL_PIN);
GPIO_SET_ANALOG(RTC_RX8010_SDA_PORT, RTC_RX8010_SDA_PIN);
return TRUE;
}
/**
* @brief RTC芯片读取时间
* @param {uint8_t} *read_buf -
* @return {BOOL} TRUE = FALSE =
* @note
*/
BOOL rtc_get_clock_time(uint8_t *read_buf)
{
return rtc_read_bytes(read_buf, RTC_CLOCK_ADDR, 7);
}
/**
* @brief RTC芯片写入时间
* @param {rtc_date} *data -
* @return {BOOL} TRUE = FALSE =
* @note
*/
BOOL rtc_set_clock_time(rtc_date *data)
{
BOOL ret = FALSE;
uint8_t tmp[7];
tmp[0] = data->second;
tmp[1] = data->minute;
tmp[2] = data->hour;
tmp[3] = data->weekday;
tmp[4] = data->day;
tmp[5] = data->month;
tmp[6] = data->year;
tmp[3] = (rtc_week_e)tmp[3]; // 改成星期几
/* stop clock */
ret = rtc_write_byte(0x40, RTC_CONTROL_ADDR);
/* set the present time */
ret = rtc_write_bytes(tmp, RTC_CLOCK_ADDR, sizeof(tmp));
/* start clock */
ret = rtc_write_byte(0x00, RTC_CONTROL_ADDR);
return ret;
}
/**
* RTC
*
* RTC设备中获取当前的日期和时间197011
* RTC设备中获取时间0
*
* @return 1970110
*/
uint32_t rtc_timestamp(void)
{
BOOL ret = FALSE;
uint8_t tmp[7];
rtc_date_t date;
rtc_time_t time;
ret = rtc_get_clock_time(tmp);
if (ret == FALSE)
{
return 0;
}
date.year = hex_format_dec(tmp[6]);
date.month = hex_format_dec(tmp[5]);
date.day = hex_format_dec(tmp[4]);
time.hour = hex_format_dec(tmp[2]);
time.minute = hex_format_dec(tmp[1]);
time.second = hex_format_dec(tmp[0]);
return time2stamp(&date, &time);
}
/**
* @brief
* @param {uint8_t} *weekday
* @return {*}
* @note
*/
void rtc_weekday_convert(uint8_t *weekday)
{
switch (*weekday)
{
case 1:
*weekday = MON;
break;
case 2:
*weekday = TUE;
break;
case 3:
*weekday = WED;
break;
case 4:
*weekday = THUR;
break;
case 5:
*weekday = FRI;
break;
case 6:
*weekday = SAT;
break;
case 7:
*weekday = SUN;
break;
default:
*weekday = 0;
break;
}
}
/**
* @brief
* @param {uint8_t} *weekday
* @return {*}
* @note
*/
void rtc_weekday_rconvert(uint8_t *weekday)
{
switch (*weekday)
{
case MON:
*weekday = 1;
break;
case TUE:
*weekday = 2;
break;
case WED:
*weekday = 3;
break;
case THUR:
*weekday = 4;
break;
case FRI:
*weekday = 5;
break;
case SAT:
*weekday = 6;
break;
case SUN:
*weekday = 7;
break;
default:
*weekday = 0;
break;
}
}

View File

@ -0,0 +1,99 @@
/**
* @file rtc_rx8010.h
* @author xxx
* @date 2023-08-30 14:05:55
* @brief rtc_rx8010.h
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#ifndef __RTC_RX8010_H__
#define __RTC_RX8010_H__
#include "main.h"
#define RTC_DEVICE_ADDR 0x32
#define RTC_WR_ADDR ((RTC_DEVICE_ADDR << 1) | 0)
#define RTC_RD_ADDR ((RTC_DEVICE_ADDR << 1) | 1)
#define RTC_FLAG_ADDR 0x1e
#define RTC_CLOCK_ADDR 0x10
#define RTC_CONTROL_ADDR 0x1f
#define RTC_REG17_ADDR 0x17
#define RTC_REG17_DATA 0xd8
#define RTC_REG30_ADDR 0x30
#define RTC_REG30_DATA 0x00
#define RTC_REG31_ADDR 0x31
#define RTC_REG31_DATA 0x08
#define RTC_IRQ_ADDR 0x32
#define RTC_IRQ_DATA 0x00
typedef enum
{
SUN = BIT0,
MON = BIT1,
TUE = BIT2,
WED = BIT3,
THUR = BIT4,
FRI = BIT5,
SAT = BIT6
} 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
} rtc_date;
/**
* @brief Initializes the RTC module.
* @return TRUE if the initialization is successful, FALSE otherwise.
*/
extern BOOL rtc_init(TIM_TypeDef *timer_us);
/**
* @brief Deinitializes the RTC module.
* @return TRUE if the deinitialization is successful, FALSE otherwise.
*/
extern BOOL rtc_dinit(void);
/**
* @brief Retrieves the current clock time from the RTC module.
* @param read_buf Pointer to the buffer to store the clock time.
* @return TRUE if the clock time is successfully retrieved, FALSE otherwise.
*/
extern BOOL rtc_get_clock_time(uint8_t *read_buf);
/**
* @brief Sets the clock time in the RTC module.
* @param data Pointer to the RTC date structure containing the new clock time.
* @return TRUE if the clock time is successfully set, FALSE otherwise.
*/
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.
*/
extern void rtc_weekday_convert(uint8_t *weekday);
/**
* @brief Converts the weekday value from a human-readable format to the RTC format.
* @param weekday Pointer to the weekday value to be converted.
*/
extern void rtc_weekday_rconvert(uint8_t *weekday);
#endif ///< !__RTC_RX8010_H__

181
User/system/driver/sht40.c Normal file
View File

@ -0,0 +1,181 @@
#include "sht40.h"
#include "i2cs.h"
#include "delay.h"
#define SHT40_SDA_PORT I2C1_SDA_GPIO_Port
#define SHT40_SDA_PIN I2C1_SDA_Pin
#define SHT40_SCL_PORT I2C1_SCL_GPIO_Port
#define SHT40_SCL_PIN I2C1_SCL_Pin
#define SHT40_I2C_ADDRESS 0x44
#define SHT40_MEASURE_CMD 0xFD // 2*8-bit T-data:8-bit CRC:2*8-bit RH-data: 8-bit CRC
static i2c_t *_sht40_i2c;
static TIM_TypeDef *_timer_us;
static uint8_t crc8(uint8_t *data, uint8_t len);
static void _delay_us(uint32_t us)
{
if (_timer_us != NULL)
{
delay_hardware_us(_timer_us, us);
}
else
{
delay_us(us);
}
}
void sht40_test(void)
{
float32 temperature = 0;
float32 humidity = 0;
sht40_read(&temperature, &humidity);
__NOP();
}
/**
* @brief SHT40
*
* SHT40 I2C GPIO I2C
*
* sht40_i2c SHT40
*/
void sht40_init(TIM_TypeDef *timer_us)
{
DBG_ASSERT(timer_us != NULL __DBG_LINE);
if (timer_us != NULL)
{
_timer_us = timer_us;
ENABLE_TIM_COUNT(_timer_us);
}
i2c_gpio_group_t gpios;
gpios.scl = gpio_create(SHT40_SCL_PORT, SHT40_SCL_PIN);
gpios.sda = gpio_create(SHT40_SDA_PORT, SHT40_SDA_PIN);
_sht40_i2c = i2c_create(gpios, 10);
DBG_ASSERT(_sht40_i2c != NULL __DBG_LINE);
// sht40_test(); // 测试 SHT40
}
/**
* @brief SHT40
*
* SHT40 湿便湿
*
*
*/
void sht40_dinit(void)
{
GPIO_SET_ANALOG(SHT40_SDA_PORT, SHT40_SDA_PIN);
GPIO_SET_ANALOG(SHT40_SCL_PORT, SHT40_SCL_PIN);
}
/**
* @brief 湿
*
* 湿湿
*
* @param temperature
* @param humidity 湿
*/
BOOL sht40_read(float32 *temperature, float32 *humidity)
{
uint8_t data[6];
osel_memset(data, 0, ARRAY_LEN(data));
// 发送开始信号
_sht40_i2c->interface.start(_sht40_i2c);
// 发送写入地址命令
_sht40_i2c->interface.write_byte(_sht40_i2c, SHT40_I2C_ADDRESS << 1);
// 等待写入地址命令响应
if (_sht40_i2c->interface.wait_ack(_sht40_i2c) == FALSE)
{
return FALSE;
}
// 发送测量命令
_sht40_i2c->interface.write_byte(_sht40_i2c, SHT40_MEASURE_CMD);
// 等待测量命令响应
if (_sht40_i2c->interface.wait_ack(_sht40_i2c) == FALSE)
{
return FALSE;
}
// 停止I2C总线
_sht40_i2c->interface.stop(_sht40_i2c);
_delay_us(10000); // 根据 SHT40 数据手册,等待至少 10ms
// 发送开始信号
_sht40_i2c->interface.start(_sht40_i2c);
// 发送写入地址命令
_sht40_i2c->interface.write_byte(_sht40_i2c, (SHT40_I2C_ADDRESS << 1) | 1);
// 等待写入地址命令响应
if (_sht40_i2c->interface.wait_ack(_sht40_i2c) == FALSE)
{
return FALSE;
}
for (uint8_t i = 0; i < ARRAY_LEN(data); i++)
{
if (i == 5)
{
data[i] = _sht40_i2c->interface.read_byte(_sht40_i2c, FALSE);
}
else
{
data[i] = _sht40_i2c->interface.read_byte(_sht40_i2c, TRUE);
}
}
// 停止I2C总线
_sht40_i2c->interface.stop(_sht40_i2c);
*temperature = 0;
*humidity = 0;
if (crc8(&data[0], 2) != data[2] || crc8(&data[3], 2) != data[5])
{
return FALSE;
}
else
{
*temperature = (float32)((uint16_t)data[0] << 8 | data[1]) * 175 / 65535 - 45;
*humidity = (float32)((uint16_t)data[3] << 8 | data[4]) * 125 / 65535 - 6;
if (*humidity > 100)
{
*humidity = 100;
}
if (*humidity < 0)
{
*humidity = 0;
}
return TRUE;
}
}
/**
* @brief crc8校验函数 x^8 + x^5 + x^4 + 1
* @param data
* @param len
* @retval
* @note SHT3温湿度传感器的数据校验
*/
static uint8_t crc8(uint8_t *data, uint8_t len)
{
const uint8_t polynomial = 0x31;
uint8_t crc = 0xFF;
int i, j;
for (i = 0; i < len; ++i)
{
crc ^= *data++;
for (j = 0; j < 8; ++j)
{
crc = (crc & 0x80) ? (crc << 1) ^ polynomial : (crc << 1);
}
}
return crc;
}

View File

@ -0,0 +1,9 @@
#ifndef __SHT40_H
#define __SHT40_H
#include "main.h"
void sht40_init(TIM_TypeDef *timer_us); ///< 初始化 SHT40 传感器
void sht40_dinit(void); ///< 反初始化 SHT40 传感器
BOOL sht40_read(float32 *temperature, float32 *humidity); ///< 读取温湿度传感器数据
#endif ///< !__SHT40_H

View File

@ -1,21 +0,0 @@
/***
* @Author:
* @Date: 2023-04-11 18:31:07
* @LastEditors: xxx
* @LastEditTime: 2023-04-11 18:31:20
* @Description:
* @email:
* @Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
void delay_init(uint16_t sysclk); /* 初始化延迟函数 */
void delay_ms(uint16_t nms); /* 延时nms */
void delay_us(uint32_t nus); /* 延时nus */
void delay_tick(uint32_t ticks); /* 延时ticks */
#endif

View File

@ -0,0 +1,38 @@
#include "pid_c.h"
/**
* @brief PID控制器参数
* @param {PID_C} *self - PID控制器结构体指针
* @param {float32} kp -
* @param {float32} ki -
* @param {float32} kd -
* @param {float32} out_min -
* @param {float32} out_max -
* @return {*} -
*/
static void _set_ctrl_prm(struct PID_C *self, float32 kp, float32 ki, float32 kd, float32 out_min, float32 out_max)
{
self->pri.kp = kp; /*比例系数*/
self->pri.ki = ki; /*积分系数*/
self->pri.kd = kd; /*微分系数*/
self->pri.deadband = 0.5; /*死区*/
self->pri.maximum = out_max; /*最大输出*/
self->pri.minimum = out_min; /*最小输出*/
self->pri.last_error = 0; /*上一次误差*/
self->pri.prev_error = 0; /*上上次误差*/
}
static float32 _PID(struct PID_C *self, float32 target, float32 feedback)
{
/**
* PID算法
*/
return 0;
}
void pid_c_constructor(struct PID_C *self)
{
self->set_ctrl_prm = _set_ctrl_prm;
self->PID = _PID;
}

View File

@ -0,0 +1,34 @@
#ifndef __PID_C_H__
#define __PID_C_H__
#include "lib.h"
typedef struct PID_C
{
/* 设置PID三个参数 */
void (*set_ctrl_prm)(struct PID_C *self, float32 kp, float32 ki, float32 kd, float32 out_min, float32 out_max);
/* 控制接口 */
float32 (*PID)(struct PID_C *self, float32 target, float32 feedback);
// 自定义参数
/* 实际值与目标值之间的误差 */
float32 err;
/* 输出值 */
float32 out;
/* private */
struct
{
float32 kp; /*比例学习速度*/
float32 ki; /*积分学习速度*/
float32 kd; /*微分学习速度*/
float32 ki_error; /*积分误差*/
float32 last_error; /*前一拍偏差*/
float32 prev_error; /*前两拍偏差*/
float32 deadband; /*死区*/
float32 maximum; /*输出值的上限*/
float32 minimum; /*输出值的下限*/
} pri;
} pid_c_t;
extern void pid_c_constructor(struct PID_C *self);
#endif // __PID_C_H__

View File

@ -0,0 +1,285 @@
#include "pid_g.h"
#include <math.h>
/**
* @brief PID积分及微分控制数据
* @param {PID_G} *self
* @return {*}
*/
static void _restctrl(struct PID_G *self)
{
self->pri.pre_error = 0;
self->pri.sum_iterm = 0;
}
/**
* @brief
* @param {PID_G} *self
* @param {float32} out_min
* @param {float32} out_max
* @return {*}
* @note
*/
static void _set_range(struct PID_G *self, float32 out_min, float32 out_max)
{
self->pri.out_max = out_max;
self->pri.out_min = out_min;
}
/**
* @brief kp
* @param {PID_G} *self
* @param {float32} kp
* @return {*}
* @note
*/
static void _set_kp(struct PID_G *self, float32 kp)
{
self->pri.kp = kp;
}
/**
* @brief ki
* @param {PID_G} *self
* @param {float32} ki
* @return {*}
* @note
*/
static void _set_ki(struct PID_G *self, float32 ki)
{
self->pri.ki = ki;
}
/**
* @brief kd
* @param {PID_G} *self
* @param {float32} kd
* @return {*}
* @note
*/
static void _set_kd(struct PID_G *self, float32 kd)
{
self->pri.kd = kd;
}
/**
* @brief 使
* @param {PID_G} *self
* @param {BOOL} enable
* @return {*}
* @note
*/
static void _set_ki_enable(struct PID_G *self, BOOL enable)
{
self->pri.ki_enable = enable;
}
/**
* @brief 使
* @param {PID_G} *self
* @param {BOOL} enable
* @return {*}
* @note
*/
static void _set_kd_enable(struct PID_G *self, BOOL enable)
{
self->pri.kd_enable = enable;
}
/**
* @brief
* @return {*}
* @note
*/
static void _set_ctrl_prm(struct PID_G *self, float32 kp, float32 ki, float32 kd, float32 err_dead, float32 out_min, float32 out_max)
{
g_param_t *pri = &self->pri;
osel_memset((uint8_t *)pri, 0, sizeof(pid_g_t));
pri->kp = kp;
pri->ki = ki;
pri->kd = kd;
pri->err_dead = err_dead;
pri->out_max = out_max;
pri->out_min = out_min;
pri->detach = FALSE;
}
static void _update_ctrl_prm(struct PID_G *self, float32 kp, float32 ki, float32 kd, float32 err_dead, float32 out_min, float32 out_max)
{
g_param_t *pri = &self->pri;
pri->kp = kp;
pri->ki = ki;
pri->kd = kd;
pri->err_dead = err_dead;
pri->out_max = out_max;
pri->out_min = out_min;
pri->detach = FALSE;
}
/**
* @brief 0+PID,PID
* @param {PID_G} *self
* @param {float32} max_err
* @param {BOOL} mode
* @return {*}
*/
static void _set_cfg(struct PID_G *self, float32 max_err, BOOL mode)
{
self->pri.err_limit = max_err;
self->pri.detach = mode == FALSE ? FALSE : TRUE;
}
/**
* @brief
* @param {PID_G} *self
* @param {float32} max_weight
* @return {*}
* @note
*/
static void _set_weight(struct PID_G *self, float32 max_ratio, BOOL mode)
{
self->pri.ui_ratio = max_ratio;
self->pri.weight = mode == FALSE ? FALSE : TRUE;
}
/**
* @brief PID算法函数
* @param {PID_G} *self
* @param {float32} target
* @param {float32} feedback
* @return {*}
* @note
*/
static float32 _PID(struct PID_G *self, float32 target, float32 feedback)
{
float32 error = 0.0f;
float32 insert = 0.0f; ///< 该值为0时积分不介入计算
float32 temp_iterm = 0.0f;
float32 temp_kd = 0.0f;
g_param_t *pri = &self->pri;
pri->ref = target; ///< 目标位置
pri->feed_back = feedback; ///< 实际位置
pri->error = pri->ref - pri->feed_back; /// 误差
error = pri->error;
if (fabs(pri->error) <= pri->err_dead) ///< 误差小于死区,不计算
{
error = 0;
}
/*根据PID配置的模式,获取积分数据,进行积分累加*/
if (pri->out >= pri->out_max) ///< 到达输出上限
{
if (fabs(error) > pri->err_limit && pri->detach) ///< 误差大于积分介入区间,积分不介入计算
{
insert = 0;
}
else
{
insert = 1;
if (error < 0)
{
temp_iterm = pri->ki * error;
}
}
}
else if (pri->out <= pri->out_min) ///< 到达输出下限
{
if (fabs(error) > pri->err_limit && pri->detach) ///< 误差大于积分介入区间,积分不介入计算
{
insert = 0;
}
else
{
insert = 1;
if (error > 0)
{
temp_iterm = pri->ki * error;
}
}
}
else
{
if (fabs(error) > pri->err_limit && pri->detach)
{
insert = 0;
}
else
{
insert = 1;
temp_iterm = pri->ki * error;
}
}
if (pri->ki_enable == FALSE)
{
temp_iterm = 0;
insert = 0;
}
/* integral */
pri->sum_iterm += temp_iterm;
if (pri->weight == TRUE)
{
if (pri->sum_iterm > pri->ui_ratio)
{
pri->sum_iterm = pri->ui_ratio;
}
else if (pri->sum_iterm < -pri->ui_ratio)
{
pri->sum_iterm = -pri->ui_ratio;
}
}
else
{
if (pri->sum_iterm > pri->out_max)
{
pri->sum_iterm = pri->out_max;
}
else if (pri->sum_iterm < pri->out_min)
{
pri->sum_iterm = pri->out_min;
}
}
/* differential */
if (pri->kd_enable == TRUE)
{
temp_kd = pri->kd;
}
else
{
temp_kd = 0;
}
pri->out = pri->kp * pri->error + pri->sum_iterm * insert + (pri->error - pri->pre_error) * temp_kd;
pri->pre_error = pri->error; ///< 记录这次误差,为下次微分计算做准备
pri->pre_feed_back = pri->feed_back;
/*limt pid output*/
pri->out = RANGE(pri->out, pri->out_min, pri->out_max); ///< 限制输出
return pri->out;
}
/**
* @brief PID接口
* @param {PID_G} *self
* @return {*}
* @note
*/
void pid_g_constructor(struct PID_G *self)
{
self->set_ctrl_prm = _set_ctrl_prm;
self->update_ctrl_prm = _update_ctrl_prm;
self->set_cfg = _set_cfg;
self->set_kp = _set_kp;
self->set_ki_enable = _set_ki_enable;
self->set_ki = _set_ki;
self->set_kd_enable = _set_kd_enable;
self->set_kd = _set_kd;
self->set_range = _set_range;
self->restctrl = _restctrl;
self->PID = _PID;
self->set_weight = _set_weight;
}

View File

@ -0,0 +1,65 @@
#ifndef __PID_G_H__
#define __PID_G_H__
#include "lib.h"
typedef struct
{
float32 ref; /*目标*/
float32 feed_back; /*实际*/
float32 pre_feed_back; /*上一次实际*/
float32 kp; /*比例学习速度*/
float32 ki; /*积分学习速度*/
float32 kd; /*微分学习速度*/
float32 ki_error; /*积分误差*/
float32 error; /*误差*/
float32 pre_error; /*前一拍偏差*/
float32 prev_error; /*前两拍偏差*/
float32 err_dead; /*死区*/
float32 err_limit; /*积分分离上限*/
float32 maximum; /*输出值的上限*/
float32 minimum; /*输出值的下限*/
float32 out; /*输出值*/
float32 sum_iterm; /*积分累加*/
float32 ui_ratio; /*积分权重*/
BOOL ki_enable; /*积分使能*/
BOOL kd_enable; /*微分使能*/
BOOL detach; /*积分分离标志*/
BOOL weight; /*积分权重标志*/
float32 out_max; /*输出最大值*/
float32 out_min; /*输出最小值*/
} g_param_t;
typedef struct PID_G
{
/* 设置PID三个参数 */
void (*set_ctrl_prm)(struct PID_G *self, float32 kp, float32 ki, float32 kd, float32 err_dead, float32 out_min, float32 out_max);
/* 更新PID参数 */
void (*update_ctrl_prm)(struct PID_G *self, float32 kp, float32 ki, float32 kd, float32 err_dead, float32 out_min, float32 out_max);
/* 控制接口 */
float32 (*PID)(struct PID_G *self, float32 target, float32 feedback);
/* 更新控制区间 */
void (*set_range)(struct PID_G *self, float32 out_min, float32 out_max);
/* 设置积分分离 */
void (*set_cfg)(struct PID_G *self, float32 max_err, BOOL mode);
/* 设置积分权重 */
void (*set_weight)(struct PID_G *self, float32 max_ratio, BOOL mode);
/* 更新kp */
void (*set_kp)(struct PID_G *self, float32 kp);
/* 使能ki */
void (*set_ki_enable)(struct PID_G *self, BOOL enable);
/* 更新ki */
void (*set_ki)(struct PID_G *self, float32 ki);
/* 使能kd */
void (*set_kd_enable)(struct PID_G *self, BOOL enable);
/* 更新kd */
void (*set_kd)(struct PID_G *self, float32 kd);
/* 复位PID积分及微分控制数据 */
void (*restctrl)(struct PID_G *self);
/* private */
g_param_t pri;
} pid_g_t;
extern void pid_g_constructor(struct PID_G *self);
#endif // __PID_G_H__

View File

@ -0,0 +1,166 @@
#include "pid_hd.h"
#include <math.h>
#include "sys.h"
#include "app.h"
#if INCOMPLETE_DIFFEREN_HD == 1 // 积分分离
/*计算微分项,使用追随误差微分项*/
static float32 td_derivative(struct PID_HD *self, float32 current_err, float32 pre_err, float32 dt)
{
pid_hd_position_t *pri = &self->pri_u.position;
float32 derivative = (current_err - pre_err) / dt; // 计算积分项
derivative = pri->td_alpha * derivative + (1 - pri->td_alpha) * pri->td_beta * pri->pre_derivative; // 追随误差微分器平滑输出
pri->pre_derivative = derivative; // 更新上一次误差
return derivative;
}
#endif
/*杭电设置位置式PID参数*/
static void _set_ctrl_prm_position(struct PID_HD *self, float32 kp, float32 ki, float32 kd)
{
pid_hd_position_t *pri = &self->pri_u.position;
osel_memset((uint8_t *)pri, 0, sizeof(pid_hd_position_t));
/*观测传进来的Kp、Ki、Kd*/
pri->kp = kp;
pri->ki = ki;
pri->kd = kd;
pri->ki_limit = 10; // 积分分离界限
pri->err_dead = 0.5; // 控制死区范围
#if INCOMPLETE_DIFFEREN_HD == 1
/*不完全微分系数*/
pri->td_alpha = 0.5;
pri->td_beta = 0.5;
#endif
}
/*杭电:设置输出限幅参数*/
static void _set_out_prm_position(struct PID_HD *self, float32 maximum, float32 minimum)
{
self->pri_u.position.out_max = maximum;
self->pri_u.position.out_min = minimum;
}
/*杭电位置式PID控制算法*/
static float32 _pid_position(struct PID_HD *self, float32 err)
{
/*计算控制的运行时间*/
// sys_millis_reset();
self->pri_u.position.control_time = sys_millis();
self->pri_u.position.tmp_time = 0;
/*测试4.18*/
if (fabs(err) < 0.1)
{
err = 0;
}
float32 x[3];
self->pri_u.position.err = err;
/*抗积分饱和*/
#if INTEGRAL_SEPARATION == 1 // 积分分离
if (self->pri_u.position.out > self->pri_u.position.out_max)
{
if (self->pri_u.position.err > self->pri_u.position.ki_limit) // 积分分离
{
self->pri_u.position.ki_error += 0;
}
else
{
if (self->pri_u.position.err < 0) // 若偏差为负值,执行负偏差的累加
{
self->pri_u.position.ki_error += self->pri_u.position.err;
}
}
}
else if (self->pri_u.position.out < self->pri_u.position.out_min)
{
if (self->pri_u.position.err > self->pri_u.position.ki_limit) // 若偏差为负值,停止积分
{
self->pri_u.position.ki_error += 0;
}
else
{
if (self->pri_u.position.err > 0) // 若偏差为正值,执行正偏差的累加
{
self->pri_u.position.ki_error += self->pri_u.position.err;
}
}
}
else
{
if (fabs(err) > self->pri_u.position.ki_limit || fabs(err) < 0.5)
{
self->pri_u.position.ki_error += 0;
}
else
{
self->pri_u.position.ki_error += self->pri_u.position.err;
}
}
#else /*无积分分离操作*/
if (fabs(err) < 0.4)
{
self->pri_u.position.ki_error += 0;
}
else
{
self->pri_u.position.ki_error += self->pri_u.position.err;
}
#endif
/*输出*/
if (fabs(err) < self->pri_u.position.err_dead)
{
/*输出上一次的值*/
// self->pri_u.position.out = self->pri_u.position.pre_out;
x[0] = self->pri_u.position.err;
x[1] = self->pri_u.position.ki_error;
self->pri_u.position.out = self->pri_u.position.kp * x[0] + self->pri_u.position.ki * x[1] + self->pri_u.position.kd * x[2];
}
else
{
x[0] = self->pri_u.position.err;
x[1] = self->pri_u.position.ki_error;
#if INCOMPLETE_DIFFEREN_HD == 1
/*不完全微分项为了解决普通PID为微分环节容易振荡的问题*/
self->pri_u.position.tmp_time = sys_millis();
self->pri_u.position.control_time -= self->pri_u.position.tmp_time;
self->pri_u.position.control_time /= 1000.0; // 将单位转换为秒
x[2] = td_derivative(&_pid.pid_u.hd, err, self->pri_u.position.pre_error, self->pri_u.position.control_time);
#else
// 普通的微分环节
x[2] = self->pri_u.position.err - self->pri_u.position.pre_error;
#endif
self->pri_u.position.out = self->pri_u.position.kp * x[0] + self->pri_u.position.ki * x[1] + self->pri_u.position.kd * x[2];
}
/*输出限幅*/
if (self->pri_u.position.out > self->pri_u.position.out_max)
{
self->pri_u.position.out = self->pri_u.position.out_max;
}
if (self->pri_u.position.out < self->pri_u.position.out_min)
{
self->pri_u.position.out = self->pri_u.position.out_min;
}
// 更新误差历史
self->pri_u.position.pre_error = self->pri_u.position.err; /*上一次误差值*/
// 更新输出历史
self->pri_u.position.pre_out = self->pri_u.position.out; /*上一次输出值*/
return self->pri_u.position.out;
}
/*杭电:参数控制器*/
void pid_hd_constructor(struct PID_HD *self)
{
self->set_ctrl_prm_position = _set_ctrl_prm_position;
self->set_out_prm_position = _set_out_prm_position;
self->pid_position = _pid_position;
}

View File

@ -0,0 +1,66 @@
#ifndef __PID_HD__
#define __PID_HD__
#include "lib.h"
#define INTEGRAL_SEPARATION 1 // 积分分离
#define INCOMPLETE_DIFFEREN_HD 1 // 不完全微分
typedef struct
{
float32 ref;
float32 feed_back;
float32 pre_feed_back;
float32 pre_error;
float32 ki_error; /*积分误差*/
float32 ki_limit; /*积分分离界限*/
float32 ki_alpha; /*变积分的系数*/
float32 err;
float32 sum_iterm;
float32 kp;
float32 kp_small; /*在接近稳态时的Kp*/
float32 kp_big; /*在大范围时的Kp*/
float32 ki;
float32 kd;
float32 err_limit;
BOOL detach;
float32 err_dead;
#if INCOMPLETE_DIFFEREN_HD == 1
float32 td_alpha; /*不完全微分系数*/
float32 td_beta; /*不完全微分系数beta*/
float32 pre_derivative; /*上一次微分值*/
#endif
float32 out;
float32 pre_out;
float32 out_max;
float32 out_min;
BOOL sm;
float32 sv_range;
uint32_t control_time; /*控制算法运行一次花费的时间*/
uint32_t tmp_time; /*临时用来记录控制的运行时间*/
} pid_hd_position_t; // 位置式PID
typedef struct PID_HD
{
/* 设置PID三个参数 */
void (*set_ctrl_prm_position)(struct PID_HD *self, float32 kp, float32 ki, float32 kd);
/* 设置输出范围 */
void (*set_out_prm_position)(struct PID_HD *self, float32 maximum, float32 minimum);
/* 控制接口 */
float32 (*pid_position)(struct PID_HD *self, float32 err);
// 自定义参数
/* 实际值与目标值之间的误差 */
float32 err;
/* 输出值 */
float32 out;
/* private */
struct
{
pid_hd_position_t position;
} pri_u;
} pid_hd_t;
extern void pid_hd_constructor(struct PID_HD *self);
#endif // __PID_HD__

View File

@ -0,0 +1,481 @@
#include "pid_x.h"
#include "math.h"
#define LAG_PHASE (6) // 迟滞相位,单位:拍
#ifndef PI
#define PI 3.14159265358979f
#endif
// 注1自适应模糊pid最重要的就是论域的选择要和你应该控制的对象相切合
// 注2以下各阀值、限幅值、输出值均需要根据具体的使用情况进行更改
// 注3因为我的控制对象惯性比较大所以以下各部分取值较小
// 论域e:[-5,5] ec:[-0.5,0.5]
// 误差的阀值小于这个数值的时候不做PID调整避免误差较小时频繁调节引起震荡
#define Emin 0.3f
#define Emid 1.0f
#define Emax 5.0f
// 调整值限幅,防止积分饱和
#define Umax 1
#define Umin -1
#define NB 0
#define NM 1
#define NS 2
#define ZO 3
#define PS 4
#define PM 5
#define PB 6
int32_t kp[7][7] = {{PB, PB, PM, PM, PS, ZO, ZO},
{PB, PB, PM, PS, PS, ZO, ZO},
{PM, PM, PM, PS, ZO, NS, NS},
{PM, PM, PS, ZO, NS, NM, NM},
{PS, PS, ZO, NS, NS, NM, NM},
{PS, ZO, NS, NM, NM, NM, NB},
{ZO, ZO, NM, NM, NM, NB, NB}};
int32_t kd[7][7] = {{PS, NS, NB, NB, NB, NM, PS},
{PS, NS, NB, NM, NM, NS, ZO},
{ZO, NS, NM, NM, NS, NS, ZO},
{ZO, NS, NS, NS, NS, NS, ZO},
{ZO, ZO, ZO, ZO, ZO, ZO, ZO},
{PB, NS, PS, PS, PS, PS, PB},
{PB, PM, PM, PM, PS, PS, PB}};
int32_t ki[7][7] = {{NB, NB, NM, NM, NS, ZO, ZO},
{NB, NB, NM, NS, NS, ZO, ZO},
{NB, NM, NS, NS, ZO, PS, PS},
{NM, NM, NS, ZO, PS, PM, PM},
{NM, NS, ZO, PS, PS, PM, PB},
{ZO, ZO, PS, PS, PM, PB, PB},
{ZO, ZO, PS, PM, PM, PB, PB}};
static float32 ec; // 误差变化率
/**************求隶属度(三角形)***************/
float32 FTri(float32 x, float32 a, float32 b, float32 c) // FuzzyTriangle
{
if (x <= a)
return 0;
else if ((a < x) && (x <= b))
return (x - a) / (b - a);
else if ((b < x) && (x <= c))
return (c - x) / (c - b);
else if (x > c)
return 0;
else
return 0;
}
/*****************求隶属度(梯形左)*******************/
float32 FTraL(float32 x, float32 a, float32 b) // FuzzyTrapezoidLeft
{
if (x <= a)
return 1;
else if ((a < x) && (x <= b))
return (b - x) / (b - a);
else if (x > b)
return 0;
else
return 0;
}
/*****************求隶属度(梯形右)*******************/
float32 FTraR(float32 x, float32 a, float32 b) // FuzzyTrapezoidRight
{
if (x <= a)
return 0;
if ((a < x) && (x < b))
return (x - a) / (b - a);
if (x >= b)
return 1;
else
return 1;
}
/****************三角形反模糊化处理**********************/
float32 uFTri(float32 x, float32 a, float32 b, float32 c)
{
float32 y, z;
z = (b - a) * x + a;
y = c - (c - b) * x;
return (y + z) / 2;
}
/*******************梯形(左)反模糊化***********************/
float32 uFTraL(float32 x, float32 a, float32 b)
{
return b - (b - a) * x;
}
/*******************梯形(右)反模糊化***********************/
float32 uFTraR(float32 x, float32 a, float32 b)
{
return (b - a) * x + a;
}
/**************************求交集****************************/
float32 fand(float32 a, float32 b)
{
return (a < b) ? a : b;
}
/**************************求并集****************************/
float32 forr(float32 a, float32 b)
{
return (a < b) ? b : a;
}
static float32 _PID(struct PID_X *self, float32 target, float32 feedback)
{
float32 pwm_var; // pwm调整量
float32 iError; // 当前误差
float32 set, input;
CLASSICPID *pri = &self->pri;
// 计算隶属度表
float32 es[7], ecs[7], e;
float32 form[7][7];
int i = 0, j = 0;
int MaxX = 0, MaxY = 0;
// 记录隶属度最大项及相应推理表的p、i、d值
float32 lsd;
int temp_p, temp_d, temp_i;
float32 detkp, detkd, detki; // 推理后的结果
// 输入格式的转化及偏差计算
set = target;
input = feedback;
iError = set - input; // 偏差
e = iError;
ec = iError - pri->lasterror;
// 当温度差的绝对值小于Emax时对pid的参数进行调整
if (fabs(iError) <= Emax)
{
// 计算iError在es与ecs中各项的隶属度
es[NB] = FTraL(e * 5, -3, -1); // e
es[NM] = FTri(e * 5, -3, -2, 0);
es[NS] = FTri(e * 5, -3, -1, 1);
es[ZO] = FTri(e * 5, -2, 0, 2);
es[PS] = FTri(e * 5, -1, 1, 3);
es[PM] = FTri(e * 5, 0, 2, 3);
es[PB] = FTraR(e * 5, 1, 3);
ecs[NB] = FTraL(ec * 30, -3, -1); // ec
ecs[NM] = FTri(ec * 30, -3, -2, 0);
ecs[NS] = FTri(ec * 30, -3, -1, 1);
ecs[ZO] = FTri(ec * 30, -2, 0, 2);
ecs[PS] = FTri(ec * 30, -1, 1, 3);
ecs[PM] = FTri(ec * 30, 0, 2, 3);
ecs[PB] = FTraR(ec * 30, 1, 3);
// 计算隶属度表确定e和ec相关联后表格各项隶属度的值
for (i = 0; i < 7; i++)
{
for (j = 0; j < 7; j++)
{
form[i][j] = fand(es[i], ecs[j]);
}
}
// 取出具有最大隶属度的那一项
for (i = 0; i < 7; i++)
{
for (j = 0; j < 7; j++)
{
if (form[MaxX][MaxY] < form[i][j])
{
MaxX = i;
MaxY = j;
}
}
}
// 进行模糊推理,并去模糊
lsd = form[MaxX][MaxY];
temp_p = kp[MaxX][MaxY];
temp_d = kd[MaxX][MaxY];
temp_i = ki[MaxX][MaxY];
if (temp_p == NB)
detkp = uFTraL(lsd, -0.3, -0.1);
else if (temp_p == NM)
detkp = uFTri(lsd, -0.3, -0.2, 0);
else if (temp_p == NS)
detkp = uFTri(lsd, -0.3, -0.1, 0.1);
else if (temp_p == ZO)
detkp = uFTri(lsd, -0.2, 0, 0.2);
else if (temp_p == PS)
detkp = uFTri(lsd, -0.1, 0.1, 0.3);
else if (temp_p == PM)
detkp = uFTri(lsd, 0, 0.2, 0.3);
else if (temp_p == PB)
detkp = uFTraR(lsd, 0.1, 0.3);
if (temp_d == NB)
detkd = uFTraL(lsd, -3, -1);
else if (temp_d == NM)
detkd = uFTri(lsd, -3, -2, 0);
else if (temp_d == NS)
detkd = uFTri(lsd, -3, 1, 1);
else if (temp_d == ZO)
detkd = uFTri(lsd, -2, 0, 2);
else if (temp_d == PS)
detkd = uFTri(lsd, -1, 1, 3);
else if (temp_d == PM)
detkd = uFTri(lsd, 0, 2, 3);
else if (temp_d == PB)
detkd = uFTraR(lsd, 1, 3);
if (temp_i == NB)
detki = uFTraL(lsd, -0.06, -0.02);
else if (temp_i == NM)
detki = uFTri(lsd, -0.06, -0.04, 0);
else if (temp_i == NS)
detki = uFTri(lsd, -0.06, -0.02, 0.02);
else if (temp_i == ZO)
detki = uFTri(lsd, -0.04, 0, 0.04);
else if (temp_i == PS)
detki = uFTri(lsd, -0.02, 0.02, 0.06);
else if (temp_i == PM)
detki = uFTri(lsd, 0, 0.04, 0.06);
else if (temp_i == PB)
detki = uFTraR(lsd, 0.02, 0.06);
// pid三项系数的修改
pri->pKp += detkp;
pri->pKi += detki;
if (pri->kd_e)
{
pri->pKd += detkd;
}
else
{
pri->pKd = 0; // 取消微分作用
}
// 对Kp,Ki进行限幅
if (pri->pKp < 0)
{
pri->pKp = 0;
}
if (pri->pKi < 0)
{
pri->pKi = 0;
}
// 计算新的K1,nKi,nKd
pri->nKp = pri->pKp + pri->pKi + pri->pKd;
pri->nKi = -(pri->pKp + 2 * pri->pKd);
pri->nKd = pri->pKd;
}
if (iError > Emax)
{
pri->out = pri->max;
pwm_var = 0;
pri->flag = 1; // 设定标志位,如果误差超过了门限值,则认为当控制量第一次到达给定值时,应该采取下面的 抑制超调 的措施
}
else if (iError < -Emax)
{
pri->out = pri->min;
pwm_var = 0;
}
else if (fabsf(iError) <= Emin)
{
pwm_var = 0;
}
else
{
if (iError < Emid && pri->flag == 1) // 第一次超过(设定值-Emid(-0.08)摄氏度),是输出为零,防止超调,也可以输出其他值,不至于太小而引起震荡
{
pri->out = 0;
pri->flag = 0;
}
else if (-iError > Emid) // 超过(设定+Emid(+0.08)摄氏度)
{
pwm_var = -1;
}
else
{
// 增量计算
pwm_var = (pri->nKp * iError // e[k]
+ pri->nKi * pri->lasterror // e[k-1]
+ pri->nKd * pri->preverror); // e[k-2]
}
if (pwm_var >= Umax)
pwm_var = Umax; // 调整值限幅,防止积分饱和
if (pwm_var <= Umin)
pwm_var = Umin; // 调整值限幅,防止积分饱和
}
pri->preverror = pri->lasterror;
pri->lasterror = iError;
pri->out += pwm_var; // 调整PWM输出
if (pri->out > pri->max)
pri->out = pri->max; // 输出值限幅
if (pri->out < pri->min)
pri->out = pri->min; // 输出值限幅
return pri->out;
}
/*整定开始前的预处理,判断状态及初始化变量*/
static void tune_pretreatment(struct PID_X *self)
{
CLASSIC_AUTOTUNE *tune = &self->tune;
CLASSICPID *vPID = &self->pri;
tune->tuneTimer = 0;
tune->startTime = 0;
tune->endTime = 0;
tune->outputStep = 100;
if (*vPID->pSV >= *vPID->pPV)
{
tune->initialStatus = 1;
tune->outputStatus = 0;
}
else
{
tune->initialStatus = 0;
tune->outputStatus = 1;
}
tune->tuneEnable = 1;
tune->preEnable = 0;
tune->zeroAcrossCounter = 0;
tune->riseLagCounter = 0;
tune->fallLagCounter = 0;
}
/*计算PID参数值*/
static void calculation_parameters(struct PID_X *self)
{
CLASSIC_AUTOTUNE *tune = &self->tune;
CLASSICPID *vPID = &self->pri;
float32 kc = 0.0f;
float32 tc = 0.0f;
float32 zn[3][3] = {{0.5f, 100000.0f, 0.0f}, {0.45f, 0.8f, 0.0f}, {0.6f, 0.5f, 0.125f}};
tc = (tune->endTime - tune->startTime) * tune->tunePeriod / 1000.0;
kc = (8.0f * tune->outputStep) / (PI * (tune->maxPV - tune->minPV));
vPID->pKp = zn[tune->controllerType][0] * kc; // 比例系数
vPID->pKi = vPID->pKp * tune->tunePeriod / (zn[tune->controllerType][1] * tc); // 积分系数
vPID->pKd = vPID->pKp * zn[tune->controllerType][2] * tc / tune->tunePeriod; // 微分系数
}
/**
* @brief
* @param {PID_X} *self
* @return {*}
* @note tuneEnablepreEnable和controllerType需要提前赋值tuneEnable变量值为0时是使用PID控制器tuneEnable变量值为1时是开启整定过程tuneEnable变量值为2时是指示整定失败preEnable变量在整定前赋值为1controllerType则根据所整定的控制器的类型来定
*/
static uint8_t _auto_tune(struct PID_X *self)
{
CLASSIC_AUTOTUNE *tune = &self->tune;
CLASSICPID *vPID = &self->pri;
/*整定开始前的预处理,只执行一次*/
if (tune->preEnable == 1)
{
tune_pretreatment(self);
}
uint32_t tuneDuration = 0;
tune->tuneTimer++;
tuneDuration = (tune->tuneTimer * tune->tunePeriod) / 1000;
if (tuneDuration > (10 * 60)) // 整定过程持续超过10分钟未能形成有效振荡整定失败
{
tune->tuneEnable = 2;
tune->preEnable = 1;
return tune->tuneEnable;
}
if (*vPID->pSV >= *vPID->pPV) // 设定值大于测量值,则开执行单元
{
tune->riseLagCounter++;
tune->fallLagCounter = 0;
if (tune->riseLagCounter > LAG_PHASE)
{
*vPID->pMV = vPID->max;
if (tune->outputStatus == 0)
{
tune->outputStatus = 1;
tune->zeroAcrossCounter++;
if (tune->zeroAcrossCounter == 3)
{
tune->startTime = tune->tuneTimer;
}
}
}
}
else
{
tune->riseLagCounter = 0;
tune->fallLagCounter++;
if (tune->fallLagCounter > LAG_PHASE)
{
*vPID->pMV = vPID->min;
if (tune->outputStatus == 1)
{
tune->outputStatus = 0;
tune->zeroAcrossCounter++;
if (tune->zeroAcrossCounter == 3)
{
tune->startTime = tune->tuneTimer;
}
}
}
}
if (tune->zeroAcrossCounter == 3) // 已经两次过零,可以记录波形数据
{
if (tune->initialStatus == 1) // 初始设定值大于测量值则区域3出现最小值
{
if (*vPID->pPV < tune->minPV)
{
tune->minPV = *vPID->pPV;
}
}
else if (tune->initialStatus == 0) // 初始设定值小于测量值则区域3出现最大值
{
if (*vPID->pPV > tune->maxPV)
{
tune->maxPV = *vPID->pPV;
}
}
}
else if (tune->zeroAcrossCounter == 4) // 已经三次过零,记录另半波的数据
{
if (tune->initialStatus == 1) // 初始设定值大于测量值则区域4出现最大值
{
if (*vPID->pPV > tune->maxPV)
{
tune->maxPV = *vPID->pPV;
}
}
else if (tune->initialStatus == 0) // 初始设定值小于测量值则区域4出现最小值
{
if (*vPID->pPV < tune->minPV)
{
tune->minPV = *vPID->pPV;
}
}
}
else if (tune->zeroAcrossCounter == 5) // 已经四次过零,振荡已形成可以整定参数
{
calculation_parameters(self);
tune->tuneEnable = 0;
tune->preEnable = 1;
}
return tune->tuneEnable;
}
void pid_x_constructor(struct PID_X *self)
{
self->PID = _PID;
self->AUTO_TUNE = _auto_tune;
self->pri.flag = 0;
self->pri.out = 0;
self->tune.preEnable = 1;
}

View File

@ -0,0 +1,71 @@
#ifndef __PID_X_H__
#define __PID_X_H__
#include "lib.h"
/*定义PID对象类型*/
typedef struct CLASSIC
{
float32 *pPV; // 测量值指针
float32 *pSV; // 设定值指针
float32 *pMV; // 输出值指针
BOOL *pMA; // 手自动操作指针
float32 out; // 输出值
float32 setpoint; // 设定值
float32 lasterror; // 前一拍偏差
float32 preverror; // 前两拍偏差
float32 max; // 输出值上限
float32 min; // 输出值下限
uint16_t flag; // 状态标志位
float32 pKp; // 比例系数
float32 pKi; // 积分系数
float32 pKd; // 微分系数
float32 nKp; // 比例系数
float32 nKi; // 积分系数
float32 nKd; // 微分系数
BOOL direct; // 正反作用
BOOL sm; // 设定值平滑
BOOL cas; // 串级设定
BOOL pac; // 输出防陡变
BOOL kd_e; // 微分使能
} CLASSICPID;
// 定义整定参数
typedef struct
{
uint8_t tuneEnable : 2; // 整定与PID控制开关0PID控制1参数整定2整定失败
uint8_t preEnable : 2; // 预处理使能,在开始整定前置位
uint8_t initialStatus : 1; // 记录开始整定前偏差的初始状态
uint8_t outputStatus : 1; // 记录输出的初始状态0允许上升过零计数1允许下降过零计数
uint8_t controllerType : 2; // 控制器类型0P控制器1PI控制器2PID控制器
uint8_t zeroAcrossCounter; // 过零点计数器每次输出改变加1比实际过零次数多1
uint8_t riseLagCounter; // 上升迟滞时间计数器
uint8_t fallLagCounter; // 下降迟滞时间计数器
uint16_t tunePeriod; // 整定采样周期
uint32_t tuneTimer; // 整定计时器
uint32_t startTime; // 记录波形周期起始时间
uint32_t endTime; // 记录波形周期结束时间
float32 outputStep; // 输出阶跃d
float32 maxPV; // 振荡波形中测量值的最大值
float32 minPV; // 振荡波形中测量值的最小值
} CLASSIC_AUTOTUNE;
typedef struct PID_X
{
/* 控制接口 */
float32 (*PID)(struct PID_X *self, float32 target, float32 feedback);
uint8_t (*AUTO_TUNE)(struct PID_X *self);
/* private */
CLASSICPID pri;
CLASSIC_AUTOTUNE tune;
} pid_x_t;
extern void pid_x_constructor(struct PID_X *self);
#endif // __PID_X_H__

View File

@ -0,0 +1,467 @@
#include "pid_zh.h"
#include "sys.h"
#include <math.h>
// 定义输出量比例因子
#ifdef GPS3000
#define KUP 0.0f // #define KUP 3.0f
#define KUI 0.00f
#define KUD 0.0f // #define KUP 3.0f
#else
#define KUP 3.0f
#define KUI 0.0f
#define KUD 0.0f
#endif
// 模糊集合
#define NL -3
#define NM -2
#define NS -1
#define ZE 0
#define PS 1
#define PM 2
#define PL 3
// 定义偏差E的范围因为设置了非线性区间误差在10时才开始进行PID调节这里E的范围为10
#define MAXE (10)
#define MINE (-MAXE)
// 定义EC的范围因为变化非常缓慢每次的EC都非常小这里可以根据实际需求来调整
#define MAXEC (10)
#define MINEC (-MAXEC)
// 定义e,ec的量化因子
#define KE 3 / MAXE
#define KEC 3 / MAXEC
static const float32 fuzzyRuleKp[7][7] = {
PL, PL, PM, PL, PS, PM, PL,
PL, PM, PM, PM, PS, PM, PL,
PM, PS, PS, PS, PS, PS, PM,
PM, PS, ZE, ZE, ZE, PS, PM,
PS, PS, PS, PS, PS, PM, PM,
PM, PM, PM, PM, PL, PL, PL,
PM, PL, PL, PL, PL, PL, PL};
static const float32 fuzzyRuleKi[7][7] = {
PL, PL, PL, PL, PM, PL, PL,
PL, PL, PM, PM, PM, PL, PL,
PM, PM, PS, PS, PS, PM, PM,
PM, PS, ZE, ZE, ZE, PS, PM,
PM, PS, PS, PS, PS, PM, PM,
PM, PM, PS, PM, PM, PL, PL,
PM, PL, PM, PL, PL, PL, PL};
/*
static const float32 fuzzyRuleKi[7][7] = {
NL, NL, NL, NL, NM, NL, NL,
NL, NL, NM, NM, NM, NL, NL,
NM, NM, NS, NS, NS, NM, NM,
NM, NS, ZE, ZE, ZE, NS, NM,
NM, NS, NS, NS, NS, NM, NM,
NM, NM, NS, NM, NM, NL, NL,
NM, NL, NM, NL, NL, NL, NL};
*/
static const float32 fuzzyRuleKd[7][7] = {
PS, PS, ZE, ZE, ZE, PL, PL,
PS, PS, PS, PS, ZE, PS, PM,
PL, PL, PM, PS, ZE, PS, PM,
PL, PM, PM, PS, ZE, PS, PM,
PL, PM, PS, PS, ZE, PS, PS,
PM, PS, PS, PS, ZE, PS, PS,
PS, ZE, ZE, ZE, ZE, PL, PL};
/*
static const float32 fuzzyRuleKp[7][7] = {
PL, PL, PM, PM, PS, ZE, ZE,
PL, PL, PM, PS, PS, ZE, NS,
PM, PM, PM, PS, ZE, NS, NS,
PM, PM, PS, ZE, NS, NM, NM,
PS, PS, ZE, NS, NS, NM, NM,
PS, ZE, NS, NM, NM, NM, NL,
ZE, ZE, NM, NM, NM, NL, NL};
static const float32 fuzzyRuleKi[7][7] = {
NL, NL, NM, NM, NS, ZE, ZE,
NL, NL, NM, NS, NS, ZE, ZE,
NL, NM, NS, NS, ZE, PS, PS,
NM, NM, NS, ZE, PS, PM, PM,
NM, NS, ZE, PS, PS, NM, PL,
ZE, ZE, PS, PS, PM, PL, PL,
ZE, ZE, PS, PM, PM, PL, PL};
static const float32 fuzzyRuleKd[7][7] = {
PS, NS, NL, NL, NL, NM, PS,
PS, NS, NL, NM, NM, NS, ZE,
ZE, NS, NM, NM, NS, NS, ZE,
ZE, NS, NS, NS, NS, NS, ZE,
ZE, ZE, ZE, ZE, ZE, ZE, ZE,
PL, NS, PS, PS, PS, PS, PL,
PL, PM, PM, PM, PS, PS, PL};
*/
static void fuzzy(float32 e, float32 ec, FUZZY_PID_ZH_t *fuzzy_pid)
{
float32 etemp, ectemp;
float32 eLefttemp, ecLefttemp; // ec,e左隶属度
float32 eRighttemp, ecRighttemp;
int eLeftIndex, ecLeftIndex; // 模糊位置标号
int eRightIndex, ecRightIndex;
e = RANGE(e, MINE, MAXE);
ec = RANGE(ec, MINEC, MAXEC);
e = e * KE;
ec = ec * KEC;
etemp = e > 3.0f ? 0.0f : (e < -3.0f ? 0.0f : (e >= 0.0f ? (e >= 2.0f ? 2.5f : (e >= 1.0f ? 1.5f : 0.5f)) : (e >= -1.0f ? -0.5f : (e >= -2.0f ? -1.5f : (e >= -3.0f ? -2.5f : 0.0f)))));
eLeftIndex = (int)((etemp - 0.5f) + 3); //[-3,2] -> [0,5]
eRightIndex = (int)((etemp + 0.5f) + 3);
eLefttemp = etemp == 0.0f ? 0.0f : ((etemp + 0.5f) - e);
eRighttemp = etemp == 0.0f ? 0.0f : (e - (etemp - 0.5f));
ectemp = ec > 3.0f ? 0.0f : (ec < -3.0f ? 0.0f : (ec >= 0.0f ? (ec >= 2.0f ? 2.5f : (ec >= 1.0f ? 1.5f : 0.5f)) : (ec >= -1.0f ? -0.5f : (ec >= -2.0f ? -1.5f : (ec >= -3.0f ? -2.5f : 0.0f)))));
ecLeftIndex = (int)((ectemp - 0.5f) + 3); //[-3,2] -> [0,5]
ecRightIndex = (int)((ectemp + 0.5f) + 3);
ecLefttemp = ectemp == 0.0f ? 0.0f : ((ectemp + 0.5f) - ec);
ecRighttemp = ectemp == 0.0f ? 0.0f : (ec - (ectemp - 0.5f));
/*************************************反模糊*************************************/
fuzzy_pid->kp = (eLefttemp * ecLefttemp * fuzzyRuleKp[eLeftIndex][ecLeftIndex] + eLefttemp * ecRighttemp * fuzzyRuleKp[eLeftIndex][ecRightIndex] + eRighttemp * ecLefttemp * fuzzyRuleKp[eRightIndex][ecLeftIndex] + eRighttemp * ecRighttemp * fuzzyRuleKp[eRightIndex][ecRightIndex]);
fuzzy_pid->ki = (eLefttemp * ecLefttemp * fuzzyRuleKi[eLeftIndex][ecLeftIndex] + eLefttemp * ecRighttemp * fuzzyRuleKi[eLeftIndex][ecRightIndex] + eRighttemp * ecLefttemp * fuzzyRuleKi[eRightIndex][ecLeftIndex] + eRighttemp * ecRighttemp * fuzzyRuleKi[eRightIndex][ecRightIndex]);
fuzzy_pid->kd = (eLefttemp * ecLefttemp * fuzzyRuleKd[eLeftIndex][ecLeftIndex] + eLefttemp * ecRighttemp * fuzzyRuleKd[eLeftIndex][ecRightIndex] + eRighttemp * ecLefttemp * fuzzyRuleKd[eRightIndex][ecLeftIndex] + eRighttemp * ecRighttemp * fuzzyRuleKd[eRightIndex][ecRightIndex]);
// 对解算出的KP,KI,KD进行量化映射
fuzzy_pid->kp = fuzzy_pid->kp * fuzzy_pid->kup;
fuzzy_pid->ki = fuzzy_pid->ki * fuzzy_pid->kui;
fuzzy_pid->kd = fuzzy_pid->kd * fuzzy_pid->kud;
}
static void smoothSetpoint(struct PID_FUZZY_ZH *self, float32 target_sv)
{
#if FUZZY_SUB_TYPE == PID_SUB_TYPE_POSITION
pid_zh_position_t *pri = &self->pri;
#else
pid_common_increment_t *pri = &self->pri;
#endif
float32 stepIn = (pri->sv_range) * 0.1f;
float32 kFactor = 0.0f;
if (fabs(pri->ref - target_sv) <= stepIn)
{
pri->ref = target_sv;
}
else
{
if (pri->ref - target_sv > 0)
{
kFactor = -1.0f;
}
else if (pri->ref - target_sv < 0)
{
kFactor = 1.0f;
}
else
{
kFactor = 0.0f;
}
pri->ref = pri->ref + kFactor * stepIn;
}
}
/*封装模糊接口*/
static void compensate(float32 e, float32 ec, FUZZY_PID_ZH_t *fuzzy_d)
{
fuzzy(e, ec, fuzzy_d);
}
/**
* @brief PID积分及微分控制数据
* @param {PID_FUZZY_ZH} *self
* @return {*}
*/
static void _restctrl(struct PID_FUZZY_ZH *self)
{
self->pri.pre_error = 0;
self->pri.sum_iterm = 0;
#if INCOMPLETE_DIFFEREN == 1
self->pri.lastdev = 0;
#endif
}
/**
* @brief
* @param {PID_FUZZY_ZH} *self
* @param {float32} out_min
* @param {float32} out_max
* @return {*}
* @note
*/
static void _set_range(struct PID_FUZZY_ZH *self, float32 out_min, float32 out_max)
{
self->pri.out_max = out_max;
self->pri.out_min = out_min;
}
/**
* @brief 使
* @param {PID_FUZZY_ZH} *self
* @param {BOOL} enable
* @return {*}
* @note
*/
// static void _set_ki_enable(struct PID_FUZZY_ZH *self, BOOL enable)
// {
// self->pri.ki_enable = enable;
// }
/**
* @brief 使
* @param {PID_FUZZY_ZH} *self
* @param {BOOL} enable
* @return {*}
* @note
*/
static void _set_kd_enable(struct PID_FUZZY_ZH *self, BOOL enable)
{
self->pri.kd_enable = enable;
}
/*
* Function:使
* parameter:*pid需要配PID参数结构指针sv_range控制范围sv的范围
* return:
*/
static void _set_smooth_enable(struct PID_FUZZY_ZH *self, BOOL enable, float32 sv_range)
{
#if FUZZY_SUB_TYPE == PID_SUB_TYPE_POSITION
pid_zh_position_t *pri = &self->pri;
#else
pid_common_increment_t *pri = &self->pri;
#endif
pri->sm = enable;
pri->sv_range = sv_range;
}
// 设置控制参数
static void _set_ctrl_prm(struct PID_FUZZY_ZH *self, float32 kp, float32 ki, float32 kd, float32 err_dead,
float32 out_min, float32 out_max)
{
self->open = TRUE;
self->fuzzy.kup = KUP;
self->fuzzy.kui = KUI;
self->fuzzy.kud = KUD;
#if FUZZY_SUB_TYPE == PID_SUB_TYPE_POSITION
pid_zh_position_t *pri = &self->pri;
osel_memset((uint8_t *)pri, 0, sizeof(pid_zh_position_t));
pri->kp = kp;
pri->ki = ki;
pri->kd = kd;
pri->err_dead = err_dead;
pri->out_max = out_max;
pri->out_min = out_min;
pri->detach = FALSE;
pri->sm = FALSE;
#else
pid_common_increment_t *pri = &self->pri;
osel_memset((uint8_t *)pri, 0, sizeof(pid_common_increment_t));
pri->kp = kp;
pri->ki = ki;
pri->kd = kd;
pri->err_dead = err_dead;
pri->out_max = out_max;
pri->out_min = out_min;
#endif
if (kd > 0)
{
pri->kd_enable = TRUE;
}
else
{
pri->kd_enable = FALSE;
}
}
static void _update_ctrl_prm(struct PID_FUZZY_ZH *self, float32 kp, float32 ki, float32 kd, float32 err_dead,
float32 out_min, float32 out_max)
{
#if FUZZY_SUB_TYPE == PID_SUB_TYPE_POSITION
pid_zh_position_t *pri = &self->pri;
pri->kp = kp;
pri->ki = ki;
pri->kd = kd;
pri->err_dead = err_dead;
pri->out_max = out_max;
pri->out_min = out_min;
pri->detach = FALSE;
pri->sm = FALSE;
#else
pid_common_increment_t *pri = &self->pri;
pri->kp = kp;
pri->ki = ki;
pri->kd = kd;
pri->err_dead = err_dead;
pri->out_max = out_max;
pri->out_min = out_min;
#endif
if (kd > 0)
{
pri->kd_enable = TRUE;
}
else
{
pri->kd_enable = FALSE;
}
}
/**
* @brief 0+PID,PID
* @param {PID_FUZZY_ZH} *self
* @param {float32} max_err
* @param {BOOL} mode
* @return {*}
*/
static void _set_cfg(struct PID_FUZZY_ZH *self, float32 max_err, BOOL mode)
{
self->pri.err_limit = max_err;
self->pri.detach = mode == FALSE ? FALSE : TRUE;
}
#if FUZZY_SUB_TYPE == PID_SUB_TYPE_POSITION
static float32 _PID(struct PID_FUZZY_ZH *self, float32 target, float32 feedback)
{
float32 error = 0;
float32 insert = 0;
float32 ec = 0;
float32 kd = 0;
#if INCOMPLETE_DIFFEREN == 1
float32 thisdev = 0;
#else
// float32 dinput = 0.0f;
#endif
float32 temp_iterm = 0.0f;
pid_zh_position_t *pri = &self->pri;
/*获取期望值与实际值,进行偏差计算*/
if (pri->sm == 1)
{
smoothSetpoint(self, target);
}
else
{
pri->ref = target;
}
pri->feed_back = feedback;
error = pri->ref - pri->feed_back;
if (fabs(error) <= pri->err_dead)
error = 0;
/* fuzzy control caculate */
ec = error - pri->pre_error;
if (self->open == TRUE)
{
compensate(error, ec, &self->fuzzy);
}
/*根据PID配置的模式,获取积分数据,进行积分累加*/
if (pri->out >= pri->out_max)
{
if (fabs(error) > pri->err_limit && pri->detach)
{
insert = 0;
}
else
{
insert = 1;
if (error < 0)
{
temp_iterm = (pri->ki + self->fuzzy.ki) * error;
}
}
}
else if (pri->out <= pri->out_min)
{
if (fabs(error) > pri->err_limit && pri->detach)
{
insert = 0;
}
else
{
insert = 1;
if (error > 0)
{
temp_iterm = (pri->ki + self->fuzzy.ki) * error;
}
}
}
else
{
if (fabs(error) > pri->err_limit && pri->detach)
{
insert = 0;
}
else
{
insert = 1;
temp_iterm = (pri->ki + self->fuzzy.ki) * error;
}
}
pri->sum_iterm += temp_iterm;
/* limt integral */
pri->sum_iterm = RANGE(pri->sum_iterm, pri->out_min, pri->out_max);
/*
if (pri->sum_ref)
pri->sum_iterm = RANGE(pri->sum_iterm, pri->sum_ref - 1.0f, pri->sum_ref + 1.0f);
else
pri->sum_iterm = RANGE(pri->sum_iterm, pri->out_min, pri->out_max);
*/
#if INCOMPLETE_DIFFEREN == 1
/*不完全微分*/
thisdev = (pri->kd + self->fuzzy.kd) * (1.0 - pri->alpha) * (error - pri->pre_error) + pri->alpha * pri->lastdev;
/*caculate pid out*/
pri->out = (pri->kp + self->fuzzy.kp) * error + pri->sum_iterm * insert + thisdev;
/*record last dev result*/
pri->lastdev = thisdev;
#else
if (pri->kd_enable == TRUE)
{
kd = pri->kd + self->fuzzy.kd;
}
else
{
kd = 0;
}
pri->out = (pri->kp + self->fuzzy.kp) * error + pri->sum_iterm * insert + (error - pri->pre_error) * (kd);
// pri->out += pri->sum_ref;
#endif
pri->pre_error = error;
/*record last feedback sensor result*/
pri->pre_feed_back = pri->feed_back;
/*limt pid output*/
pri->out = RANGE(pri->out, pri->out_min, pri->out_max);
return pri->out;
}
#else
#endif
void pid_zh_constructor(struct PID_FUZZY_ZH *self)
{
self->set_ctrl_prm = _set_ctrl_prm;
self->update_ctrl_prm = _update_ctrl_prm;
self->set_cfg = _set_cfg;
self->set_smooth_enable = _set_smooth_enable;
// self->set_ki_enable = _set_ki_enable;
self->set_kd_enable = _set_kd_enable;
self->set_range = _set_range;
self->restctrl = _restctrl;
self->PID = _PID;
}

View File

@ -0,0 +1,73 @@
#ifndef __PID_ZH_H__
#define __PID_ZH_H__
#include "lib.h"
#include "pid_auto_tune.h"
#define GPS2000
typedef struct
{
float32 ref;
float32 feed_back;
float32 pre_feed_back;
float32 pre_error;
float32 sum_ref;
float32 sum_iterm;
float32 kp;
float32 ki;
float32 kd;
float32 err_limit;
BOOL detach;
float32 err_dead;
#if INCOMPLETE_DIFFEREN == 1
float32 alpha;
float32 lastdev;
#endif
float32 out;
float32 out_max;
float32 out_min;
float32 sv_range;
BOOL sm;
BOOL ki_enable;
BOOL kd_enable;
} pid_zh_position_t; // 位置式PID
typedef struct
{
float32 kp;
float32 ki;
float32 kd;
float32 kup;
float32 kui;
float32 kud;
} FUZZY_PID_ZH_t;
// 模糊PID
typedef struct PID_FUZZY_ZH
{
/* 设置PID三个参数 */
void (*set_ctrl_prm)(struct PID_FUZZY_ZH *self, float32 kp, float32 ki, float32 kd, float32 err_dead,
float32 out_min, float32 out_max); // 设置PID参数
void (*update_ctrl_prm)(struct PID_FUZZY_ZH *self, float32 kp, float32 ki, float32 kd, float32 err_dead,
float32 out_min, float32 out_max); // 更新PID参数
void (*set_range)(struct PID_FUZZY_ZH *self, float32 out_min, float32 out_max); // 更新最大最小值
void (*set_cfg)(struct PID_FUZZY_ZH *self, float32 max_err, BOOL mode); // 配置PID模式,默认不使用积分分离
void (*set_smooth_enable)(struct PID_FUZZY_ZH *self, BOOL enable, float32 sv_range); // 设置平滑范围
// void (*set_ki_enable)(struct PID_FUZZY *self, BOOL enable);
// 微分开启使能
void (*set_kd_enable)(struct PID_FUZZY_ZH *self, BOOL enable);
void (*restctrl)(struct PID_FUZZY_ZH *self); // 复位PID积分及微分控制数据
/* 控制接口 */
float32 (*PID)(struct PID_FUZZY_ZH *self, float32 target, float32 feedback);
pid_zh_position_t pri;
BOOL open; // 是否使用模糊PID控制
FUZZY_PID_ZH_t fuzzy;
} pid_zh_t; // 模糊PID
extern void pid_zh_constructor(struct PID_FUZZY_ZH *self);
#endif

View File

@ -0,0 +1,619 @@
#include <math.h>
#include "pid_zh1.h"
// 定义输出量比例因子
#define KUP 1.0f
#define KUI 1.0f
#define KUD 1.0f
// 模糊集合
#define NL -3
#define NM -2
#define NS -1
#define ZE 0
#define PS 1
#define PM 2
#define PL 3
// 定义偏差E的范围因为设置了非线性区间误差在10时才开始进行PID调节这里E的范围为10
#define MAXE (10)
#define MINE (-MAXE)
// 定义EC的范围因为变化非常缓慢每次的EC都非常小这里可以根据实际需求来调整
#define MAXEC (10)
#define MINEC (-MAXEC)
// 定义e,ec的量化因子
#define KE 3 / MAXE
#define KEC 3 / MAXEC
/*
static const float fuzzyRuleKp[7][7] = {
PL, PL, PM, PL, PS, PM, PL,
PL, PM, PM, PM, PS, PM, PL,
PM, PS, PS, PS, PS, PS, PM,
PM, PS, ZE, ZE, ZE, PS, PM,
PS, PS, PS, PS, PS, PM, PM,
PM, PM, PM, PM, PL, PL, PL,
PM, PL, PL, PL, PL, PL, PL};
static const float fuzzyRuleKi[7][7] = {
PL, PL, PL, PL, PM, PL, PL,
PL, PL, PM, PM, PM, PL, PL,
PM, PM, PS, PS, PS, PM, PM,
PM, PS, ZE, ZE, ZE, PS, PM,
PM, PS, PS, PS, PS, PM, PM,
PM, PM, PS, PM, PM, PL, PL,
PM, PL, PM, PL, PL, PL, PL};
static const float fuzzyRuleKd[7][7] = {
PS, PS, ZE, ZE, ZE, PL, PL,
PS, PS, PS, PS, ZE, PS, PM,
PL, PL, PM, PS, ZE, PS, PM,
PL, PM, PM, PS, ZE, PS, PM,
PL, PM, PS, PS, ZE, PS, PS,
PM, PS, PS, PS, ZE, PS, PS,
PS, ZE, ZE, ZE, ZE, PL, PL};
*/
static const float fuzzyRuleKp[7][7] = {
PL, PL, PM, PL, PS, PM, PL,
PL, PM, PM, PM, PS, PM, PL,
PM, PS, PS, PS, PS, PS, PM,
PM, PS, ZE, ZE, ZE, PS, PM,
PS, PS, PS, PS, PS, PM, PM,
PM, PM, PM, PM, PL, PL, PL,
PM, PL, PL, PL, PL, PL, PL};
static const float fuzzyRuleKi[7][7] = {
PL, PL, PL, PL, PM, PL, PL,
PL, PL, PM, PM, PM, PL, PL,
PM, PM, PS, PS, PS, PM, PM,
PM, PS, ZE, ZE, ZE, PS, PM,
PM, PS, PS, PS, PS, PM, PM,
PM, PM, PS, PM, PM, PL, PL,
PM, PL, PM, PL, PL, PL, PL};
static const float fuzzyRuleKd[7][7] = {
PS, PS, ZE, ZE, ZE, PL, PL,
PS, PS, PS, PS, ZE, PS, PM,
PL, PL, PM, PS, ZE, PS, PM,
PL, PM, PM, PS, ZE, PS, PM,
PL, PM, PS, PS, ZE, PS, PS,
PM, PS, PS, PS, ZE, PS, PS,
PS, ZE, ZE, ZE, ZE, PL, PL};
static void fuzzy(float e, float ec, fuzzy_pid_t *fuzzy_pid)
{
float etemp, ectemp;
float eLefttemp, ecLefttemp; // 左隶属度
float eRighttemp, ecRighttemp; // 右隶属度
int eLeftIndex, ecLeftIndex; // 模糊位置标号
int eRightIndex, ecRightIndex;
e = RANGE(e, MINE, MAXE);
ec = RANGE(ec, MINEC, MAXEC);
e = e * KE;
ec = ec * KEC;
etemp = e > 3.0f ? 0.0f : (e < -3.0f ? 0.0f : (e >= 0.0f ? (e >= 2.0f ? 2.5f : (e >= 1.0f ? 1.5f : 0.5f)) : (e >= -1.0f ? -0.5f : (e >= -2.0f ? -1.5f : (e >= -3.0f ? -2.5f : 0.0f)))));
eLeftIndex = (int)((etemp - 0.5f) + 3);
eRightIndex = (int)((etemp + 0.5f) + 3);
eLefttemp = etemp == 0.0f ? 0.0f : ((etemp + 0.5f) - e);
eRighttemp = etemp == 0.0f ? 0.0f : (e - (etemp - 0.5f));
ectemp = ec > 3.0f ? 0.0f : (ec < -3.0f ? 0.0f : (ec >= 0.0f ? (ec >= 2.0f ? 2.5f : (ec >= 1.0f ? 1.5f : 0.5f)) : (ec >= -1.0f ? -0.5f : (ec >= -2.0f ? -1.5f : (ec >= -3.0f ? -2.5f : 0.0f)))));
ecLeftIndex = (int)((ectemp - 0.5f) + 3);
ecRightIndex = (int)((ectemp + 0.5f) + 3);
ecLefttemp = ectemp == 0.0f ? 0.0f : ((ectemp + 0.5f) - ec);
ecRighttemp = ectemp == 0.0f ? 0.0f : (ec - (ectemp - 0.5f));
/*************************************反模糊*************************************/
fuzzy_pid->kp = (eLefttemp * ecLefttemp * fuzzyRuleKp[eLeftIndex][ecLeftIndex] + eLefttemp * ecRighttemp * fuzzyRuleKp[eLeftIndex][ecRightIndex] + eRighttemp * ecLefttemp * fuzzyRuleKp[eRightIndex][ecLeftIndex] + eRighttemp * ecRighttemp * fuzzyRuleKp[eRightIndex][ecRightIndex]);
fuzzy_pid->ki = (eLefttemp * ecLefttemp * fuzzyRuleKi[eLeftIndex][ecLeftIndex] + eLefttemp * ecRighttemp * fuzzyRuleKi[eLeftIndex][ecRightIndex] + eRighttemp * ecLefttemp * fuzzyRuleKi[eRightIndex][ecLeftIndex] + eRighttemp * ecRighttemp * fuzzyRuleKi[eRightIndex][ecRightIndex]);
fuzzy_pid->kd = (eLefttemp * ecLefttemp * fuzzyRuleKd[eLeftIndex][ecLeftIndex] + eLefttemp * ecRighttemp * fuzzyRuleKd[eLeftIndex][ecRightIndex] + eRighttemp * ecLefttemp * fuzzyRuleKd[eRightIndex][ecLeftIndex] + eRighttemp * ecRighttemp * fuzzyRuleKd[eRightIndex][ecRightIndex]);
// 对解算出的KP,KI,KD进行量化映射
fuzzy_pid->kp = fuzzy_pid->kp * fuzzy_pid->kup;
fuzzy_pid->ki = fuzzy_pid->ki * fuzzy_pid->kui;
fuzzy_pid->kd = fuzzy_pid->kd * fuzzy_pid->kud;
}
static void smooth_init(smart_pid_t *pid, BOOL sm_open, float maxTarget)
{
if (!pid)
return;
pid->sm_open = sm_open;
pid->maxTarget = maxTarget;
}
static void smooth_target(smart_pid_t *pid, float *target)
{
if ((!pid) || (!target))
return;
if (!pid->maxTarget)
return;
float sm_step = (pid->maxTarget) * 0.1f;
float k = 0.0f;
if (fabs(pid->target - *target) <= sm_step)
{
pid->target = *target;
}
else
{
if (pid->target - *target > 0)
{
k = -1.0f;
}
else if (pid->target - *target < 0)
{
k = 1.0f;
}
else
{
k = 0.0f;
}
pid->target += k * sm_step;
}
}
static void smart_pid_init(smart_pid_t *pid, float *duty, float *kp, float *ki, float *kd, float *errorDead, float *iDetachCondation, float *maxOut)
{
if ((!pid) || (!duty) || (!kp) || (!ki) || (!kd) || (!iDetachCondation) || (!maxOut))
return;
pid->duty = *duty;
pid->kp = *kp;
pid->ki = *ki;
pid->kd = *kd;
pid->errorDead = *errorDead;
pid->iDetachCondation = *iDetachCondation;
pid->maxOutput = *maxOut;
}
void cascade_pid_init(cascade_pid_t *pid, smart_pid_t *pid_outer, smart_pid_t *pid_inner)
{
smooth_init(&pid->outer, pid_outer->sm_open, pid_outer->maxTarget);
smooth_init(&pid->inner, pid_inner->sm_open, pid_inner->maxTarget);
smart_pid_init(&pid->outer, &pid_outer->duty, &pid_outer->kp, &pid_outer->ki, &pid_outer->kd, &pid_outer->errorDead, &pid_outer->iDetachCondation, &pid_outer->maxOutput);
smart_pid_init(&pid->inner, &pid_inner->duty, &pid_inner->kp, &pid_inner->ki, &pid_inner->kd, &pid_inner->errorDead, &pid_inner->iDetachCondation, &pid_inner->maxOutput);
}
void smart_pid_calc(smart_pid_t *pid, float *target, float *feedback)
{
// 将旧error存起来
pid->lastError = pid->error;
// 平滑处理目标值
if (pid->sm_open == TRUE)
smooth_target(pid, target);
else
pid->target = *target;
// 计算新error
pid->error = pid->target - *feedback;
if (fabs(pid->error) <= pid->errorDead)
pid->error = 0.0f;
// 计算误差变化
pid->dError = pid->error - pid->lastError;
// 选用模糊规则
if (pid->fuzzy_open == TRUE)
{
fuzzy(pid->error, pid->dError, &pid->fuzzy_pid);
}
// 计算微分
float dout = pid->dError * (pid->kd + pid->fuzzy_pid.kd);
// 计算比例
float pout = pid->error * (pid->kp + pid->fuzzy_pid.kp);
// 积分分离
if (fabs(pid->error) <= pid->iDetachCondation)
{
pid->integral += pid->error * (pid->ki + pid->fuzzy_pid.ki);
pid->iDetach = FALSE;
}
else
{
pid->iDetach = TRUE;
pid->integral = 0;
}
// 积分限幅
if (pid->integral > pid->maxOutput)
pid->integral = pid->maxOutput;
else if (pid->integral < -pid->maxOutput)
pid->integral = -pid->maxOutput;
// 计算输出
pid->output = pout + dout + pid->integral * (!pid->iDetach);
// 输出限幅
if (pid->output > pid->maxOutput)
pid->output = pid->maxOutput;
else if (pid->output < -pid->maxOutput)
pid->output = -pid->maxOutput;
}
void cascade_pid_calc(struct CascadePID *pid, float *outerRef, float *outerFdb, float *innerFdb)
{
// 外环位置控制
smart_pid_calc(&pid->cascade_pid.outer, outerRef, outerFdb);
// 内环速度控制
smart_pid_calc(&pid->cascade_pid.inner, &pid->cascade_pid.outer.output, innerFdb);
// 内环输出就是串级PID的输出
// pid->cascade_pid.output = pid->cascade_pid.inner.output;
pid->cascade_pid.output = pid->cascade_pid.outer.output;
}
void pid_zh_constructor1(struct CascadePID *pid)
{
pid->smart_pid_init = smart_pid_init;
pid->smart_pid_calc = smart_pid_calc;
pid->cascade_pid_init = cascade_pid_init;
pid->cascade_pid_calc = cascade_pid_calc;
}
/*
L[1] -> 1/s
L[t] -> 1/s^2
L[1/2t^2] -> 1/s^3
G(s) = k/(TS+1)
G(s) = k/S^i(TS+1)
i = 0 0 i = 1 I I = 2 II
G(s)
G闭(s) = G(s) / 1 + G(s)
R(s) = 1/1+G(s)
limf(t) = lim s*G(s)
t-> s->0
o型系统r/s
e = lim f(t) = lim s*G(s) = G(s) = k/1+G(s) = k/ 1 + (Ts+1+k)..
t-> s->0 s->0 s->0 = s->0
*
*线
*
tr td tp
G(s) = 1/ s^2 *(2ξwn)s + wn^2
ξ:
wn = 1/T:
K T
RC电路
Gs = 1/Ts+1
EPM气压控制等主导环节
G(s) = wn^2/ s*( s + 2ξwn)
G(s) = wn^2/ (s^2 + (2ξwn)s + wn^2)
ξ
Wn
0 < ξ < 1
s^2 + (2ξwn)s + wn^2 = 0
I型系统来消除静差PID控制器
EPM本身的控制特性线性度差
EMP本身的控制线性度差EPM性能的不足
EPM IP开度大小决定EPM本身的不足
:
PID
    u(t) = k*(e(t) +e(t)dt + de(t)dt)
u(n) = k*(e(n) +  e(n)/Ti + Td*(e(n) - e(n-1)))
:PID + PD控制
    [-5%,5%] PID < 0.3%
    [-100%,5%] [5%,100%] PD控制
   
    <= 5%
              > 5%
   
              >= 100%   =  100%
              <= -100% = -100%
    : 60%
    : < 60%
    ->->,t0 -> -> -> ,t1
      <|
    Tu
    : Ku = - / ( - )
    Kp = 0.8 * Ku
          Ti = 0.6 * Tu
          Td = 0.125 * Tu
          Ki = Kp / Ti = Kp / (0.6 * Tu)
          Kd = Kp * Td = Kp * 0.125 * Td
    s1:AD值
    s2:AD值
    v1:
    v2:  
    v:
a
t:
v = (s2 - s1) / t
a = (v2 - v1) / t
   
    PID
    = -
    =
= Kp*  +  Ki *  + Kd *
   
   
      = -
      = -
      = Kp1*  +  Ki1 *  + Kd1 *
      = -
      = -
      = Kp2*  +  Ki2 *  + Kd2 *
???
automatic control theory
control system
linear and nonlinear system
线
modelling
analysis
线
L变换 Z变换
problems
time consuming
nyquist
0
root locus
G(s) = k/s(s+1)
线
p-n/n-m
lambda
lambda
tao/t
PI D
PID
makefile
1->->
#source object target
SRC := *.c
OBJ := *.o
TARGET := mqtt_test
#compile library include
CC := cc
LIB:= -lpthread
LDFLAG := -L. libmosquitto.so
CFLAG :=
CXXFLAG :=
#link
$(TARGET):$(OBJ)
$(CC) -o $(TARGET) $(BOJ) $(LIB) $(LDFLAG)
$(CC) -o $@ $^ $(LIB) $(LDFLAG)
$(OBJ):$(SRC)
$(CC) -c $(SRC)
#all
all:$(TARGET)
$(CC) -o $(TARGET) $(SRC) $(LIB) $(LDFLAG)
#clean
clean:
rm -rf *.o $(TARGET)
*/
// ————————————————————————————————————
/*
typedef struct
{
int argc;
char **argv;
int sock;
}st_app_param;
const char *g_version = "V1.0.0 24.08.16";
int child_mian_ini()
{
int i_re;
i_re = gw_support_init();
if(i_re < 0)
{
printf("解析支持文件错误.\n");
return -1;
}
i_re = gw_config_init();
if(i_re < 0)
{
printf("解析配置文件错误.\n");
return -1;
}
i_re = gw_data_init();
if(i_re < 0)
{
printf("数据初始化错误.\n");
return -1;
}
i_re = gw_modol_init();
if(i_re < 0)
{
printf("解析模型文件错误.\n");
return -1;
}
i_re = gw_stat_init();
if(i_re < 0)
{
printf("数据统计初始化错误.\n");
return -1;
}
i_re = gw_process_init();
if(i_re < 0)
{
printf("规约初始化错误.\n");
return -1;
}
i_re = gw_manage_init();
if(i_re < 0)
{
printf("界面通讯初始化错误.\n");
return -1;
}
pthread_create(tid,thread_task1,p_param);
while(1)
{
get_sys_time();
sleep(1);
}
}
int child_main(int argc,char **argv)
{
if((argc == 2)&&(strcasecmp(argv[1],"-version") == 0))
{
printf("version [%s]",g_version);
}
child_mian_ini();
}
static int run_child_process_thread((void *)param)
{
st_app_param *p_param;
p_param = param;
chlid_main(p_parm->argc,p_param->argv);
}
static int run_child_process(int argc,char **argv,int sock)
{
int i_re;
pthread_t *tid;
st_app_param p_param;
p_param.argc = argc;
p_param.argv = argv;
p_param.sock = sock;
pthread_creat(tid,run_child_process_thread,(void *)p_param);
i_re = recv(sock,..,0);//阻塞接收
send(sock,'q',0);
}
int main(int argc,char**argv)
{
int i_re,fd,pid;
char lock_file[16];
socketpair sockpaire[2];
sprintf(lock_file,"%s.lock",argv[0]);
fd = open(lock_file,_O_WRONLY|_EXC,0777);
if(fd < 0)
{
printf("应用:[%s]已运行.\n",argv[0]);
return 0;
}
sockpaire[0] = -1;
while(1)
{
i_re = socketpaire(sockpaire,AN_UNIX,..);
if(i_re < 0)
{
printf("[%d]创建sockpaire失败.\n",getpid());
return 0;
}
pid = fork();
if(pid < 0)
{
printf("[%d]创建进程失败.\n",getpid());
close(sockpaire[0]);
sockpaire[0] = -1
close(sockpaire[1]);
return 0;
}
if(pid == 0)//child process
{
close(sockpair[0]);
return run_child_process(argc,argv,sockpair[1]);
}
printf("[%d]创建子进程成功.\n",getpid());
close(sockpair[1]);
while(1)//father process
{
i_re = recv(sockpaire[0],....,0);//阻塞接收
if(i_re <= 0)
{
//连接中断,重连
sockpaire[0] = -1;
break;
}
else
{
//正常退出
goto EXIT:
}
}
EXIT:
//退出操作
if(sockpaire[0] == -1)
{
//有子进程,关闭子进程
}
close(fd);
unlink(file_lock);
}
}
*/

View File

@ -0,0 +1,63 @@
/*
* @Author: zxm5337@163.com
* @Date: 2024-06-25 10:26:36
* @LastEditors: DaMingSY zxm5337@163.com
* @LastEditTime: 2024-09-03 09:19:23
* @FilePath: \controller-v2\User\lib\control\custom\cascade_pid_zh.h
* @Description: ,`customMade`, koroFileHeader查看配置 : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#ifndef __CASCADE_PID_ZH__
#define __CASCADE_PID_ZH__
#include "data_type_def.h"
typedef enum
{
TARGET_DIR_ADD,
TARGET_DIR_SUB,
} target_dir_e;
typedef struct
{
float kp;
float ki;
float kd;
float kup;
float kui;
float kud;
} fuzzy_pid_t;
typedef struct
{
BOOL iDetach, sm_open, fuzzy_open;
float feedBack;
float target, maxTarget;
float duty, kp, ki, kd;
float error, dError, lastError, errorDead;
float integral, iDetachCondation;
float output, maxOutput;
fuzzy_pid_t fuzzy_pid;
} smart_pid_t;
typedef struct
{
smart_pid_t inner;
smart_pid_t outer;
float output;
} cascade_pid_t;
typedef struct CascadePID
{
void (*smart_pid_init)(smart_pid_t *pid, float *duty, float *kp, float *ki, float *kd, float *errorDead, float *iDetachCondation, float *maxOut);
void (*cascade_pid_init)(cascade_pid_t *pid, smart_pid_t *pid_outer, smart_pid_t *pid_inner);
void (*smart_pid_calc)(smart_pid_t *pid, float *target, float *feedback);
void (*cascade_pid_calc)(struct CascadePID *pid, float *outerRef, float *outerFdb, float *innerFdb);
smart_pid_t smart_pid;
cascade_pid_t cascade_pid;
} pid_zh1_t; // PID_t;
extern void pid_zh_constructor1(struct CascadePID *pid);
#endif

View File

@ -0,0 +1,26 @@
# 架构
|文件|路径| <div style="width:300px">说明</div>|
|:--|:--|:--|
|pid|User\lib\control\src|PID算法模块|
|execute|User\application\src|执行器|
|app_flow|User|任务流程控制|
## APP_FLOW任务流程控制
> adjust_inspection 中在没有检测到调试信号时执行<b style="color:blue">execute_dac,EXECUTE_PLAN</b>定义了需要执行的算法任务计划
## PID算法模块
文件内容:
|文件| <div style="width:300px">说明</div>|
|:--|:--|
|pid.c|构造算法的入口|
|pid_common.c|普通算法|
|pid_neural.c|神经网络算法|
|pid_fuzzy.c|模糊算法|
<b style="color:blue">custom 目录下为各自算法实现</b>
## EXECUTE执行器
> execute_pid_init中定义了初始化参数
> execute_dac中定义了执行器

View File

@ -1,9 +1,17 @@
#ifndef __PID_H__ #ifndef __PID_H__
#define __PID_H__ #define __PID_H__
#include "lib.h" #include "lib.h"
#include "pid_auto_tune.h" #include "pid_auto_tune.h"
#define INCOMPLETE_DIFFEREN 0 // 不完全微分 #include "pid_c.h"
#include "pid_g.h"
#include "pid_x.h"
#include "pid_zh.h"
#include "pid_zh1.h"
#include "pid_hd.h"
#define INCOMPLETE_DIFFEREN 1 // 不完全微分
typedef enum typedef enum
{ {
@ -54,6 +62,7 @@ typedef struct
float32 err_limit; float32 err_limit;
BOOL detach; BOOL detach;
float32 err_dead; float32 err_dead;
// 不完全微分方式在微分环节采用了低通滤波有效地提高了微分项的特性。其中α的取值是一个0~1之间的数。两个极限值在0时其实就是没有滤波的普通微分环节而取1时则没有微分作用。所以α的取值对不完全微分的效果是至关重要的一般要根据被控对象的特性来确定
float32 alpha; float32 alpha;
float32 lastdev; float32 lastdev;
float32 out; float32 out;
@ -219,6 +228,14 @@ typedef struct
pid_common_t common; pid_common_t common;
pid_neural_t neural; pid_neural_t neural;
pid_fuzzy_t fuzzy; pid_fuzzy_t fuzzy;
// 自定义PID
pid_c_t cao;
pid_g_t gao;
pid_x_t xu;
pid_zh_t zhang;
pid_zh1_t zhang1;
pid_hd_t hd;
} pid_u; } pid_u;
pid_auto_tune_t auto_tune; pid_auto_tune_t auto_tune;
} pid_t; } pid_t;

View File

@ -20,6 +20,22 @@ void pid_constructor(pid_t *self)
case PID_TYPE_AUTO_TUNE: case PID_TYPE_AUTO_TUNE:
pid_auto_tune_constructor(&self->auto_tune); pid_auto_tune_constructor(&self->auto_tune);
break; break;
case PID_TYPE_CUSTOM_CAO:
pid_c_constructor(&self->pid_u.cao);
break;
case PID_TYPE_CUSTOM_GAO:
pid_g_constructor(&self->pid_u.gao);
break;
case PID_TYPE_CUSTOM_XU:
pid_x_constructor(&self->pid_u.xu);
break;
case PID_TYPE_CUSTOM_ZHANG:
// pid_zh_constructor(&self->pid_u.zhang);
pid_zh_constructor1(&self->pid_u.zhang1);
break;
case PID_TYPE_CUSTOM_HANGDIAN:
pid_hd_constructor(&self->pid_u.hd);
break;
default: default:
break; break;
} }

View File

@ -13,17 +13,17 @@
#define PL 3 #define PL 3
// 定义偏差E的范围因为设置了非线性区间误差在10时才开始进行PID调节这里E的范围为10 // 定义偏差E的范围因为设置了非线性区间误差在10时才开始进行PID调节这里E的范围为10
#define MAXE (100) #define MAXE (30)
#define MINE (-MAXE) #define MINE (-MAXE)
// 定义EC的范围因为变化非常缓慢每次的EC都非常小这里可以根据实际需求来调整 // 定义EC的范围因为变化非常缓慢每次的EC都非常小这里可以根据实际需求来调整
#define MAXEC (100) #define MAXEC (30)
#define MINEC (-MAXEC) #define MINEC (-MAXEC)
// 定义e,ec的量化因子 // 定义e,ec的量化因子
#define KE 3 / MAXE #define KE 3 / MAXE
#define KEC 3 / MAXEC #define KEC 3 / MAXEC
// 定义输出量比例因子 // 定义输出量比例因子
#define KUP 1.0f // 这里只使用了模糊PID的比例增益 #define KUP 3.0f // 这里只使用了模糊PID的比例增益
#define KUI 0.0f #define KUI 0.0f
#define KUD 0.0f #define KUD 0.0f
@ -442,6 +442,7 @@ static void _set_ctrl_prm(struct PID_FUZZY *self, float32 kp, float32 ki, float3
pri->detach = FALSE; pri->detach = FALSE;
pri->sm = FALSE; pri->sm = FALSE;
pri->ki_enable = TRUE; pri->ki_enable = TRUE;
pri->alpha = 0.25;
} }
else else
{ {
@ -456,6 +457,7 @@ static void _set_ctrl_prm(struct PID_FUZZY *self, float32 kp, float32 ki, float3
pri->out_max = out_max; pri->out_max = out_max;
pri->out_min = out_min; pri->out_min = out_min;
pri->ki_enable = TRUE; pri->ki_enable = TRUE;
pri->alpha = 0.25;
} }
} }

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief basic KV samples.
*
* basic Key-Value Database KV feature samples
* get and show currnet boot counts
*/
#include <flashdb.h>
#ifdef FDB_USING_KVDB
#define FDB_LOG_TAG "[sample][kvdb][basic]"
void kvdb_basic_sample(fdb_kvdb_t kvdb)
{
struct fdb_blob blob;
int boot_count = 0;
FDB_INFO("==================== kvdb_basic_sample ====================\n");
{ /* GET the KV value */
/* get the "boot_count" KV value */
fdb_kv_get_blob(kvdb, "boot_count", fdb_blob_make(&blob, &boot_count, sizeof(boot_count)));
/* the blob.saved.len is more than 0 when get the value successful */
if (blob.saved.len > 0) {
FDB_INFO("get the 'boot_count' value is %d\n", boot_count);
} else {
FDB_INFO("get the 'boot_count' failed\n");
}
}
{ /* CHANGE the KV value */
/* increase the boot count */
boot_count ++;
/* change the "boot_count" KV's value */
fdb_kv_set_blob(kvdb, "boot_count", fdb_blob_make(&blob, &boot_count, sizeof(boot_count)));
FDB_INFO("set the 'boot_count' value to %d\n", boot_count);
}
FDB_INFO("===========================================================\n");
}
#endif /* FDB_USING_KVDB */

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief blob KV samples.
*
* Key-Value Database blob type KV feature samples
*/
#include <flashdb.h>
#ifdef FDB_USING_KVDB
#define FDB_LOG_TAG "[sample][kvdb][blob]"
void kvdb_type_blob_sample(fdb_kvdb_t kvdb)
{
struct fdb_blob blob;
FDB_INFO("==================== kvdb_type_blob_sample ====================\n");
{ /* CREATE new Key-Value */
int temp_data = 36;
/* It will create new KV node when "temp" KV not in database.
* fdb_blob_make: It's a blob make function, and it will return the blob when make finish.
*/
fdb_kv_set_blob(kvdb, "temp", fdb_blob_make(&blob, &temp_data, sizeof(temp_data)));
FDB_INFO("create the 'temp' blob KV, value is: %d\n", temp_data);
}
{ /* GET the KV value */
int temp_data = 0;
/* get the "temp" KV value */
fdb_kv_get_blob(kvdb, "temp", fdb_blob_make(&blob, &temp_data, sizeof(temp_data)));
/* the blob.saved.len is more than 0 when get the value successful */
if (blob.saved.len > 0) {
FDB_INFO("get the 'temp' value is: %d\n", temp_data);
}
}
{ /* CHANGE the KV value */
int temp_data = 38;
/* change the "temp" KV's value to 38 */
fdb_kv_set_blob(kvdb, "temp", fdb_blob_make(&blob, &temp_data, sizeof(temp_data)));
FDB_INFO("set 'temp' value to %d\n", temp_data);
}
{ /* DELETE the KV by name */
fdb_kv_del(kvdb, "temp");
FDB_INFO("delete the 'temp' finish\n");
}
FDB_INFO("===========================================================\n");
}
#endif /* FDB_USING_KVDB */

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