diff --git a/Core/App/adc.c b/Core/App/adc.c index 3ac84ae..96bbcca 100644 --- a/Core/App/adc.c +++ b/Core/App/adc.c @@ -12,7 +12,7 @@ * - Установку callback-функций для событий: * - завершение секвенсора * - половина буфера - * - полный буфер + * - полный буфера * - ошибка * + Управление цифровыми компараторами (DC0-DC3): * - Инициализацию и конфигурацию компараторов @@ -39,56 +39,102 @@ ##### Как использовать этот драйвер ##### ============================================================================== - 1. Общие функции ADC: + -------------------------- Общие функции АЦП -------------------------------- - a) Инициализация: - (+) adc_init_first() — обязательный вызов перед использованием ADC + 1. Инициализация АЦП: + (+) adc_init_first() - обязательный вызов перед использованием АЦП + (+) Настраивает тактирование, GPIO и ожидает готовности аналогового модуля + + 2. Калибровка каналов: + (+) ADC_Channel_Calibr(&hadc, channel, OFFSET, GAIN) - калибровка смещения и усиления + (+) Формула калибровки: Dc = Dr * (4096+GAIN)/4096 + OFFSET + + 3. Чтение значений каналов: + (+) ADC_Channel_GetValue(&hadc, channel) - получение текущего значения канала + (+) Данные обновляются автоматически при работе секвенсоров + + 4. Инициализация GPIO: + (+) adc_gpio_init(hadc.ChannelEnable) - настраивает пины выбранных каналов + (+) Вызывается автоматически в adc_init_first() + + ------------------------ Секвенсоры (SEQ0, SEQ1) ---------------------------- - b) Работа с каналами: - (+) ADC_Get_ChannelValue(&hadc, channel) — получение текущего значения канала + 1. Настройка в periph_config.h: + (+) Определите adc_seq0_config, adc_seq1_config + (+) Настройте ADC_ClockSource и ADC_ClockMHz для тактирования АЦП + (+) Определите adc_ch_config для включения нужных каналов + + 2. Инициализация секвенсоров: + (+) adc_seq_init(&hadc, ADC_SEQ_Num_0, &adc_seq0_config) - инициализация SEQ0 + (+) Аналогично для SEQ1 при необходимости + + 3. Работа с секвенсорами: + (+) ADC_SEQ_Start(&hadc, ADC_SEQ_Num_0, buffer, buffer_size) - запуск с буфером + (+) ADC_SEQ_Stop(&hadc, ADC_SEQ_Num_0) - остановка секвенсора + (+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, тип, func) - установка обработчика + (+) ADC_SEQ_SoftwareStart() - программный запуск преобразования + + 4. Обработка прерываний секвенсоров: + (+) ADC_SEQ0_IRQHandler - вызвать adc_seq_irq_handler(&hadc, ADC_SEQ_Num_0) + (+) ADC_SEQ1_IRQHandler - вызвать adc_seq_irq_handler(&hadc, ADC_SEQ_Num_1) + + ------------------------ Цифровые компараторы (DC) -------------------------- + + ============================================================================== + ##### Особенности работы ##### + ============================================================================== + + -------------------------- Общие особенности -------------------------------- - 2. Секвенсоры (SEQ): - - a) Настройка периферии (periph_config.h): - (+) Определить структуры ADC_SEQ_ExtInit_TypeDef для нужных секвенсоров: - adc_seq0_config, adc_seq1_config - (+) Настроить последовательность каналов, режимы работы - (+) Настроить прерывания (IT) и ITCount - (+) Определить callback-функции (можно NULL) - - b) Инициализация: - (+) adc_init_first() — первичная настройка тактирования, сброс ADC, инициализация хендла hadc - (+) adc_seq_init(&hadc, ADC_SEQ_Num_0, &adc_seq0_config) — инициализация конкретного секвенсора - - c) Callback-функции (опционально): - (+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_SeqCplt, Callback) — завершение секвенсора - (+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_BuffHalf, Callback) — половина буфера - (+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_BuffFull, Callback) — полный буфер - (+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_Error, Callback) — ошибки - - d) Запуск и остановка: - (+) ADC_SEQ_Start(&hadc, ADC_SEQ_Num_0, data_buffer, buffer_size) — запуск с буфером - (+) ADC_SEQ_Stop(&hadc, ADC_SEQ_Num_0) — остановка секвенсора - - e) Работа с данными: - (+) ADC_Get_ChannelValue(&hadc, channel) — чтение текущего значения канала из хендла - (+) ADC_SEQ_SoftwareStart() — программный запуск преобразования - - f) Обработка прерываний: - (+) adc_seq_irq_handler(&hadc, ADC_SEQ_Num_0) — обработчик прерываний секвенсора - - В обработчике автоматически читаются данные из FIFO, обновляются каналы и буфер - - В обработчиках автоматически вызываются соответствующие callback-функции - и сбрасываются флаги - - g) Особенности работы: - (+) Данные автоматически читаются из FIFO в прерывании - (+) Поддерживается кольцевой буфер (BufferCircular) - (+) Автоматический вызов callback при заполнении половины/всего буфера - - 3. Цифровые компараторы (DC): - + - Частота ADC: + - Задается через ADC_ClockMHz в periph_config.h + - Автоматически настраивается делитель от источника тактирования + + - Аналоговый модуль (AM): + - Требует времени для старта после включения (до 1 мс) + - adc_init_first() ожидает готовности AM с таймаутом 1 секунда + - При неудаче вызывает Error_Handler() + + - Калибровка: + - OFFSET: смещение в диапазоне [-255, 255] квантов АЦП + - GAIN: коэффициент усиления в диапазоне [-255, 255] квантов АЦП (4096+GAIN) + - Калибровка применяется аппаратно для каждого канала отдельно + + ------------------------ Секвенсоры (SEQ0, SEQ1) ---------------------------- + - Буферизация данных: + - Данные в буфере хранятся в формате [канал][время] + - При buffer_size=100 для 2 каналов буфер будет 200 элементов + - Буфер может быть кольцевым (BufferCircular=ENABLE) + + - Прерывания секвенсоров: + - Генерируются после заданного количества рестартов (ITCount) + - ITCount=0 означает прерывание после каждого прохода секвенсора + - Данные автоматически читаются из FIFO в прерывании + + - Работа с усреднением: + - Аппаратное усреднение измерения: + - 2, 4, 8, 16, 32 или 64 выборок (SEQ_Init.ReqAverage) + - Включается через SEQ_Init.ReqAverageEn + - Усредненные значения помещаются в FIFO как единый результат + - Аппаратное усреднение рестартов + - 2, 4, 8, 16, 32, 64, 128, 256 выборок (SER_Init.RestartCount + 1) + - Включается через SEQ_Init.RestartAverageEn + - Усредненные значения помещаются в FIFO как единый результат + + - Таймер рестартов: + - Период в тиках ADC_ClockMHz/2 (драйвер автоматически делит на 2) + - Используется для периодического запуска секвенсора + - При RestartTimer=0 рестарт происходит немедленно + + - Чтение FIFO: + - FIFO буфер на 32 элемента автоматически читается в прерывании + - Данные распределяются по каналам согласно последовательности в Req[0..3] + - При переполнении FIFO (>32 элементов до прерывания) возможна потеря данных + + ------------------------ Цифровые компараторы (DC) -------------------------- + @endverbatim ****************************************************************************** */ @@ -122,6 +168,10 @@ void adc_init_first(void) // Включаем аналоговый модуль ADC_AM_Cmd(ENABLE); + // Настройка пинов для ADC + hadc.ChannelEnable = &adc_ch_config; + adc_gpio_init(hadc.ChannelEnable); + hadc.Instance = ADC; #endif @@ -140,15 +190,6 @@ void adc_init_first(void) } #endif -#if (USE_ADC_DC0==1) -#endif -#if (USE_ADC_DC1==1) -#endif -#if (USE_ADC_DC2==1) -#endif -#if (USE_ADC_DC3==1) -#endif - #if (USE_ADC_SEQ0==1) || (USE_ADC_SEQ1==1) || (USE_ADC_DC0==1) || (USE_ADC_DC1==1) || (USE_ADC_DC2==1) || (USE_ADC_DC3==1) uint32_t starttick = millis(); while (!ADC_AM_ReadyStatus()) { @@ -158,6 +199,41 @@ void adc_init_first(void) #endif } +/** + * @brief Записать калибровочные значения канала + * @param hadc указатель на хендл АЦП + * @param channel номер канала + * @param OFFSET Коэффициент корректировки смещения нуля АЦП в квантах [-255:255] + * @param GAIN Коэффициент корректировки усиления зн АЦП в квантах [-255:255] + * @retval значение ADC (0 если данные невалидны) + * @details Результат преобразования передается на схему коррекции, которая нивелирует + * ошибку усиления и смещения нуля и работа которой описывается формулой + * Dc = Dr * (4096+GAIN)/4096 + OFFSET + */ +OperationStatus ADC_Channel_Calibr(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel, int OFFSET, int GAIN) +{ + if (!hadc || (int)channel >= ADC_CH_Total) + return ERROR; + + ADC_CH_SetOffsetTrim(channel, OFFSET); + ADC_CH_SetGainTrim(channel, GAIN); + return OK; +} + +/** + * @brief Получение текущего значения канала + * @param hadc указатель на хендл АЦП + * @param channel номер канала + * @retval значение ADC (0 если данные невалидны) + */ +uint16_t ADC_Channel_GetValue(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel) +{ + if (!hadc || (int)channel >= ADC_CH_Total) + return 0; + + return hadc->ChannelData[channel]; +} + //-- ADC Sequencers API functions ---------------------------------------------- /** @@ -302,20 +378,6 @@ OperationStatus ADC_SEQ_Stop(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Nu return OK; } -/** - * @brief Получение текущего значения канала - * @param hadc указатель на хендл АЦП - * @param channel номер канала - * @retval значение ADC (0 если данные невалидны) - */ -uint16_t ADC_Get_ChannelValue(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel) -{ - if (!hadc || (int)channel >= ADC_CH_Total) - return 0; - - return hadc->ChannelData[channel]; -} - /** * @brief Программный запуск преобразования */ @@ -323,7 +385,7 @@ void ADC_SEQ_SoftwareStart(void) { ADC_SEQ_SwStartCmd(); } -int itcnt; + /** * @brief Обработчик прерываний секвенсора * @param hadc указатель на хендл АЦП @@ -335,7 +397,7 @@ void adc_seq_irq_handler(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num) if (!hadc || !hadc->Instance || !hadc->SEQ[SEQ_Num].Config) return; // GPIO_SetBits(GPIOA, GPIO_Pin_7); - itcnt++; + ADC_SEQ_HandleTypeDef *hseq = &hadc->SEQ[SEQ_Num]; ADC_SEQ_ExtInit_TypeDef *conf = hseq->Config; @@ -482,3 +544,45 @@ static void __adc_seq_fifo_read(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ //-- ADC Digital Comparators API functions ------------------------------------- + + + +//-- ADC GPIO functions -------------------------------------------------------- +/** + * @brief Инициализация GPIO для ADC + */ +void adc_gpio_init(ADC_ChannelEnableTypeDef *ChEn) +{ +#if (USE_ADC_SEQ0==1) || (USE_ADC_SEQ1==1) || (USE_ADC_DC0==1) || (USE_ADC_DC1==1) || (USE_ADC_DC2==1) || (USE_ADC_DC3==1) + // Получаем структуру + GPIO_Init_TypeDef *ch0_config = gpio_get_init(ADC_Ch0_GPIO_Port, ADC_Ch0_Pin); + GPIO_Init_TypeDef *ch1_config = gpio_get_init(ADC_Ch1_GPIO_Port, ADC_Ch1_Pin); + GPIO_Init_TypeDef *ch2_config = gpio_get_init(ADC_Ch2_GPIO_Port, ADC_Ch2_Pin); + GPIO_Init_TypeDef *ch3_config = gpio_get_init(ADC_Ch3_GPIO_Port, ADC_Ch3_Pin); + + if(ChEn->Ch0) + { + GPIO_StructInit(ch0_config); + ch0_config->Pin = ADC_Ch0_Pin; + GPIO_Init(ADC_Ch0_GPIO_Port, ch0_config); + } + if(ChEn->Ch1) + { + GPIO_StructInit(ch1_config); + ch1_config->Pin = ADC_Ch1_Pin; + GPIO_Init(ADC_Ch1_GPIO_Port, ch1_config); + } + if(ChEn->Ch2) + { + GPIO_StructInit(ch2_config); + ch2_config->Pin = ADC_Ch2_Pin; + GPIO_Init(ADC_Ch2_GPIO_Port, ch2_config); + } + if(ChEn->Ch3) + { + GPIO_StructInit(ch3_config); + ch3_config->Pin = ADC_Ch3_Pin; + GPIO_Init(ADC_Ch3_GPIO_Port, ch3_config); + } +#endif +} diff --git a/Core/App/adc.h b/Core/App/adc.h index bb381e4..9c8befe 100644 --- a/Core/App/adc.h +++ b/Core/App/adc.h @@ -17,6 +17,18 @@ #include "retarget_conf.h" //-- Defines ------------------------------------------------------------------- +// Дефайны для пинов ADC +#define ADC_Ch0_Pin GPIO_Pin_0 /**< PB0 — ADC Channel 0 */ +#define ADC_Ch0_GPIO_Port GPIOB /**< GPIO порт ADC Channel 0 */ + +#define ADC_Ch1_Pin GPIO_Pin_1 /**< PB1 — ADC Channel 1 */ +#define ADC_Ch1_GPIO_Port GPIOB /**< GPIO порт ADC Channel 1 */ + +#define ADC_Ch2_Pin GPIO_Pin_2 /**< PB2 — ADC Channel 2 */ +#define ADC_Ch2_GPIO_Port GPIOB /**< GPIO порт ADC Channel 2 */ + +#define ADC_Ch3_Pin GPIO_Pin_3 /**< PB3 — ADC Channel 3 */ +#define ADC_Ch3_GPIO_Port GPIOB /**< GPIO порт ADC Channel 3 */ //-- Types --------------------------------------------------------------------- @@ -32,6 +44,17 @@ typedef enum ADC_Callback_Error, /*!< Ошибка */ }ADC_CallbackTypeDef; +/** + * @brief Типы callback-функций ADC + */ +typedef struct +{ + unsigned Ch0:1; /*!< АЦП Канал 0 */ + unsigned Ch1:1; /*!< АЦП Канал 1 */ + unsigned Ch2:1; /*!< АЦП Канал 2 */ + unsigned Ch3:1; /*!< АЦП Канал 3 */ +}ADC_ChannelEnableTypeDef; + /** * @brief Расширенная конфигурация секвенсора ADC */ @@ -42,6 +65,7 @@ typedef struct uint8_t ITCount; /*!< Количество запросов для генерации прерывания */ FunctionalState BufferCircular; /*!< Циклический буфер */ + void (*SEQCpltCallback)(void); /*!< Вызывается при завершении секвенсора */ void (*BuffHalfCallback)(void); /*!< Вызывается при заполнении половины буфера */ void (*BuffFullCallback)(void); /*!< Вызывается при заполнении буфера */ @@ -87,11 +111,12 @@ typedef struct { ADC_TypeDef *Instance; /*!< Регистры ADC */ - ADC_SEQ_HandleTypeDef SEQ[ADC_SEQ_Total]; /*!< Хендл секвенсоров */ - ADC_DC_ExtInit_TypeDef DC[ADC_DC_Total]; /*!< Хендл компараторов */ + ADC_SEQ_HandleTypeDef SEQ[ADC_SEQ_Total]; /*!< Хендл секвенсоров */ + ADC_DC_ExtInit_TypeDef DC[ADC_DC_Total]; /*!< Хендл компараторов */ /* ===== Channels ===== */ - uint16_t ChannelData[ADC_CH_Total]; /*!< Текущие значения каналов */ + ADC_ChannelEnableTypeDef *ChannelEnable; /*!< Какие каналы АЦП инициализировать (GPIO Pin) */ + uint16_t ChannelData[ADC_CH_Total]; /*!< Текущие значения каналов */ }ADC_HandleTypeDef; //-- External handles ---------------------------------------------------------- extern ADC_HandleTypeDef hadc; @@ -99,6 +124,14 @@ extern ADC_HandleTypeDef hadc; //-- Exported functions prototypes --------------------------------------------- /* Первичная инициализация ADC */ void adc_init_first(void); +void adc_gpio_init(ADC_ChannelEnableTypeDef *ChEn); + +/* ADC API functions */ + +/* Записать калибровочные значения канала */ +OperationStatus ADC_Channel_Calibr(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel, int OFFSET, int GAIN); +/* Получение текущего значения канала */ +uint16_t ADC_Channel_GetValue(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel); /* Sequencer Init functions*/ @@ -107,7 +140,7 @@ OperationStatus adc_seq_init(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Nu /* Обработчик прерываний секвенсора */ void adc_seq_irq_handler(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num); -/* Sequencer API functions*/ +/* Sequencer API functions */ /* Установка коллбека секвенсора АЦП */ OperationStatus ADC_SEQ_Set_Callback(ADC_HandleTypeDef* hadc, ADC_SEQ_Num_TypeDef SEQ_Num, ADC_CallbackTypeDef CallbackType, void (*Callback)(void)); @@ -117,8 +150,6 @@ OperationStatus ADC_SEQ_Start(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_N /* Остановка секвенсора АЦП */ OperationStatus ADC_SEQ_Stop(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num); -/* Получение текущего значения канала */ -uint16_t ADC_Get_ChannelValue(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel); /* Программный запуск преобразования секвенсора */ void ADC_SEQ_SoftwareStart(void); diff --git a/Core/App/gpio.c b/Core/App/gpio.c index a806d9c..9dc7251 100644 --- a/Core/App/gpio.c +++ b/Core/App/gpio.c @@ -29,7 +29,7 @@ 1. Настройка периферии (periph_config.h): (+) Определить массивы GPIO_Init_TypeDef для портов: gpioa_config[32], gpiob_config[32] - (+) Настроить режим пинов: Input, Output, AltFunc и другие функции + (+) Настроить режим пинов: Input, Output, AltFunc или не используется (аналог режим) 2. Инициализация GPIO: (+) gpio_init() — инициализация портов GPIOA и GPIOB @@ -47,9 +47,37 @@ (+) GPIO_Switch_Init(&sw, GPIOB, GPIO_PIN_0, SET) — инициализация кнопки (+) GPIO_Read_Switch(&sw) — чтение состояния кнопки с фильтрацией - 5. Утилитарные функции: - (+) gpio_get_init(GPIOA, GPIO_PIN_5) — получение конфигурации пина + 5. Получение конфигурации пинов: + (+) gpio_get_init(порт, пин) - для периферии + ============================================================================== + ##### Особенности работы ##### + ============================================================================== + + - Динамические режимы светодиодов: + - Моргание: простой on/off с заданным периодом + - Плавное затухание: квадратичное изменение яркости через ШИМ + - Требуют вызова GPIO_LED_Dynamic_Handle() в основном цикле + + - Защита от дребезга: + - Фильтрация по времени (Sw_FilterDelay в миллисекундах) + - Неблокирующий алгоритм с отслеживанием состояния + - При изменении уровня запускается таймер, состояние обновляется после задержки + + - ШИМ для плавного затухания: + - Программная генерация с 15 уровнями яркости (LED_PWM_TICKS) + - Полный цикл затухания-разтухания: 2 × LED_PWM_TICKS шагов + + - Конфигурация пинов: + - Периферия может перезаписывать конфигурацию пинов (например, UART на AltFunc) + - gpio_get_init() позволяет периферии получить исходную конфигурацию + - После использования периферии можно восстановить исходные настройки + + - Табличный подход: + - Каждый пин имеет свою строку в массиве конфигурации + - Позволяет централизованно управлять всеми пинами + - Упрощает отладку и модификацию конфигурации + @endverbatim ****************************************************************************** */ diff --git a/Core/App/gpio.h b/Core/App/gpio.h index 7d1db46..c70f4a6 100644 --- a/Core/App/gpio.h +++ b/Core/App/gpio.h @@ -23,7 +23,6 @@ #define GPIO_PinMode_Input DISABLE, DISABLE, ENABLE #define GPIO_PinMode_Output ENABLE, DISABLE, ENABLE #define GPIO_PinMode_AltFunc DISABLE, ENABLE, ENABLE -//#define GPIO_PinMode_Analog DISABLE, DISABLE, DISABLE #ifndef LED_PWM_TICKS #define LED_PWM_TICKS 15 ///< Количество тиков в периоде ШИМ diff --git a/Core/App/sysclk.c b/Core/App/sysclk.c index 7601265..d390c0a 100644 --- a/Core/App/sysclk.c +++ b/Core/App/sysclk.c @@ -14,6 +14,9 @@ ****************************************************************************** * @attention * + * Этот драйвер должен быть инициализирован ПЕРВЫМ в программе, до любой другой периферии. + * Неправильная настройка тактирования может привести к неработоспособности всего МК. + * * Использование этого драйвера предполагает наличие корректных настроек: * - Определены константы SYSCLK_CORE_CLOCK_MHZ и SYSCLK_Oscil_Type в periph_config.h * - Определен тип системного тика SYSCLK_TickType в periph_config.h @@ -24,37 +27,44 @@ ##### Как использовать этот драйвер ##### ============================================================================== - 1. Настройка периферии (periph_config.h): - (+) Определить SYSCLK_CORE_CLOCK_MHZ - частота ядра в МГц (например, 100) - (+) Определить SYSCLK_Oscil_Type - тип осциллятора (RCU_Oscil_OSE или RCU_Oscil_OSI) - (+) Определить SYSCLK_TickType - тип системного тика (SYSCLK_Tick_1us, SYSCLK_Tick_1ms и т.д.) + 1. Настройка в periph_config.h: + (+) SYSCLK_CORE_CLOCK_MHZ - частота ядра в МГц (например, 100) + (+) SYSCLK_Oscil_Type - источник тактирования (RCU_Oscil_OSE или RCU_Oscil_OSI) + (+) SYSCLK_TickType - период системного тика (от SYSCLK_Tick_1us до SYSCLK_Tick_100ms) - 2. Инициализация тактирования: - (+) sysclk_init() — обязательный вызов в начале программы - - Автоматически настраивает PLL для заданной частоты - - Настраивает SysTick для генерации системных тиков - - Обновляет SystemCoreClock + 2. Инициализация (в начале main()): + (+) sysclk_init() - настраивает PLL, SysTick и счетчики времени + (+) В SysTick_Handler() вызвать sysclk_irq_handler() 3. Работа со временем: - (+) millis() — получение текущего времени в миллисекундах - (+) micros() — получение текущего времени в микросекундах - (+) sysclk_irq_handler() — обработчик прерываний SysTick (должен вызываться из SysTick_Handler) + (+) millis() - текущее время в миллисекундах (переполнение через 49 дней) + (+) micros() - текущее время в микросекундах (точность зависит от SYSCLK_TickType) - 4. Система коллбеков: - (+) SYSCLK_Set_Callback() — добавление периодического коллбека - - Коллбеки автоматически вызываются в sysclk_irq_handler() с заданным периодом - - Максимальное количество коллбеков: SYSCLK_NUMB_OF_CUSTOM_CALLBACKS + 4. Периодические задачи: + (+) SYSCLK_Set_Callback(func, period_ms) - регистрация функции для периодического вызова + (+) Максимум 16 функций, период должен быть >= периода системного тика - 5. Настройка тактирования Периферии: - (+) АЦП: rcu_set_clock_adc(ClkSrc, ClkMHz, state) - - ClkSrc: источник тактирования (RCU_PeriphClk_OSEClk, RCU_PeriphClk_PLLClk и т.д.) - - ClkMHz: желаемая частота ADC в МГц - - state: включение/выключение тактирования + 5. Настройка тактирования периферии: + (+) rcu_set_clock_adc(source, freq_mhz, enable) - для АЦП + (+) Частота АЦП не должна превышать 12.5 МГц согласно datasheet - 6. Особенности работы: - (+) Системные тики работают на основе SysTick - (+) Поддерживаются различные периоды тиков от 1 мкс до 100 мс - (+) Переполнение счетчиков происходит через ~49 дней + ============================================================================== + ##### Особенности работы ##### + ============================================================================== + + - Выбор SYSCLK_TickType влияет на: + - Точность micros() (при 1ms тике micros() дает значения с шагом 1000) + - Нагрузку на ЦП (1us = 1М прерываний в секунду, 100ms = 10 прерываний в секунду) + - Минимальный период коллбеков (не может быть меньше SYSCLK_TickType) + + - При настройке PLL: + - Драйвер автоматически подбирает делители для заданной частоты + - Если частота недостижима - вызовется Error_Handler() + - Всегда проверяйте supported frequencies в datasheet + + - Коллбеки выполняются в контексте прерывания SysTick: + - Не должны выполняться долго + - Не должны вызывать блокирующие функции @endverbatim ****************************************************************************** diff --git a/Core/App/tmr.c b/Core/App/tmr.c index 132050b..668bd4e 100644 --- a/Core/App/tmr.c +++ b/Core/App/tmr.c @@ -23,43 +23,49 @@ ##### Как использовать этот драйвер ##### ============================================================================== - 1. Настройка периферии (periph_config.h): - (+) Определить структуры TMR_ExtInit_TypeDef для нужных таймеров: - tmr0_config, tmr1_config, tmr2_config, tmr3_config - (+) Настроить частоту/период в мкс или тиках, прескалер - (+) Разрешить прерывания (IT) и при необходимости ADC SOC / DMA запросы - (+) Указать внешнее тактирование при необходимости - (+) Установить callback-функцию (можно NULL) + 1. Настройка в periph_config.h: + (+) Определите структуры tmr0_config, tmr1_config и т.д. + (+) Используйте макросы для задания периода: + • PERIOD_US(us) - период в микросекундах + • FREQ_HZ(hz) - частота в герцах + • LOAD(ticks, presc) - период в тиках с псевдопрескалером - 2. Инициализация таймеров: - (+) tmr_init_first() — первичная настройка тактирования, сброс периферии и NVIC - (+) tmr_init(&htmr, &config) — инициализация конкретного таймера с конфигурацией + 2. Инициализация: + (+) tmr_init_first() - включает тактирование и сброс таймеров + (+) Для каждого таймера автоматически создается хендл (htmr0, htmr1...) - 3. Callback-функции (опционально): - (+) TMR_Set_Callback(&htmr, TMR_Callback_Update, Callback) + 3. Работа с таймером: + (+) TMR_Start(&htmr, IT) / TMR_Stop(&htmr, IT) - запуск и остановка + (+) TMR_Set_Callback(&htmr, TMR_Callback_Update, func) - установка обработчика + (+) TMR_Get_Cnt(&htmr) - текущее значение (уже поделенное на прескалер) + (+) TMR_Get_Period(&htmr) - период (уже поделенный на прескалер) - 4. Запуск и остановка таймера: - (+) TMR_Start(&htmr) — запуск таймера - (+) TMR_Stop(&htmr) — остановка таймера + 4. Задержки: + (+) TMR_Delay(&htmr, ticks) - блокирующая задержка в тиках таймера с псевдопрескалером + (+) TMR_Delay_Start(&htmr, &var) + TMR_Delay_Done(&htmr, ticks, &var) - неблокирующая + задержка в тиках таймера с псевдопрескалером - 5. Задержки: - - Blocking (блокирующая): - (+) TMR_Delay(&htmr, ticks) — задержка в тиках таймера - - Non-blocking (неблокирующая): - (+) TMR_Delay_Start(&htmr, &var) — запоминает текущее значение таймера - (+) TMR_Delay_Done(&htmr, ticks, &var) — проверяет завершение задержки + 5. Обработка прерываний: + (+) Callback-функция будет вызвана автоматически + + ============================================================================== + ##### Особенности работы ##### + ============================================================================== - 6. Получение текущих значений: - (+) TMR_Get_Cnt(&htmr) — получение текущего счетчика с учетом псевдопрескалера - (+) TMR_Get_Period(&htmr) — получение периода таймера с учетом псевдопрескалера + - Псевдопрескалер: + - Это программная абстракция, реальный счетчик всегда считает полные тики + - TMR_Get_Cnt() возвращает значение уже поделенное на (Prescaler+1) + - Позволяет увеличить максимальный период в (Prescaler+1) раз + - Пример: LOAD(1000, 99) даст реальный период в 100 раз больше - 7. Обработка прерываний: - (+) tmr_irq_handler(&htmr) — общий обработчик ISR - - В обработчиках автоматически вызываются соответствующие callback-функции - и сбрасываются флаги + - Особенности счетчиков: + - Максимальный период: 42.9 сек при 100 МГц + - Таймеры используют убывающий счет (от LOAD до 0). Функция TMR_Get_Cnt + возвращает инвертированный счетчик (LOAD-VALUE) - 8. Псевдо-PLIB функции: - (+) TMR_Init(TMRx, InitStruct) — инициализация таймера с расширенными параметрами + - Задержки: + - TMR_Delay проверяет, что задержка < LOAD, иначе вернет ERROR + - Неблокирующие задержки используют "сырые" тики (без учета прескалера) @endverbatim ****************************************************************************** @@ -226,6 +232,7 @@ OperationStatus TMR_Stop(TMR_HandleTypeDef *htmr, FunctionalState IT) * @retval Текущие значение счетчика с псевдопрескалером * @details Если частота таймера 100 МГц, и псведопрескалер 100-1, * то при реальном счетчике 100,000, вернется значение 1,000 + * Также переводит счетчик в возрастающий (LOAD-VALUE) */ uint32_t TMR_Get_Cnt(TMR_HandleTypeDef *htmr) { @@ -235,7 +242,7 @@ uint32_t TMR_Get_Cnt(TMR_HandleTypeDef *htmr) } uint32_t presc = htmr->Config->Prescaler+1; - uint32_t currtick = htmr->Instance->VALUE; + uint32_t currtick = (htmr->Instance->LOAD - htmr->Instance->VALUE); return currtick/presc; } diff --git a/Core/App/tmr.h b/Core/App/tmr.h index 01f5771..4c426bd 100644 --- a/Core/App/tmr.h +++ b/Core/App/tmr.h @@ -20,7 +20,7 @@ //-- Defines ------------------------------------------------------------------- // Дефайны для режима таймера Период в мкс, Частота, ПсевдоПрескалер, Период в тиках /** @brief Период в мкс */ -#define PERIOD_MKS(_per_) (_per_), 0, 0, 0 +#define PERIOD_US(_per_) (_per_), 0, 0, 0 /** @brief Период в Гц */ #define FREQ_HZ(_freq_) 0, (_freq_), 0, 0 /** @brief Период в прескалере и тиках */ diff --git a/Core/App/uart.c b/Core/App/uart.c index fb7d6ea..18d50ac 100644 --- a/Core/App/uart.c +++ b/Core/App/uart.c @@ -24,49 +24,76 @@ ##### Как использовать этот драйвер ##### ============================================================================== - 1. Настройка периферии (periph_config.h): - (+) Определить структуры UART_ExtInit_TypeDef для нужных UART: - uart0_config, uart1_config - (+) Настроить скорость, стоп-биты, четность, длину данных - (+) Настроить FIFO и направление (Tx, Rx или оба) - (+) Определить callback-функции (можно NULL) - (+) Определить пины TX/RX для UART0/UART1 - (+) Включить/отключить очередь сообщений для отправки: USE_TX_QUEUE в uart.h + 1. Настройка в periph_config.h: + (+) Определите uart0_config, uart1_config для нужных UART + (+) Используйте макросы для направления: + • UART_Direction_None - прием и передача отключены + • UART_Direction_RxTx - полный дуплекс + • UART_Direction_Tx - только передача + • UART_Direction_Rx - только прием - 2. Инициализация UART: - (+) uart_init_first() — первичная настройка GPIO, тактирования и NVIC - (+) uart_init(&huart, &config) — инициализация конкретного UART с конфигурацией + 2. Инициализация: + (+) uart_init_first() - настройка GPIO, тактирования и прерываний + (+) uart_init(&huart, &config) - инициализация конкретного UART 3. Callback-функции: - (+) UART_Set_Callback(&huart, UART_Callback_Rx, Callback) — вызов при приёме данных - (+) UART_Set_Callback(&huart, UART_Callback_Tx, Callback) — вызов при завершении передачи - (+) UART_Set_Callback(&huart, UART_Callback_Idle, Callback) — вызов при событии Idle - (+) UART_Set_Callback(&huart, UART_Callback_Error, Callback) — вызов при ошибках + (+) UART_Set_Callback(&huart, UART_Callback_Rx, func) - при завершении приема + (+) UART_Set_Callback(&huart, UART_Callback_Tx, func) - при завершении передачи + (+) UART_Set_Callback(&huart, UART_Callback_Idle, func) - при обнаружении IDLE + (+) UART_Set_Callback(&huart, UART_Callback_Error, func) - при ошибках - 4. Запуск UART и FIFO: - (+) UART_Start(&huart, TxFifoLevel, RxFifoLevel) — включает UART и настраивает FIFO + 4. Запуск UART: + (+) UART_Start(&huart, TxFifoLevel, RxFifoLevel) - включение UART и настройка FIFO 5. Передача и приём данных: - - Режим Polling (blocking): - (+) UART_Transmit(&huart, buf, size, timeout) — передача данных с ожиданием - (+) UART_Receive(&huart, buf, size, timeout) — приём данных с ожиданием - - Режим Interrupt (non-blocking): - (+) UART_Transmit_IT(&huart, buf, size) — передача данных через прерывания - (+) UART_Receive_IT(&huart, buf, size) — приём данных через прерывания + - Режим Polling: + (+) UART_Transmit(&huart, buf, size, timeout) - блокирующая передача + (+) UART_Receive(&huart, buf, size, timeout) - блокирующий прием + - Режим Interrupt: + (+) UART_Transmit_IT(&huart, buf, size) - неблокирующая передача + (+) UART_Receive_IT(&huart, buf, size) - неблокирующий прием - 6. Обработка прерываний UART: - (+) uart_irq_handler(&huart) — общий обработчик ISR для RX/TX FIFO, ошибок и Idle - - В обработчиках автоматически вызываются соответствующие callback-функции - и сбрасываются флаги - - Поддерживается очередь передачи для предотвращения потери данных + 6. Обработка прерываний: + (+) Прерывания обрабатывают TX FIFO, RX FIFO, ошибки и состояние IDLE 7. GPIO для UART: - (+) uart0_gpio_init()/uart0_gpio_deinit() — инициализация и деинициализация UART0 - (+) uart1_gpio_init()/uart1_gpio_deinit() — инициализация и деинициализация UART1 + (+) Пины настраиваются автоматически при вызове uart_init_first() + (+) При необходимости можно вызвать uart0_gpio_deinit() для восстановления - 8. Режимы работы: - (+) Polling (blocking) — функции блокируются до завершения передачи/приёма - (+) Interrupt (non-blocking) — передача/приём через прерывания, управление через callback + ============================================================================== + ##### Особенности работы ##### + ============================================================================== + + - Очередь передачи (USE_TX_QUEUE): + - Циклический буфер на 32 сообщения (TX_QUEUE_SIZE) + - Предотвращает потерю данных при частой отправке + - Включается автоматически при USE_TX_QUEUE=1 в uart.h + - Сообщения обрабатываются последовательно по завершении предыдущей передачи + + - FIFO и прерывания: + - Аппаратный FIFO 16 байт для приема и передачи + - Уровни прерываний настраиваются через TxFifoLevel и RxFifoLevel + - Прерывание TX FIFO генерируется когда FIFO не полон + - Прерывание RX FIFO генерируется когда FIFO не пуст + + - Состояние IDLE: + - Обнаруживается по таймауту приема (32 бит-времени) + - Генерирует прерывание RecieveTimeout + - Полезно для определения конца пакета переменной длины + + - Обработка ошибок: + - Обрабатываются все типы ошибок UART: фрейм, паритет, переполнение, break + - При ошибке вызывается ErrCallback и сбрасываются флаги ошибок + - Ошибки не останавливают работу UART + + - GPIO автоматическая настройка: + - Пины TX/RX настраиваются в AltFunc режим при инициализации + - Поддерживаются стандартные пины (PB10/PB11 для UART0, PB8/PB9 для UART1) + + - Режимы работы: + - Polling: простой, но блокирующий, подходит для инициализации и отладки + - Interrupt: неблокирующий, требует прерываний и поддерживает callback-функций + - Queue: расширенный interrupt режим с буферизацией сообщений @endverbatim ****************************************************************************** diff --git a/Core/App/uart.h b/Core/App/uart.h index 5d2c766..f212093 100644 --- a/Core/App/uart.h +++ b/Core/App/uart.h @@ -32,7 +32,7 @@ // Дефайны для пинов UART #define UART0_Tx_Pin GPIO_Pin_10 /**< PB10 — UART0 Tx */ -#define UART0_Rx_Pin GPIO_Pin_1 /**< PB11 — UART0 Rx */ +#define UART0_Rx_Pin GPIO_Pin_11 /**< PB11 — UART0 Rx */ #define UART0_GPIO_Port GPIOB /**< GPIO порт UART0 */ #define UART1_Tx_Pin GPIO_Pin_8 /**< PB8 — UART1 Tx */ diff --git a/Core/Config/periph_config.h b/Core/Config/periph_config.h index eafc0a0..734aee3 100644 --- a/Core/Config/periph_config.h +++ b/Core/Config/periph_config.h @@ -43,17 +43,17 @@ void Error_Handler(void); /* UART */ #define USE_UART0 0 /*!< Использовать UART0 */ -#define USE_UART1 0 /*!< Использовать UART1 */ +#define USE_UART1 1 /*!< Использовать UART1 */ /* Timers */ -#define USE_TMR0 0 /*!< Использовать Таймер 0 */ -#define USE_TMR1 0 /*!< Использовать Таймер 1 */ -#define USE_TMR2 0 /*!< Использовать Таймер 2 */ +#define USE_TMR0 1 /*!< Использовать Таймер 0 */ +#define USE_TMR1 1 /*!< Использовать Таймер 1 */ +#define USE_TMR2 1 /*!< Использовать Таймер 2 */ #define USE_TMR3 0 /*!< Использовать Таймер 3 */ /* ADC */ #define USE_ADC_SEQ0 0 /*!< Использовать Секвенсор 0 */ -#define USE_ADC_SEQ1 0 /*!< Использовать Секвенсор 1 */ +#define USE_ADC_SEQ1 1 /*!< Использовать Секвенсор 1 */ #define USE_ADC_DC0 0 /*!< Использовать Компаратор 0 */ #define USE_ADC_DC1 0 /*!< Использовать Компаратор 1 */ #define USE_ADC_DC2 0 /*!< Использовать Компаратор 2 */ @@ -75,7 +75,7 @@ void Error_Handler(void); */ static RCU_PLL_Ref_TypeDef SYSCLK_Oscil_Type = RCU_PLL_Ref_OSEClk; -/** @brief Желаемая частота тактирования МК */ +/** @brief Желаемая частота тактирования МК в МГц*/ #define SYSCLK_CORE_CLOCK_MHZ 100 /** @brief Частота тиков uwTick тактирования МК */ @@ -89,7 +89,7 @@ static SYSCLK_TickHz_TypeDef SYSCLK_TickType = SYSCLK_Tick_1ms; /** @brief Конфигурации пинов порта GPIOA */ static GPIO_Init_TypeDef gpioa_config[] = { -// Пин, Режим, Выходной режим, Входной режим, Подтяжка, Нагрузка/Скорость +// Pin, Mode, OutMode, InMode, PullMode, DriveMode { GPIO_Pin_0, GPIO_PinMode_Unused, GPIO_OutMode_PP, GPIO_InMode_Schmitt, GPIO_PullMode_Disable, GPIO_DriveMode_HighFast }, { GPIO_Pin_1, GPIO_PinMode_Unused, GPIO_OutMode_PP, GPIO_InMode_Schmitt, GPIO_PullMode_Disable, GPIO_DriveMode_HighFast }, { GPIO_Pin_2, GPIO_PinMode_Unused, GPIO_OutMode_PP, GPIO_InMode_Schmitt, GPIO_PullMode_Disable, GPIO_DriveMode_HighFast }, @@ -110,7 +110,7 @@ static GPIO_Init_TypeDef gpioa_config[] = { /** @brief Конфигурации пинов порта GPIOB */ static GPIO_Init_TypeDef gpiob_config[] = { -// Пин, Режим, Выходной режим, Входной режим, Подтяжка, Нагрузка/Скорость +// Pin, Mode, OutMode, InMode, PullMode, DriveMode { GPIO_Pin_0, GPIO_PinMode_Unused, GPIO_OutMode_PP, GPIO_InMode_Schmitt, GPIO_PullMode_Disable, GPIO_DriveMode_HighFast }, { GPIO_Pin_1, GPIO_PinMode_Unused, GPIO_OutMode_PP, GPIO_InMode_Schmitt, GPIO_PullMode_Disable, GPIO_DriveMode_HighFast }, { GPIO_Pin_2, GPIO_PinMode_Unused, GPIO_OutMode_PP, GPIO_InMode_Schmitt, GPIO_PullMode_Disable, GPIO_DriveMode_HighFast }, @@ -134,18 +134,18 @@ static GPIO_Init_TypeDef gpiob_config[] = { //-- UART Конфигурации -------------------------------------------------------- #if USE_UART0==1 static UART_ExtInit_TypeDef uart0_config = { -//Стоп биты, Четность, Длина посылки, Скорость, FIFO, Направление работы +//StopBit, ParityBit, DataWidth, BaudRate, FIFO, Direction UART_StopBit_1, UART_ParityBit_Disable, UART_DataWidth_8, 115200, DISABLE, UART_Direction_RxTx, -//Rx Коллбек Tx Коллбек Idle Коллбек Error Коллбек +//RxCallback TxCallback IdleCallback ErrCallback NULL, NULL, NULL, NULL }; #endif #if USE_UART1==1 static UART_ExtInit_TypeDef uart1_config = { -//Стоп биты, Четность, Длина посылки, Скорость, FIFO, Направление работы +//StopBit, ParityBit, DataWidth, BaudRate, FIFO, Direction UART_StopBit_1, UART_ParityBit_Disable, UART_DataWidth_8, 115200, DISABLE, UART_Direction_RxTx, -//Rx Коллбек Tx Коллбек Idle Коллбек Error Коллбек +//RxCallback TxCallback IdleCallback ErrCallback NULL, NULL, NULL, NULL }; #endif @@ -153,135 +153,156 @@ static UART_ExtInit_TypeDef uart1_config = { //-- TMR Конфигурации --------------------------------------------------------- +/** @note Макросы для задания периода: + * - LOAD(Period, Prescaler) - период в тиках и прескалер* + * - FREQ_HZ(Hz) - период таймера в Герцах + * - PERIOD_US(us) - период в микросекундах + * * Т.к. аппаратного прескалера нет, используется программный. + * Получить тики будто бы они с прескалером можно функциями TMR_Get_Cnt, TMR_Get_Period + */ #if USE_TMR0==1 static TMR_ExtInit_TypeDef tmr0_config = { -//Частота Clk МГц, Период обновления +//SystemCoreClock, Period Update SYSCLK_CORE_CLOCK_MHZ, LOAD(0xFFFFFFFF, SYSCLK_CORE_CLOCK_MHZ-1), -//Прерывания Запуск конверсии АЦП Реквест DMA Внешнее тактирование - DISABLE, DISABLE, DISABLE, TMR_ExtInput_Disable +//IT ADCSOC DMAReq ExtInput + DISABLE, DISABLE, DISABLE, TMR_ExtInput_Disable }; #endif #if USE_TMR1==1 static TMR_ExtInit_TypeDef tmr1_config = { -//Частота Clk МГц, Период обновления +//SystemCoreClock, Period Update SYSCLK_CORE_CLOCK_MHZ, FREQ_HZ(10), -//Прерывания Запуск конверсии АЦП Реквест DMA Внешнее тактирование - DISABLE, DISABLE, DISABLE, TMR_ExtInput_Disable +//IT ADCSOC DMAReq ExtInput + DISABLE, DISABLE, DISABLE, TMR_ExtInput_Disable }; #endif #if USE_TMR2==1 static TMR_ExtInit_TypeDef tmr2_config = { -//Частота Clk МГц, Период обновления - SYSCLK_CORE_CLOCK_MHZ, PERIOD_MKS(1000000), -//Прерывания Запуск конверсии АЦП Реквест DMA Внешнее тактирование - ENABLE, DISABLE, DISABLE, TMR_ExtInput_Disable +//SystemCoreClock, Period Update + SYSCLK_CORE_CLOCK_MHZ, PERIOD_US(1000000), +//IT ADCSOC DMAReq ExtInput + DISABLE, DISABLE, DISABLE, TMR_ExtInput_Disable }; #endif #if USE_TMR3==1 static TMR_Init_TypeDef tmr3_config = { -//Частота Clk МГц, Период обновления - SYSCLK_CORE_CLOCK_MHZ, PERIOD_MKS(1000), -//Прерывания Запуск конверсии АЦП Реквест DMA Внешнее тактирование - DISABLE, DISABLE, DISABLE, TMR_ExtInput_Disable +//SystemCoreClock, Period Update + SYSCLK_CORE_CLOCK_MHZ, PERIOD_US(1000), +//IT ADCSOC DMAReq ExtInput + DISABLE, DISABLE, DISABLE, TMR_ExtInput_Disable }; #endif -//-- ADC SEQ Конфигурации ----------------------------------------------------- +//-- ADC Конфигурации ----------------------------------------------------- +/** @brief Источник тактирования АЦП */ static RCU_PeriphClk_TypeDef ADC_ClockSource = RCU_PeriphClk_PLLClk; +/** @brief Желаемая частота тактирования АЦП в МГц*/ static float ADC_ClockMHz = 12.5; +/** @brief Пины каких каналов инициализировать для АЦП */ +static ADC_ChannelEnableTypeDef adc_ch_config = { +//Channel 0, Channel 1, Channel 2, Channel 3 + ENABLE, ENABLE, ENABLE, ENABLE, +}; +//-- ADC SEQ Конфигурации ----------------------------------------------------- #if USE_ADC_SEQ0==1 static ADC_SEQ_ExtInit_TypeDef adc_seq0_config = { -//Событие запуска секвенсора, Разрешение программного запуска +//StartEvent, SWStartEn ADC_SEQ_StartEvent_SwReq, ENABLE, -//Выбор каналов для запросов секвенсора +//Req[0], Req[1], Req[2], Req[3] ADC_CH_Num_0, ADC_CH_Num_1, ADC_CH_Num_2, ADC_CH_Num_3, -//Последний запрос, Усреднение запросов, Усреднение запросов +//ReqMax, ReqAverage, ReqAverageEn ADC_SEQ_ReqNum_1, ADC_SEQ_Average_2, DISABLE, -//Кол-во рестартов секвенсора, Усреднение рестартов, Задержка между рестартами (в тиках ADC_ClockSource/2) - 0, DISABLE, 0, -//Разрешение каналов цифровых компараторов - DISABLE, DISABLE, DISABLE, DISABLE, -//Настройка DMA FIFO, Разрешение DMA +//RestartCount, RestartAverageEn, RestartTimer (в тиках ADC_ClockMHz) + 0, DISABLE, 0, +//DCEn[0], DCEn[1], DCEn[2], DCEn[3] + DISABLE, DISABLE, DISABLE, DISABLE, +//DMAFIFOLevel, DMAEn ADC_SEQ_DMAFIFOLevel_1, DISABLE, - //Прерывания, Кол-во рестартов для прерывания Циклический буфер - ENABLE, 0, ENABLE, -//SEQ Complete Коллбек, BuffHalf Коллбек, BuffFull Коллбек, Error коллбек - NULL, NULL, NULL, NULL, - + //IT, ITCount BufferCircular + ENABLE, 0, ENABLE, +//SEQCpltCallback, BuffHalfCallback, BuffFullCallback, ErrorCallback + NULL, NULL, NULL, NULL, }; #endif #if USE_ADC_SEQ1==1 static ADC_SEQ_ExtInit_TypeDef adc_seq1_config = { -//Событие запуска секвенсора, Разрешение программного запуска +//StartEvent, SWStartEn ADC_SEQ_StartEvent_SwReq, ENABLE, -//Выбор каналов для запросов секвенсора - ADC_CH_Num_2, ADC_CH_Num_3, ADC_CH_Num_2, ADC_CH_Num_3, -//Последний запрос, Усреднение запросов, Усреднение запросов +//Req[0], Req[1], Req[2], Req[3] + ADC_CH_Num_0, ADC_CH_Num_1, ADC_CH_Num_2, ADC_CH_Num_3, +//ReqMax, ReqAverage, ReqAverageEn ADC_SEQ_ReqNum_1, ADC_SEQ_Average_2, DISABLE, -//Кол-во рестартов секвенсора, Усреднение рестартов, Задержка между рестартами (в тиках ADC_ClockSource/2) - 0, DISABLE, 0, -//Разрешение каналов цифровых компараторов - DISABLE, DISABLE, DISABLE, DISABLE, -//Настройка DMA FIFO, Разрешение DMA +//RestartCount, RestartAverageEn, RestartTimer (в тиках ADC_ClockMHz) + 0, DISABLE, 0, +//DCEn[0], DCEn[1], DCEn[2], DCEn[3] + DISABLE, DISABLE, DISABLE, DISABLE, +//DMAFIFOLevel, DMAEn ADC_SEQ_DMAFIFOLevel_1, DISABLE, - //Прерывания, Кол-во рестартов для прерывания Циклический буфер - ENABLE, 0, ENABLE, -//SEQ Complete Коллбек, BuffHalf Коллбек, BuffFull Коллбек, Error коллбек - NULL, NULL, NULL, NULL, - + //IT, ITCount BufferCircular + ENABLE, 0, ENABLE, +//SEQCpltCallback, BuffHalfCallback, BuffFullCallback, ErrorCallback + NULL, NULL, NULL, NULL, }; #endif //-- ADC DC Конфигурации ------------------------------------------------------ #if USE_ADC_DC0==1 static ADC_DC_ExtInit_TypeDef adc_dc0_config = { -//Включение выхода компаратора +//DCOutput DISABLE, -//Нижний порог, Верхний порог +//ThresholdLow, ThresholdHigh 0, 0, -//Запуск измерения, Канал, Режим срабатывания, Условие срабатывания +//Source, Channel, Mode, Condition ADC_DC_Source_EOC, ADC_CH_Num_1, ADC_DC_Mode_Multiple, ADC_DC_Condition_Low, -//DC Triggered Коллбек, Error коллбек - NULL, NULL +//IT + DISABLE, +//DC_TrigCallback, ErrorCallback + NULL, NULL }; #endif #if USE_ADC_DC1==1 static ADC_DC_ExtInit_TypeDef adc_dc1_config = { -//Включение выхода компаратора +//DCOutput DISABLE, -//Нижний порог, Верхний порог +//ThresholdLow, ThresholdHigh 0, 0, -//Запуск измерения, Канал, Режим срабатывания, Условие срабатывания - ADC_DC_Source_EOC, ADC_CH_Num_2, ADC_DC_Mode_Multiple, ADC_DC_Condition_Low, -//DC Triggered Коллбек, Error коллбек - NULL, NULL +//Source, Channel, Mode, Condition + ADC_DC_Source_EOC, ADC_CH_Num_1, ADC_DC_Mode_Multiple, ADC_DC_Condition_Low, +//IT + DISABLE, +//DC_TrigCallback, ErrorCallback + NULL, NULL }; #endif #if USE_ADC_DC2==1 static ADC_DC_ExtInit_TypeDef adc_dc2_config = { -//Включение выхода компаратора +//DCOutput DISABLE, -//Нижний порог, Верхний порог +//ThresholdLow, ThresholdHigh 0, 0, -//Запуск измерения, Канал, Режим срабатывания, Условие срабатывания - ADC_DC_Source_EOC, ADC_CH_Num_3, ADC_DC_Mode_Multiple, ADC_DC_Condition_Low, -//DC Triggered Коллбек, Error коллбек - NULL, NULL +//Source, Channel, Mode, Condition + ADC_DC_Source_EOC, ADC_CH_Num_1, ADC_DC_Mode_Multiple, ADC_DC_Condition_Low, +//IT + DISABLE, +//DC_TrigCallback, ErrorCallback + NULL, NULL }; #endif #if USE_ADC_DC3==1 static ADC_DC_ExtInit_TypeDef adc_dc3_config = { -//Включение выхода компаратора +//DCOutput DISABLE, -//Нижний порог, Верхний порог +//ThresholdLow, ThresholdHigh 0, 0, -//Запуск измерения, Канал, Режим срабатывания, Условие срабатывания - ADC_DC_Source_EOC, ADC_CH_Num_4, ADC_DC_Mode_Multiple, ADC_DC_Condition_Low, -//DC Triggered Коллбек, Error коллбек - NULL, NULL +//Source, Channel, Mode, Condition + ADC_DC_Source_EOC, ADC_CH_Num_1, ADC_DC_Mode_Multiple, ADC_DC_Condition_Low, +//IT + DISABLE, +//DC_TrigCallback, ErrorCallback + NULL, NULL }; #endif diff --git a/Template.uvoptx b/Template.uvoptx index 990bf76..76b1e42 100644 --- a/Template.uvoptx +++ b/Template.uvoptx @@ -135,7 +135,7 @@ 0 JL2CM3 - -U -O14 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight JTAG-DP") -D00(4BA00477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0K1921VK035.FLM -FS00 -FL010000 -FP0($$Device:K1921VK035$Flash\K1921VK035.FLM) + -U-O14 -O14 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight JTAG-DP") -D00(4BA00477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0K1921VK035.FLM -FS00 -FL010000 -FP0($$Device:K1921VK035$Flash\K1921VK035.FLM) 0 @@ -158,6 +158,41 @@ 1 1 + huart1 + + + 2 + 1 + hadc + + + 3 + 1 + tickbuff + + + 4 + 1 + adc_seq1_config + + + 5 + 1 + ch3_config + + + 6 + 1 + starttick - htmr->Instance->VALUE,0x0A + + + 7 + 1 + gpiob_config + + + 8 + 1 seq0_buff @@ -203,6 +238,16 @@ + + + System Viewer\ADC + 35905 + + + System Viewer\GPIOB + 35904 + + diff --git a/Template.uvprojx b/Template.uvprojx index 4cdf21f..2fbcc92 100644 --- a/Template.uvprojx +++ b/Template.uvprojx @@ -314,7 +314,7 @@ 1 - 1 + 2 0 0 1