From ce169b9cb9ce8506808880ee0dca91da03858e2d Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 26 Jun 2026 15:24:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=8F=D0=B4=D1=80=D0=BE=20=D0=BF=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B2=D0=BA=D0=B8=20john103C6T6=5FF4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Core/Inc/Proj_setup.h | 13 + .../john103C6T6_JZ-F407VET6_F4/Core/Inc/adc.h | 52 ++ .../john103C6T6_JZ-F407VET6_F4/Core/Inc/can.h | 52 ++ .../Core/Inc/dallas_tools.h | 170 ++++ .../john103C6T6_JZ-F407VET6_F4/Core/Inc/def.h | 14 + .../john103C6T6_JZ-F407VET6_F4/Core/Inc/dma.h | 53 ++ .../Core/Inc/ds18b20_driver.h | 104 +++ .../Core/Inc/gpio.h | 49 ++ .../john103C6T6_JZ-F407VET6_F4/Core/Inc/i2c.h | 52 ++ .../Core/Inc/main.h | 150 ++++ .../Core/Inc/onewire.h | 77 ++ .../Core/Inc/ow_port.h | 60 ++ .../john103C6T6_JZ-F407VET6_F4/Core/Inc/rtc.h | 65 ++ .../john103C6T6_JZ-F407VET6_F4/Core/Inc/spi.h | 52 ++ .../Core/Inc/stm32f4xx_hal_conf.h | 605 ++++++++++++++ .../Core/Inc/stm32f4xx_it.h | 47 ++ .../john103C6T6_JZ-F407VET6_F4/Core/Inc/tim.h | 57 ++ .../Core/Inc/usart.h | 54 ++ .../Core/Src/UART_TERM.c | 129 +++ .../john103C6T6_JZ-F407VET6_F4/Core/Src/adc.c | 106 +++ .../john103C6T6_JZ-F407VET6_F4/Core/Src/can.c | 120 +++ .../Core/Src/dallas_tools.c | 646 +++++++++++++++ .../john103C6T6_JZ-F407VET6_F4/Core/Src/dma.c | 67 ++ .../Core/Src/ds18b20_driver.c | 607 ++++++++++++++ .../Core/Src/gpio.c | 105 +++ .../john103C6T6_JZ-F407VET6_F4/Core/Src/i2c.c | 117 +++ .../Core/Src/main.c | 763 ++++++++++++++++++ .../Core/Src/main.c.orig | 540 +++++++++++++ .../Core/Src/onewire.c | 379 +++++++++ .../Core/Src/ow_port.c | 122 +++ .../john103C6T6_JZ-F407VET6_F4/Core/Src/rtc.c | 333 ++++++++ .../john103C6T6_JZ-F407VET6_F4/Core/Src/spi.c | 124 +++ .../Core/Src/stm32f4xx_hal_msp.c | 86 ++ .../Core/Src/stm32f4xx_hal_timebase_tim.c | 177 ++++ .../Core/Src/stm32f4xx_it.c | 178 ++++ .../Core/Src/system_stm32f4xx.c | 747 +++++++++++++++++ .../john103C6T6_JZ-F407VET6_F4/Core/Src/tim.c | 262 ++++++ .../Core/Src/usart.c | 205 +++++ 38 files changed, 7539 insertions(+) create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/Proj_setup.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/adc.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/can.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dallas_tools.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/def.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dma.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ds18b20_driver.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/gpio.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/i2c.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/main.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/onewire.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ow_port.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/rtc.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/spi.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/stm32f4xx_hal_conf.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/stm32f4xx_it.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/tim.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/usart.h create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/UART_TERM.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/adc.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/can.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dallas_tools.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dma.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ds18b20_driver.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/gpio.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/i2c.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c.orig create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/onewire.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ow_port.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/rtc.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/spi.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_msp.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_timebase_tim.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_it.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/system_stm32f4xx.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/tim.c create mode 100644 john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/usart.c diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/Proj_setup.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/Proj_setup.h new file mode 100644 index 0000000..ed964fa --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/Proj_setup.h @@ -0,0 +1,13 @@ +#ifndef __PROJ_SETUP +#define __PROJ_SETUP + +//**********BEGIN defines*********** +//#define OldVer +#define MAX_SENSE 32 // НЕ ДЕЛАТЬ МЕНЬШЕ 16 + + + + +//**********END defines*********** + +#endif \ No newline at end of file diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/adc.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/adc.h new file mode 100644 index 0000000..a89c33e --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/adc.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 */ + +extern ADC_HandleTypeDef hadc1; + +/* 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__ */ + diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/can.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/can.h new file mode 100644 index 0000000..77729ee --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/can.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file can.h + * @brief This file contains all the function prototypes for + * the can.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 __CAN_H__ +#define __CAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern CAN_HandleTypeDef hcan; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_CAN_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CAN_H__ */ + diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dallas_tools.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dallas_tools.h new file mode 100644 index 0000000..ab6126d --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dallas_tools.h @@ -0,0 +1,170 @@ +/** +****************************************************************************** +* @file dallas_tools.h +* @brief Драйвер датчиков температуры DALLAS +****************************************************************************** +* Этот файл предоставляет объявления и определения для работы с датчиками +* температуры DS18B20. Он включает структуры данных, макросы и прототипы +* функций для инициализации, чтения температуры +* и управления датчиками. +* +* Работа с датчиками ведётся через протокол OneWire. +*****************************************************************************/ + +#ifndef DALLAS_TOOLS_H +#define DALLAS_TOOLS_H + +/* Includes -----------------------------------------------------------------*/ +#include "ds18b20_driver.h" +#include "onewire.h" + + +/* Определения пользовательских байтов для записи чтения */ +#define DALLAS_USER_BYTE_1 (1<<0) ///< Первый пользовательский байт +#define DALLAS_USER_BYTE_2 (1<<1) ///< Второй пользовательский байт +#define DALLAS_USER_BYTE_3 (1<<2) ///< Третий пользовательский байт +#define DALLAS_USER_BYTE_4 (1<<3) ///< Четвёртый пользовательский байт + +#define DALLAS_USER_BYTE_12 (DALLAS_USER_BYTE_1|DALLAS_USER_BYTE_2) ///< Первые два байта +#define DALLAS_USER_BYTE_34 (DALLAS_USER_BYTE_3|DALLAS_USER_BYTE_4) ///< Вторые два байта +#define DALLAS_USER_BYTE_ALL (DALLAS_USER_BYTE_12|DALLAS_USER_BYTE_34) ///< Все пользовательские байты + +/* Declarations and definitions ---------------------------------------------*/ +#define DALLAS_ROM_SIZE 8 + +#define DALLAS_CONFIG_9_BITS 0x1F +#define DALLAS_CONFIG_10_BITS 0x3F +#define DALLAS_CONFIG_11_BITS 0x5F +#define DALLAS_CONFIG_12_BITS 0x7F + +#define DALLAS_DELAY_MS_9_BITS 94 +#define DALLAS_DELAY_MS_10_BITS 188 +#define DALLAS_DELAY_MS_11_BITS 375 +#define DALLAS_DELAY_MS_12_BITS 750 +#define DALLAS_DELAY_MS_MAX DALLAS_DELAY_MS_12_BITS + +typedef struct _SensorHandleStruct DALLAS_SensorHandleTypeDef; +typedef struct _DallasHandleStruct DALLAS_HandleTypeDef; + +/** @brief Структура Scratchpad датчика DALLAS */ +typedef struct +{ + uint8_t TemperatureLSB; ///< Младший байт температуры + uint8_t TemperatureMSB; ///< Старший байт температуры + uint8_t tHighRegister; ///< Верхний температурный порог + uint8_t tLowRegister; ///< Нижний температурный порог + uint8_t ConfigRegister; ///< Конфигурационный регистр + uint8_t reserved; ///< Зарезервировано + uint8_t UserByte3; ///< Пользовательский байт 3 + uint8_t UserByte4; ///< Пользовательский байт 4 + uint8_t ScratchpadCRC; ///< Контрольная сумма +}DALLAS_ScratchpadTypeDef; + +/** @brief Структура флагов ошибок датчиков DALLAS */ +typedef struct +{ + uint8_t disconnect_cnt; ///< Счетчик отключений датчика + uint8_t read_temperature_err_cnt; ///< Счетчик ошибок чтения температуры + uint8_t timeout_convertion_cnt; ///< Счетчик ошибок таймаута конвертации + uint8_t write_err_cnt; ///< Счетчик других ошибок +}DALLAS_FlagsTypeDef; + + +/** @brief Структура инициализации датчика DALLAS */ +typedef struct __packed +{ + union + { + uint64_t Ind; ///< порядковый номер датчика + uint64_t ROM; ///< ROM датчика + struct + { + uint8_t UserByte1; ///< Младший байт (бит 0–7) + uint8_t UserByte2; ///< Следующий байт (бит 8–15) + uint8_t UserByte3; ///< Байт (бит 16–23) + uint8_t UserByte4; ///< Байт (бит 24–31) + uint8_t Reserved[4]; ///< Остальные байты (бит 32–63, если нужно) + } UserBytes; ///< UserBytes датчика + }InitParam; ///< Параметр для инициализации: ROM/UserBytes/Индекс + uint8_t Resolution; ///< Разрешение датчика + HAL_StatusTypeDef (*init_func)(DALLAS_HandleTypeDef *, DALLAS_SensorHandleTypeDef *); ///< Функция инициализации +} DALLAS_InitStructTypeDef; + + + +/** @brief Cтруктура обработчика DALLAS для общения с датчиком*/ +struct _DallasHandleStruct +{ + OneWire_t *onewire; + DS18B20_Drv_t *ds_devices; + DALLAS_ScratchpadTypeDef scratchpad; +}; +extern DALLAS_HandleTypeDef hdallas; + +/** @brief Основная структура обработчика датчика DALLAS */ +struct _SensorHandleStruct +{ + unsigned isConnected:1; ///< Флаг соединения + unsigned isInitialized:1; ///< Флаг инициализации + unsigned isLost:1; ///< Флаг потери связи + uint16_t lost_cnt; + DALLAS_FlagsTypeDef f; ///< Флаги + + + float set_temp; + uint16_t hyst; + + DALLAS_HandleTypeDef *hdallas; + uint64_t sensROM; ///< ROM-код датчика + + float temperature; ///< Текущая температура + + DALLAS_InitStructTypeDef Init; ///< Структура инициализации + + +}; + + + +/** @brief Варианты ожидания окончания конверсии */ +typedef enum +{ + DALLAS_WAIT_NONE = 0x00, ///< Без ожидания окончания конверсии + DALLAS_WAIT_BUS = 0x01, ///< Ожидание окончания конверсии по шине (опрос датчиков - чтение бита) + DALLAS_WAIT_DELAY = 0x02, ///< Без ожидания окончания через задержку (максимальная задержка для заданной разрядности) +} DALLAS_WaitConvertionTypeDef; + + + +/* Functions ---------------------------------------------------------------*/ + +HAL_StatusTypeDef Dallas_BusFirstInit(TIM_HandleTypeDef *htim); +/* Функция для иниицализации нового датчика в структуре */ +HAL_StatusTypeDef Dallas_AddNewSensors(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor); +/* Инициализирует структуру датчика по ROM */ +HAL_StatusTypeDef Dallas_SensorInitByROM(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor); +/* Инициализирует структуру датчика по пользовательским байтам */ +HAL_StatusTypeDef Dallas_SensorInitByUserBytes(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor); +/* Инициализирует структуру датчика по порядковому номеру */ +HAL_StatusTypeDef Dallas_SensorInitByInd(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor); +/* Инициализирует датчик для работы */ +HAL_StatusTypeDef Dallas_SensorInit(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor, uint8_t (*ROM)[DALLAS_ROM_SIZE]); +/* Деинициализирует структуру датчика */ +HAL_StatusTypeDef Dallas_SensorDeInit(DALLAS_SensorHandleTypeDef *sensor); +/* Функция для нахождения нового датчика на место потерянного */ +HAL_StatusTypeDef Dallas_ReplaceLostedSensor(DALLAS_SensorHandleTypeDef *sensor); +/* Запускает измерение температуры на всех датчиках */ +HAL_StatusTypeDef Dallas_StartConvertTAll(DALLAS_HandleTypeDef *hdallas, DALLAS_WaitConvertionTypeDef waitCondition, uint8_t dallas_delay_ms); +/* Измеряет температуру на датчике */ +HAL_StatusTypeDef Dallas_ConvertT(DALLAS_SensorHandleTypeDef *sensor, DALLAS_WaitConvertionTypeDef waitCondition); +/* Читает измеренную датчиком температуру */ +HAL_StatusTypeDef Dallas_ReadTemperature(DALLAS_SensorHandleTypeDef *sensor); +/* Проверяет подключен ли датчик (чтение scratchpad) */ +HAL_StatusTypeDef Dallas_IsConnected(DALLAS_SensorHandleTypeDef *sensor); +/* Записывает пользовательские байты */ +HAL_StatusTypeDef Dallas_WriteUserBytes(DALLAS_SensorHandleTypeDef *sensor, uint16_t UserBytes12, uint16_t UserBytes34, uint8_t UserBytesMask); +/* Записывает пользовательские байты */ +HAL_StatusTypeDef Dallas_ReadScratchpad(DALLAS_SensorHandleTypeDef *sensor); + + +#endif // #ifndef DALLAS_TOOLS_H \ No newline at end of file diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/def.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/def.h new file mode 100644 index 0000000..6570fb8 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/def.h @@ -0,0 +1,14 @@ +#ifndef __DEF_H +#define __DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_DEVICES 10 + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ \ No newline at end of file diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dma.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dma.h new file mode 100644 index 0000000..aa7f6a2 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/dma.h @@ -0,0 +1,53 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.h + * @brief This file contains all the function prototypes for + * the dma.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 -------------------------------------*/ +extern DMA_HandleTypeDef hdma_memtomem_dma1_channel1; + +/* 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__ */ + diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ds18b20_driver.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ds18b20_driver.h new file mode 100644 index 0000000..3a30f9f --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ds18b20_driver.h @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file ds18b20_driver.h + * @brief This file contains all the constants parameters for the DS18B20 + * 1-Wire Digital Thermometer + ****************************************************************************** + * @attention + * Usage: + * Uncomment LL Driver for HAL driver + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef DS18B20_H +#define DS18B20_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "onewire.h" +#include "PROJ_setup.h" + + + +/* Data Structure ------------------------------------------------------------*/ +#define DS18B20_DEVICE_AMOUNT MAX_SENSE + +/* Register ------------------------------------------------------------------*/ +#define DS18B20_CMD_CONVERT 0x44 +#define DS18B20_CMD_ALARM_SEARCH 0xEC +#define DS18B20_CMD_READSCRATCHPAD 0xBE +#define DS18B20_CMD_WRITESCRATCHPAD 0x4E +#define DS18B20_CMD_COPYSCRATCHPAD 0x48 +/* Data Structure ------------------------------------------------------------*/ +#define DS18B20_FAMILY_CODE 0x28 + + +#define DS18B20_SERIAL_NUMBER_LEN_BYTES 6 +#define DS18B20_SERIAL_NUMBER_OFFSET_BYTES 1 + +#define DS18B20_SCRATCHPAD_T_LSB_BYTE_IDX 0 +#define DS18B20_SCRATCHPAD_T_MSB_BYTE_IDX 1 +#define DS18B20_SCRATCHPAD_T_LIMIT_H_BYTE_IDX 2 +#define DS18B20_SCRATCHPAD_T_LIMIT_L_BYTE_IDX 3 +#define DS18B20_SCRATCHPAD_CONFIG_BYTE_IDX 4 +#define DS18B20_SCRATCHPAD_USER_BYTE_3_IDX 6 +#define DS18B20_SCRATCHPAD_USER_BYTE_4_IDX 7 +#define DS18B20_SCRATCHPAD_CRC_IDX 8 + +/* Bits locations for resolution */ +#define DS18B20_RESOLUTION_R1 6 +#define DS18B20_RESOLUTION_R0 5 + +#define DS18B20_DECIMAL_STEP_12BIT 0.0625 +#define DS18B20_DECIMAL_STEP_11BIT 0.125 +#define DS18B20_DECIMAL_STEP_10BIT 0.25 +#define DS18B20_DECIMAL_STEP_9BIT 0.5 + +#define DS18B20_DELAY_MS_9_BITS 94 +#define DS18B20_DELAY_MS_10_BITS 188 +#define DS18B20_DELAY_MS_11_BITS 375 +#define DS18B20_DELAY_MS_12_BITS 750 +#define DS18B20_DELAY_MS_MAX DS18B20_DELAY_MS_12_BITS + + +/* DS18B20 Resolutions */ +typedef enum { + DS18B20_RESOLUTION_9BITS = 0x1F, + DS18B20_RESOLUTION_10BITS = 0x3F, + DS18B20_RESOLUTION_11BITS = 0x5F, + DS18B20_RESOLUTION_12BITS = 0x7F +} DS18B20_Res_t; + +typedef struct +{ + uint8_t DevAddr[DS18B20_DEVICE_AMOUNT][8]; +} DS18B20_Drv_t; +extern DS18B20_Drv_t DS; +extern OneWire_t OW; + +/* External Function ---------------------------------------------------------*/ +HAL_StatusTypeDef DS18B20_Search(DS18B20_Drv_t *DS, OneWire_t *OW); +HAL_StatusTypeDef DS18B20_StartConvT(OneWire_t* OW, uint8_t *ROM); +HAL_StatusTypeDef DS18B20_StartConvTAll(OneWire_t* OW); +HAL_StatusTypeDef DS18B20_CalcTemperature(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad, float *destination); +HAL_StatusTypeDef DS18B20_ReadScratchpad(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad); +HAL_StatusTypeDef DS18B20_WaitForEndConvertion(OneWire_t* OW); +HAL_StatusTypeDef DS18B20_WaitForEndConvertion_NonBlocking(OneWire_t* OW); +HAL_StatusTypeDef DS18B20_SetTempAlarm(OneWire_t* OW, uint8_t *ROM, int8_t Low, + int8_t High); +HAL_StatusTypeDef DS18B20_WriteUserBytes(OneWire_t* OW, uint8_t *ROM, int16_t UserBytes12, + int16_t UserBytes34, uint8_t UserBytesMask); +uint8_t DS18B20_AlarmSearch(DS18B20_Drv_t *DS, OneWire_t* OW); + +HAL_StatusTypeDef DS18B20_SetResolution(OneWire_t* OW, uint8_t *ROM, + DS18B20_Res_t Resolution); +HAL_StatusTypeDef DS18B20_IsValidAddress(uint8_t *ROM); +#ifdef __cplusplus +} +#endif + +#endif /* DS18B20_H */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/gpio.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/gpio.h new file mode 100644 index 0000000..9ac4857 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/gpio.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 __GPIO_H__ +#define __GPIO_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_GPIO_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif +#endif /*__ GPIO_H__ */ + diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/i2c.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/i2c.h new file mode 100644 index 0000000..e5f10f5 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/i2c.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.h + * @brief This file contains all the function prototypes for + * the i2c.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __I2C_H__ +#define __I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern I2C_HandleTypeDef hi2c1; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_I2C1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __I2C_H__ */ + diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/main.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/main.h new file mode 100644 index 0000000..6788d40 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/main.h @@ -0,0 +1,150 @@ +/* USER CODE BEGIN Header */ +/** +*************************************************************** +* 1 2 3 4 5 6 7 8 * +* --- +++ * +* * +***************************************************************** + + + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "Proj_setup.h" +#include "dallas_tools.h" +#include "modbus.h" + +typedef enum +{ + FuncOK=0, + FuncERROR=1 + +}FuncStat; + + +typedef enum { + CONFIG_DEVICE_ID = 0, + CONFIG_BAUDRATE, + CONFIG_CALIBRATION, + CONFIG_SETTINGS +} ConfigParams; + + + +typedef enum { + STATE_OPEN_VALVE = 0, // open + STATE_CLOSE_VALVE= 1 // close +} ValveState; +typedef struct +{ + uint32_t id[2]; + float temp; + uint16_t location; + uint8_t t_open; + float t_set; + uint8_t t_close; + uint8_t status_T_sense:1 ; + ValveState state; + uint16_t count; +}TEMP_TypeDef; +typedef struct { + uint32_t init_tsens : 1; // Update Interrupt Flag (бит 0) — флаг переполнения/обновления + + // ... (другие биты могут быть зарезервированы или использоваться в расширенных таймерах) +} Flags_TypeDef; + + + + + + + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ +#define reset_blink_delay 50 +#define rest_iter 10 +#define GPIOB11_valve MB_DATA.Coils.coils[0].state_val_bit.state_val_01 +#define ralay_5v_on GPIOA->ODR&(1<<10); + + + +extern void handle_command(char* cmd); +typedef void (*FunctionPointer)(void); + +uint16_t handle_valves(TEMP_TypeDef* temp_sense[MAX_SENSE]); +void init_setpoint_all_T_sense(TEMP_TypeDef* temp_sense, int size_array); +void iwdg_refresh(void); +void led_blink(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,uint8_t iter,uint16_t delay); +FuncStat Field_modbus(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag); +FuncStat packStruct(MB_DataStructureTypeDef* MB_DATA,int sizeARR); +void Check_Tconnect(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag ,DALLAS_HandleTypeDef* hdallas, int a[50]); +FuncStat value_control(void ); + +void reinit_t_sens(void); +HAL_StatusTypeDef ModbusMaster_Request(RS_MsgTypeDef *request, + void (*callback)(RS_HandleTypeDef *, RS_MsgTypeDef *)); + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define Relay_dc5v_Pin GPIO_PIN_10 +#define Relay_dc5v_GPIO_Port GPIOA +#define One_wire_Pin GPIO_PIN_15 +#define One_wire_GPIO_Port GPIOA + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/onewire.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/onewire.h new file mode 100644 index 0000000..5fb2935 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/onewire.h @@ -0,0 +1,77 @@ +/** +****************************************************************************** +* @file onewire.h +* @brief This file contains all the constants parameters for the OneWire +****************************************************************************** +*/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef ONEWIRE_H +#define ONEWIRE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ow_port.h" + +/* Driver Selection ----------------------------------------------------------*/ +//#define LL_Driver +//#define CMSIS_Driver +/* OneWire Timings -----------------------------------------------------------*/ +#define ONEWIRE_RESET_PULSE_US 480 // Длительность импульса сброса +#define ONEWIRE_PRESENCE_WAIT_US 70 // Ожидание ответа от датчика +#define ONEWIRE_PRESENCE_DURATION_US 410 // Длительность сигнала присутствия + +#define ONEWIRE_WRITE_1_US 8 // Длительность записи "1" +#define ONEWIRE_WRITE_0_US 57 // Длительность записи "0" +#define ONEWIRE_READ_CMD_US 2 // Время комманды чтения бита +#define ONEWIRE_READ_DELAY_US 6 // Задержка перед считыванием бита +#define ONEWIRE_COMMAND_SLOT_US 58 // Общее время комманды OneWire +#define ONEWIRE_RECOVERY_TIME_US 1 // Восстановление перед следующим слотом +/* Common Register -----------------------------------------------------------*/ +#define ONEWIRE_CMD_SEARCHROM 0xF0 +#define ONEWIRE_CMD_READROM 0x33 +#define ONEWIRE_CMD_MATCHROM 0x55 +#define ONEWIRE_CMD_SKIPROM 0xCC + +/* Data Structure ------------------------------------------------------------*/ +typedef enum +{ + Input, + Output +} PinMode; + +typedef struct +{ + uint8_t LastDiscrepancy; + uint8_t LastFamilyDiscrepancy; + uint8_t LastDeviceFlag; + uint8_t RomByte[8]; + uint8_t RomCnt; + uint16_t DataPin; + GPIO_TypeDef *DataPort; +} OneWire_t; + +/* External Function ---------------------------------------------------------*/ +void OneWire_Init(OneWire_t* OW); +uint8_t OneWire_Search(OneWire_t* OW, uint8_t Cmd); +void OneWire_GetDevRom(OneWire_t* OW, uint8_t *dev); +uint8_t OneWire_Reset(OneWire_t* OW); +uint8_t OneWire_ReadBit(OneWire_t* OW); +uint8_t OneWire_ReadByte(OneWire_t* OW); +void OneWire_WriteByte(OneWire_t* OW, uint8_t byte); +void OneWire_MatchROM(OneWire_t* OW, uint8_t *Rom); +void OneWire_Skip(OneWire_t* OW); +uint8_t OneWire_CRC8(uint8_t *addr, uint8_t len); + +void OneWire_Pin_Mode(OneWire_t* OW, PinMode Mode); +void OneWire_Pin_Level(OneWire_t* OW, uint8_t Level); +uint8_t OneWire_Pin_Read(OneWire_t* OW); +void OneWire_WriteBit(OneWire_t* OW, uint8_t bit); + +#ifdef __cplusplus +} +#endif + +#endif /* ONEWIRE_H */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ow_port.h b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ow_port.h new file mode 100644 index 0000000..89129fc --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Inc/ow_port.h @@ -0,0 +1,60 @@ +/** +****************************************************************************** +* @file ow_port.h +* @brief This file includes the driver for port for OneWire purposes +****************************************************************************** +*/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef ONEWIRE_PORT_H +#define ONEWIRE_PORT_H + + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/* I/O Port ------------------------------------------------------------------*/ +//#define LL_Driver ///< использовать CMSIS для управления ножкой +#define CMSIS_Driver ///< использовать CMSIS для управления ножкой +// если ничего не выбрано - используется HAL + + +/** + * @def OW_GPIO_Port + * @brief Порт вывода для шины 1-Wire. + * @details Указывает порт GPIO, к которому подключена линия данных 1-Wire (например, для DS18B20). + */ +#define OW_GPIO_Port GPIOA + +/** + * @def OW_Pin_Numb + * @brief Номер пина в порту OW_GPIO_Port. + * @details Используется для формирования маски пина и настройки ввода/вывода. + */ +#define OW_Pin_Numb 15 + +/** + * @def OW_Pin + * @brief Маска пина, соответствующая номеру OW_Pin_Numb. + * @details Используется при доступе к регистрам порта для управления состоянием линии 1-Wire. + */ +#define OW_Pin (1< +#include +#include + +#include "main.h" +#include "def.h" +//extern uint8_t devices_found ; +extern uint8_t roms[MAX_DEVICES][8]; +extern char rx_buffer[64]; +extern TEMP_TypeDef temp_sense[30]; +extern uint8_t init; +int test_var=0; +//void handle_command(char* cmd) +// +//{ +// if (strncmp(cmd, "list", 4) == 0) +// { +// printf("find %d devices:\r\n", devices_found); +// for (int i = 0; i < devices_found; i++) +// { +// printf("Device #%d: ", i); +// for (int j = 0; j < 8; j++) +// printf("%02X ", roms[i][j]); +// printf("\r\n"); +// } +// } +// else if (strncmp(cmd, "temp all", 8) == 0) +// { +// for (int i = 0; i < devices_found; i++) +// { +// ds_reset(); +// ds_write_byte(0x55); +// for (int j = 0; j < 8; j++) +// ds_write_byte(roms[i][j]); +// ds_write_byte(0x44); +// } + +// HAL_Delay(750); + +// for (int i = 0; i < devices_found; i++) +// { +// ds_reset(); +// ds_write_byte(0x55); +// for (int j = 0; j < 8; j++) +// ds_write_byte(roms[i][j]); +// ds_write_byte(0xBE); +// uint8_t tl = ds_read_byte(); +// uint8_t th = ds_read_byte(); +// int16_t t = (th << 8) | tl; +// float temp = t / 16.0; +// printf("T[%d] = %.2f C\r\n", i, temp); +// } +// } +// else if (strncmp(cmd, "temp ", 5) == 0) +// { +// int id = atoi(&cmd[5]); +// if (id < 0 || id >= devices_found) +// { +// printf("unknown ID\r\n"); +// return; +// } + +// ds_reset(); +// ds_write_byte(0x55); +// for (int j = 0; j < 8; j++) +// ds_write_byte(roms[id][j]); +// ds_write_byte(0x44); +// HAL_Delay(750); + +// ds_reset(); +// ds_write_byte(0x55); +// for (int j = 0; j < 8; j++) +// ds_write_byte(roms[id][j]); +// ds_write_byte(0xBE); +// uint8_t tl = ds_read_byte(); +// uint8_t th = ds_read_byte(); +// int16_t t = (th << 8) | tl; +// float temp = t / 16.0; +// printf("T[%d] = %.2f C\r\n", id, temp); +// } +// else if (strncmp(cmd, "ts_1_open_minus",15 ) == 0) +// { +// temp_sense[0].t_open-=1; +// +// } +// else if (strncmp(cmd, "ts_1_open_plus",14 ) == 0) +// { +// temp_sense[0].t_open+=1; +// +// } +// else if (strncmp(cmd, "ts_1_close_minus",16 ) == 0) +// { +// temp_sense[0].t_close-=1; +// +// } +// else if (strncmp(cmd, "ts_1_close_plus",15 ) == 0) +// { +// +// temp_sense[0].t_close+=1; +// } +// else if (strncmp(cmd, "init",4 ) == 0) +// { +// init=1; +// printf("init %s\r\n", "OK"); +// } +// else if +// (strncmp(cmd, "set_temp ", 9) == 0) +// { +// uint8_t sense_num = (atoi(&cmd[9])&0x7c0)>>10; +// int parse_uart=atoi(&cmd[10]); +// +// temp_sense[sense_num].t_set=(float)parse_uart/10.; +// printf("temp_sense %i %s\r\n",sense_num, "OK"); +// +// +// } +// else if (strncmp(cmd, "temp ", 5) == 0) +// { +// +// +// } +// else +// { +// printf("unknown CMD: %s\r\n", cmd); +// for (int i=0;i<63;i++) +// rx_buffer[i]=0; +// +// } +//} \ No newline at end of file diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/adc.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/adc.c new file mode 100644 index 0000000..6b65f32 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/adc.c @@ -0,0 +1,106 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 */ + +ADC_HandleTypeDef hadc1; + +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Common config + */ + hadc1.Instance = ADC1; + hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; + hadc1.Init.ContinuousConvMode = ENABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Regular Channel + */ + sConfig.Channel = ADC_CHANNEL_VREFINT; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} + +void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) +{ + + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + /* ADC1 clock enable */ + __HAL_RCC_ADC1_CLK_ENABLE(); + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } +} + +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) +{ + + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC1_CLK_DISABLE(); + /* USER CODE BEGIN ADC1_MspDeInit 1 */ + + /* USER CODE END ADC1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/can.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/can.c new file mode 100644 index 0000000..8b7c344 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/can.c @@ -0,0 +1,120 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file can.c + * @brief This file provides code for the configuration + * of the CAN instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "can.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +CAN_HandleTypeDef hcan; + +/* CAN init function */ +void MX_CAN_Init(void) +{ + + /* USER CODE BEGIN CAN_Init 0 */ + + /* USER CODE END CAN_Init 0 */ + + /* USER CODE BEGIN CAN_Init 1 */ + + /* USER CODE END CAN_Init 1 */ + hcan.Instance = CAN1; + hcan.Init.Prescaler = 16; + hcan.Init.Mode = CAN_MODE_NORMAL; + hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan.Init.TimeSeg1 = CAN_BS1_1TQ; + hcan.Init.TimeSeg2 = CAN_BS2_1TQ; + hcan.Init.TimeTriggeredMode = DISABLE; + hcan.Init.AutoBusOff = DISABLE; + hcan.Init.AutoWakeUp = DISABLE; + hcan.Init.AutoRetransmission = DISABLE; + hcan.Init.ReceiveFifoLocked = DISABLE; + hcan.Init.TransmitFifoPriority = DISABLE; + if (HAL_CAN_Init(&hcan) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN CAN_Init 2 */ + + /* USER CODE END CAN_Init 2 */ + +} + +void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(canHandle->Instance==CAN1) + { + /* USER CODE BEGIN CAN1_MspInit 0 */ + + /* USER CODE END CAN1_MspInit 0 */ + /* CAN1 clock enable */ + __HAL_RCC_CAN1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**CAN GPIO Configuration + PA11 ------> CAN_RX + PA12 ------> CAN_TX + */ + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN CAN1_MspInit 1 */ + + /* USER CODE END CAN1_MspInit 1 */ + } +} + +void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle) +{ + + if(canHandle->Instance==CAN1) + { + /* USER CODE BEGIN CAN1_MspDeInit 0 */ + + /* USER CODE END CAN1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CAN1_CLK_DISABLE(); + + /**CAN GPIO Configuration + PA11 ------> CAN_RX + PA12 ------> CAN_TX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); + + /* USER CODE BEGIN CAN1_MspDeInit 1 */ + + /* USER CODE END CAN1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dallas_tools.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dallas_tools.c new file mode 100644 index 0000000..cfe20ff --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dallas_tools.c @@ -0,0 +1,646 @@ +/** +****************************************************************************** +* @file dallas_tools.c +* @brief Драйвер для работы с датчиками температуры DS18B20 +****************************************************************************** +@details +Библиотека предназначена для работы с цифровыми датчиками температуры DS18B20 +по однопроводному интерфейсу 1-Wire. Реализована поддержка инициализации, поиска, +добавления и работы с несколькими датчиками. + +@verbatim +============================================================================== + ## Основные задачи библиотеки ## +============================================================================== +Эта библиотека предоставляет следующие основные функции: + (+) Инициализация шины 1-Wire и обнаружение подключённых датчиков + (+) Инициализация структуры датчика по: + - ROM-адресу + - пользовательским байтам (TH, TL, UserByte3, UserByte4) + - порядковому номеру в списке найденных устройств + (+) Конфигурация разрешения измерения + (+) Чтение температуры + (+) Замена «потерянного» датчика + (+) Деинициализация структуры датчика + +============================================================================== + ## Быстрый старт ## +============================================================================== +Пример последовательности инициализации и использования: + + 1. Определение пина и таймера для OneWire в ow_port.h: + #define OW_GPIO_Port GPIOB + #define OW_Pin_Numb 0 + #define OW_Pin (1<hdallas = hdallas; + + result = sensor->Init.init_func(hdallas, sensor); + + return result; +} + + + + +/** + * @brief Функция для нахождения нового датчика на место потерянного + * @param sensor Указатель на структуру датчика + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_ReplaceLostedSensor(DALLAS_SensorHandleTypeDef *sensor) +{ + HAL_StatusTypeDef result; + + + if(sensor == NULL) + return HAL_ERROR; + + result = Dallas_IsConnected(sensor); + + if(sensor->isLost) + { + if(DS18B20_Search(sensor->hdallas->ds_devices, sensor->hdallas->onewire) != HAL_OK) + return HAL_ERROR; + + if(sensor->Init.init_func(sensor->hdallas, sensor) != HAL_OK) + return HAL_ERROR; + + return HAL_OK; + } + else + { + return HAL_BUSY; // датчик не потерян + } +} + + +/** + * @brief Запускает измерение температуры на всех датчиках + * @param hdallas Указатель на хендл для общения с датчиками + * @param waitCondition Условие ожидания завершения преобразования + * @param dallas_delay_ms Время ожидания окончания конверсии + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_StartConvertTAll(DALLAS_HandleTypeDef *hdallas, DALLAS_WaitConvertionTypeDef waitCondition, uint8_t dallas_delay_ms) +{ + HAL_StatusTypeDef result; + uint8_t rxDummyData; + + if(hdallas == NULL) + return HAL_ERROR; + + // Отправка команды начала преобразования температуры + result = DS18B20_StartConvTAll(hdallas->onewire); + if(result != HAL_OK) + { + return result; + } +// // Проверка что преобразование началось +// if(OneWire_ReadBit(onewire) == 1) +// return HAL_ERROR; + + // Ожидание завершения преобразования, путем проверки шины + if (waitCondition == DALLAS_WAIT_BUS) + { + result = DS18B20_WaitForEndConvertion(hdallas->onewire); + return result; + } + + // Ожидание завершения преобразования, путем задержки + if (waitCondition == DALLAS_WAIT_DELAY) + { + uint32_t delayValueMs = 0; + + switch (dallas_delay_ms) + { + case DALLAS_CONFIG_9_BITS: + delayValueMs = DALLAS_DELAY_MS_9_BITS; + break; + + case DALLAS_CONFIG_10_BITS: + delayValueMs = DALLAS_DELAY_MS_10_BITS; + break; + + case DALLAS_CONFIG_11_BITS: + delayValueMs = DALLAS_DELAY_MS_11_BITS; + break; + + case DALLAS_CONFIG_12_BITS: + delayValueMs = DALLAS_DELAY_MS_12_BITS; + break; + + default: + break; + } + + HAL_Delay(delayValueMs); + } + + return result; +} + +/** + * @brief Измеряет температуру на датчике + * @param sensor Указатель на структуру датчика + * @param waitCondition Условие ожидания завершения преобразования + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_ConvertT(DALLAS_SensorHandleTypeDef *sensor, DALLAS_WaitConvertionTypeDef waitCondition) +{ + HAL_StatusTypeDef result; + uint8_t rxDummyData; + + if(sensor == NULL) + return HAL_ERROR; + if(sensor->isInitialized == 0) + return HAL_ERROR; + + /* Проверка присутствует ли выбранный датчик на линии */ + result = Dallas_IsConnected(sensor); + if (result != HAL_OK) + return result; + + // Отправка команды начала преобразования температуры + result = DS18B20_StartConvT(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM); + if(result != HAL_OK) + { + return result; + } + + // Ожидание завершения преобразования, путем проверки шины + if (waitCondition == DALLAS_WAIT_BUS) + { + result = DS18B20_WaitForEndConvertion(sensor->hdallas->onewire); + if(result == HAL_TIMEOUT) + { + sensor->f.timeout_convertion_cnt++; + } + return result; + } + + // Ожидание завершения преобразования, путем задержки + if (waitCondition == DALLAS_WAIT_DELAY) + { + uint32_t delayValueMs = 0; + + switch (sensor->hdallas->scratchpad.ConfigRegister) + { + case DALLAS_CONFIG_9_BITS: + delayValueMs = DALLAS_DELAY_MS_9_BITS; + break; + + case DALLAS_CONFIG_10_BITS: + delayValueMs = DALLAS_DELAY_MS_10_BITS; + break; + + case DALLAS_CONFIG_11_BITS: + delayValueMs = DALLAS_DELAY_MS_11_BITS; + break; + + case DALLAS_CONFIG_12_BITS: + delayValueMs = DALLAS_DELAY_MS_12_BITS; + break; + + default: + break; + } + + HAL_Delay(delayValueMs); + } + + /* Не считываем температуру, если не выбрано ожидание окончания преобразования */ + if(waitCondition != DALLAS_WAIT_NONE) + { + result = Dallas_ReadTemperature(sensor); + } + + return result; +} + + +/** + * @brief Читает измеренную датчиком температуру + * @param sensor Указатель на структуру датчика + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_ReadTemperature(DALLAS_SensorHandleTypeDef *sensor) +{ + HAL_StatusTypeDef result; + + if(sensor == NULL) + return HAL_ERROR; + if(sensor->isInitialized == 0) + return HAL_ERROR; + + /* Проверка присутствует ли выбранный датчик на линии */ + result = Dallas_IsConnected(sensor); + if (result != HAL_OK) + { + return result; + } + + + result = DS18B20_CalcTemperature(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM, (uint8_t *)&sensor->hdallas->scratchpad, &sensor->temperature); + + if (result != HAL_OK) + { + sensor->f.read_temperature_err_cnt++; + return result; + } + + return HAL_OK; +} + +/** + * @brief Проверяет подключен ли датчик (чтение scratchpad) + * @param sensor Указатель на структуру датчика + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_IsConnected(DALLAS_SensorHandleTypeDef *sensor) +{ + HAL_StatusTypeDef result; + if(sensor == NULL) + return HAL_ERROR; + + result = Dallas_ReadScratchpad(sensor); + + if (result == HAL_OK) + { + sensor->isConnected = 1; + sensor->isLost = 0; + return HAL_OK; + } + else + { + sensor->temperature = 0; + if(sensor->isConnected == 1) + { + sensor->f.disconnect_cnt++; + } + sensor->isLost = 1; + sensor->isConnected = 0; + +// Dallas_ReplaceLostedSensor(sensor); + return HAL_BUSY; // использую busy, чтобы отличать ситуацию от HAL_ERROR + } +} + +/** + * @brief Записывает пользовательские байты + * @param sensor Указатель на структуру датчика + * @param UserBytes12 Пользовательские байты 1 и 2 + * @param UserBytes34 Пользовательские байты 3 и 4 + * @param UserBytesMask Маска, какие байты записывать, а какие нет + * @retval HAL Status + * @details старший байт - UserByte4/UserByte2, младший - UserByte3/UserByte1. + */ +HAL_StatusTypeDef Dallas_WriteUserBytes(DALLAS_SensorHandleTypeDef *sensor, uint16_t UserBytes12, uint16_t UserBytes34, uint8_t UserBytesMask) +{ + HAL_StatusTypeDef result; + if(sensor == NULL) + return HAL_ERROR; + + if(sensor->isInitialized == 0) + return HAL_ERROR; + + /* Проверка присутствует ли выбранный датчик на линии */ + result = Dallas_IsConnected(sensor); + if (result != HAL_OK) + return result; + + result = DS18B20_WriteUserBytes(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM, UserBytes12, UserBytes34, UserBytesMask); + if (result != HAL_OK) + { + sensor->f.write_err_cnt++; + return result; + } + result = Dallas_ReadScratchpad(sensor); + if (result != HAL_OK) + { + return result; + } + + return result; +} + + +HAL_StatusTypeDef Dallas_ReadScratchpad(DALLAS_SensorHandleTypeDef *sensor) +{ + if(sensor == NULL) + return HAL_ERROR; + return DS18B20_ReadScratchpad(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM, (uint8_t *)&sensor->hdallas->scratchpad); +} + +/** + * @brief Инициализирует структуру датчика по ROM + * @param hdallas Указатель на хендл для общения с датчиками + * @param sensor Указатель на структуру датчика + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_SensorInitByROM(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor) +{ + HAL_StatusTypeDef result; + + if(hdallas == NULL) + return HAL_ERROR; + if(sensor == NULL) + return HAL_ERROR; + + uint8_t ROM[8] = {0}; + ROM[0] = (sensor->Init.InitParam.ROM >> (7*8)) & 0xFF; + ROM[1] = (sensor->Init.InitParam.ROM >> (6*8)) & 0xFF; + ROM[2] = (sensor->Init.InitParam.ROM >> (5*8)) & 0xFF; + ROM[3] = (sensor->Init.InitParam.ROM >> (4*8)) & 0xFF; + ROM[4] = (sensor->Init.InitParam.ROM >> (3*8)) & 0xFF; + ROM[5] = (sensor->Init.InitParam.ROM >> (2*8)) & 0xFF; + ROM[6] = (sensor->Init.InitParam.ROM >> (1*8)) & 0xFF; + ROM[7] = (sensor->Init.InitParam.ROM >> (0*8)) & 0xFF; + + if(DS18B20_IsValidAddress(ROM) != HAL_OK) + return HAL_ERROR; + + uint8_t comparebytes = DALLAS_ROM_SIZE; + int ROM_ind = 0; + for(int i = 0; i < hdallas->onewire->RomCnt; i++) + { + comparebytes = DALLAS_ROM_SIZE; + for(int rom_byte = 0; rom_byte < DALLAS_ROM_SIZE; rom_byte++) + { + if(hdallas->ds_devices->DevAddr[i][rom_byte] == ROM[rom_byte]) + comparebytes--; + } + if(comparebytes == 0) + { + ROM_ind = i; + break; + } + } + + /* Проверка присутствует ли выбранный датчик на линии */ + if(comparebytes == 0) + { + + result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[ROM_ind]); + return result; + } + else + { + return HAL_ERROR; + } + + +} + + + +/** + * @brief Инициализирует структуру датчика по пользовательским байтам + * @param hdallas Указатель на хендл для общения с датчиками + * @param sensor Указатель на структуру датчика + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_SensorInitByUserBytes(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor) +{ + HAL_StatusTypeDef result; + + if(hdallas == NULL) + return HAL_ERROR; + if(sensor == NULL) + return HAL_ERROR; + + uint8_t UserByte1 = sensor->Init.InitParam.UserBytes.UserByte1; + uint8_t UserByte2 = sensor->Init.InitParam.UserBytes.UserByte2; + uint8_t UserByte3 = sensor->Init.InitParam.UserBytes.UserByte3; + uint8_t UserByte4 = sensor->Init.InitParam.UserBytes.UserByte4; + uint8_t UserByte12Cmp = 0; + uint8_t UserByte34Cmp = 0; + + for(int i = 0; i < hdallas->onewire->RomCnt; i++) + { + /* Проверка присутствует ли выбранный датчик на линии */ + result = DS18B20_ReadScratchpad(hdallas->onewire, (uint8_t *)&hdallas->ds_devices->DevAddr[i], (uint8_t *)&hdallas->scratchpad); + if (result != HAL_OK) + return result; + + /* Сравнение UserByte1 и UserByte2, если они не равны нулю */ + if(UserByte1 | UserByte2) + { + if( (hdallas->scratchpad.tHighRegister == UserByte1) && + (hdallas->scratchpad.tLowRegister == UserByte2)) + { + UserByte12Cmp = 1; + } + }/* Если сравнение UserByte1 и UserByte2 не выбрано, то считаем что они совпадают */ + else + { + UserByte12Cmp = 1; + } + /* Сравнение UserByte3 и UserByte4, если они не равны нулю */ + if(UserByte3 | UserByte4) + { + if( (hdallas->scratchpad.UserByte3 == UserByte3) && + (hdallas->scratchpad.UserByte4 == UserByte4)) + { + UserByte34Cmp = 1; + } + }/* Если сравнение UserByte3 и UserByte4 не выбрано, то считаем что они одинаковые */ + else + { + UserByte34Cmp = 1; + } + /* Если нашли нужный датчик - завершаем поиск */ + if(UserByte12Cmp && UserByte34Cmp) + { +// sensor->isInitialized = 1; +// sensor->Init.init_func = (HAL_StatusTypeDef (*)())Dallas_SensorInitByUserBytes; + result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[i]); + return result; + } + } + + sensor->sensROM = 0; + /* Возвращаем ошибку если не нашли */ + return HAL_ERROR; +} + +/** + * @brief Инициализирует структуру датчика по порядковому номеру + * @param hdallas Указатель на хендл для общения с датчиками + * @param sensor Указатель на структуру датчика + * @retval HAL Status + * @details Порядковый номер датчика в списке найденных. + * Т.е. каким по счету этот датчик был найден + */ +HAL_StatusTypeDef Dallas_SensorInitByInd(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor) +{ + HAL_StatusTypeDef result; + + if(hdallas == NULL) + return HAL_ERROR; + if(sensor == NULL) + return HAL_ERROR; + + result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[sensor->Init.InitParam.Ind]); + + return result; +} + +/** + * @brief Инициализирует датчик для работы + * @param hdallas Указатель на хендл для общения с датчиками + * @param sensor Указатель на структуру датчика + * @param ROM ROM датчика, который надо инициализировать + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_SensorInit(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor, uint8_t (*ROM)[DALLAS_ROM_SIZE]) +{ + HAL_StatusTypeDef result; + + if(sensor == NULL) + return HAL_ERROR; + if(hdallas == 0) + return HAL_ERROR; + + sensor->hdallas = hdallas; + sensor->sensROM = 0; + sensor->sensROM = *(uint64_t *)(ROM); +// for(int i = 0; i < DALLAS_ROM_SIZE; i++) +// sensor->sensROM |= ((uint64_t)(*ROM)[i] << (56 - 8*i)); + + /* Проверка присутствует ли выбранный датчик на линии */ + result = Dallas_ReadScratchpad(sensor); + if (result == HAL_OK) + { + /* Установка разрешения */ + result = DS18B20_SetResolution(hdallas->onewire, (uint8_t *)ROM, sensor->Init.Resolution); + if (result == HAL_OK) + { + sensor->isInitialized = 1; + return HAL_OK; + } + else + { + sensor->isInitialized = 0; + return result; + } + } + else + { + sensor->isInitialized = 0; + return result; + } +} + +/** + * @brief Деинициализирует структуру датчика + * @param sensor Указатель на структуру датчика + * @retval HAL Status + */ +HAL_StatusTypeDef Dallas_SensorDeInit(DALLAS_SensorHandleTypeDef *sensor) +{ + if(sensor == NULL) + return HAL_ERROR; + + memset(&sensor->f, 0, sizeof(sensor->f)); + sensor->isConnected = 0; + sensor->isInitialized = 0; + sensor->isLost = 0; + sensor->temperature = 0; + sensor->sensROM = 0; + + return HAL_OK; +} diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dma.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dma.c new file mode 100644 index 0000000..50400ee --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/dma.c @@ -0,0 +1,67 @@ +/* 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) 2025 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 */ +DMA_HandleTypeDef hdma_memtomem_dma1_channel1; + +/** + * Enable DMA controller clock + * Configure DMA for memory to memory transfers + * hdma_memtomem_dma1_channel1 + */ +void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMA1_CLK_ENABLE(); + + /* Configure DMA request hdma_memtomem_dma1_channel1 on DMA1_Channel1 */ + hdma_memtomem_dma1_channel1.Instance = DMA1_Channel1; + hdma_memtomem_dma1_channel1.Init.Direction = DMA_MEMORY_TO_MEMORY; + hdma_memtomem_dma1_channel1.Init.PeriphInc = DMA_PINC_ENABLE; + hdma_memtomem_dma1_channel1.Init.MemInc = DMA_MINC_ENABLE; + hdma_memtomem_dma1_channel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_memtomem_dma1_channel1.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_memtomem_dma1_channel1.Init.Mode = DMA_NORMAL; + hdma_memtomem_dma1_channel1.Init.Priority = DMA_PRIORITY_LOW; + if (HAL_DMA_Init(&hdma_memtomem_dma1_channel1) != HAL_OK) + { + Error_Handler(); + } + +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ + diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ds18b20_driver.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ds18b20_driver.c new file mode 100644 index 0000000..416d8a4 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ds18b20_driver.c @@ -0,0 +1,607 @@ +/** + ****************************************************************************** + * @file ds18b20_driver.c + * @brief This file includes the HAL/LL driver for DS18B20 1-Wire Digital + * Thermometer + ****************************************************************************** + */ +#include "ds18b20_driver.h" + +DS18B20_Drv_t DS; +OneWire_t OW; + +/** + * @brief The function is used to check valid DS18B20 ROM + * @retval Return in OK = 1, Failed = 0 + * @param ROM Pointer to ROM number + */ +HAL_StatusTypeDef DS18B20_IsValidAddress(uint8_t *ROM) +{ + if(ROM == NULL) + return HAL_ERROR; + + uint8_t check_family = (*ROM == DS18B20_FAMILY_CODE); + /* Calculate CRC */ + uint8_t crc = OneWire_CRC8(ROM, 7); + uint8_t check_crc = (crc == ROM[7]); + /* Checks if first byte is equal to DS18B20's family code */ + if(check_family && check_crc) + return HAL_OK; + else + return HAL_ERROR; +} +/** + * @brief The function is used to check valid DS18B20 ROM + * @retval Return in OK = 1, Failed = 0 + * @param ROM Pointer to ROM number + */ +HAL_StatusTypeDef DS18B20_IsValid(uint8_t *ROM) +{ + if(ROM == NULL) + return HAL_ERROR; + + if(*ROM == DS18B20_FAMILY_CODE) + return HAL_OK; + else + return HAL_ERROR; +} + +/** + * @brief The function is used to get resolution + * @retval Return value in 9 - 12 + * @param OW OneWire HandleTypedef + * @param ROM Pointer to ROM number + */ +uint8_t DS18B20_GetResolution(OneWire_t* OW, uint8_t *ROM) { + uint8_t conf; + + if(OW == NULL) + return HAL_ERROR; + if(ROM == NULL) + return HAL_ERROR; + + /* Check valid ROM */ + if (DS18B20_IsValid(ROM) != HAL_OK) + return 0; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Read scratchpad command by onewire protocol */ + OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD); + + /* Ignore first 4 bytes */ + OneWire_ReadByte(OW); + OneWire_ReadByte(OW); + OneWire_ReadByte(OW); + OneWire_ReadByte(OW); + + /* 5th byte of scratchpad is configuration register */ + conf = OneWire_ReadByte(OW); + + /* Return 9 - 12 value according to number of bits */ + return ((conf & 0x60) >> 5) + 9; +} + +/** + * @brief The function is used as set resolution + * @retval status in OK = 1, Failed = 0 + * @param OW OneWire HandleTypedef + * @param ROM Pointer to ROM number + * @param Resolution Resolution in 9 - 12 + */ +HAL_StatusTypeDef DS18B20_SetResolution(OneWire_t* OW, uint8_t *ROM, + DS18B20_Res_t Resolution) +{ + if(OW == NULL) + return HAL_ERROR; + if(ROM == NULL) + return HAL_ERROR; + + uint8_t th, tl, conf; + + /* Check valid ROM */ + if (DS18B20_IsValid(ROM) != HAL_OK) + return HAL_ERROR; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Read scratchpad command by onewire protocol */ + OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD); + + /* Ignore first 2 bytes */ + OneWire_ReadByte(OW); + OneWire_ReadByte(OW); + + th = OneWire_ReadByte(OW); + tl = OneWire_ReadByte(OW); + conf = OneWire_ReadByte(OW); + + /* Set choosed resolution */ + conf = Resolution; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Write scratchpad command by onewire protocol, only th, tl and conf + * register can be written */ + OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD); + + /* Write bytes */ + OneWire_WriteByte(OW, th); + OneWire_WriteByte(OW, tl); + OneWire_WriteByte(OW, conf); + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Copy scratchpad to EEPROM of DS18B20 */ + OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD); + + return HAL_OK; +} + +/** + * @brief The function is used as start selected ROM device + * @retval status in OK = 1, Failed = 0 + * @param OW OneWire HandleTypedef + * @param ROM Pointer to ROM number + */ +HAL_StatusTypeDef DS18B20_StartConvT(OneWire_t* OW, uint8_t *ROM) +{ + if(OW == NULL) + return HAL_ERROR; + if(ROM == NULL) + return HAL_ERROR; + + /* Check if device is DS18B20 */ + if(DS18B20_IsValid(ROM) != HAL_OK) + return HAL_ERROR; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Start temperature conversion */ + OneWire_WriteByte(OW, DS18B20_CMD_CONVERT); + + return HAL_OK; +} +/** + * @brief The function is used as start all ROM device + * @param OW OneWire HandleTypedef + */ +HAL_StatusTypeDef DS18B20_StartConvTAll(OneWire_t* OW) +{ + if(OW == NULL) + return HAL_ERROR; + + /* Reset pulse */ + OneWire_Reset(OW); + + /* Skip rom */ + OneWire_WriteByte(OW, ONEWIRE_CMD_SKIPROM); + + /* Start conversion on all connected devices */ + OneWire_WriteByte(OW, DS18B20_CMD_CONVERT); + + return HAL_OK; +} + +/** + * @brief The function is used as read temreature from device and store in selected + * destination + * @retval status in OK = 1, Failed = 0 + * @param OW OneWire HandleTypedef + * @param ROM Pointer to ROM number + * @param Destination Pointer to return value + */ +HAL_StatusTypeDef DS18B20_CalcTemperature(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad, float *Destination) +{ + if(OW == NULL) + return HAL_ERROR; + if(ROM == NULL) + return HAL_ERROR; + if(Scratchpad == NULL) + return HAL_ERROR; + if(Destination == NULL) + return HAL_ERROR; + + uint16_t temperature; + uint8_t resolution; + int8_t digit, minus = 0; + float decimal; + + /* Check if device is DS18B20 */ + if (DS18B20_IsValid(ROM) != HAL_OK) + return HAL_ERROR; + + /* First two bytes of scratchpad are temperature values */ + temperature = Scratchpad[0] | (Scratchpad[1] << 8); + + /* Reset line */ + OneWire_Reset(OW); + + /* Check if temperature is negative */ + if (temperature & 0x8000) { + /* Two's complement, temperature is negative */ + temperature = ~temperature + 1; + minus = 1; + } + + /* Get sensor resolution */ + resolution = Scratchpad[4]; + + /* Store temperature integer digits and decimal digits */ + digit = temperature >> 4; + digit |= ((temperature >> 8) & 0x7) << 4; + + /* Store decimal digits */ + switch (resolution) { + case DS18B20_RESOLUTION_9BITS: { + decimal = (temperature >> 3) & 0x01; + decimal *= (float)DS18B20_DECIMAL_STEP_9BIT; + } break; + case DS18B20_RESOLUTION_10BITS: { + decimal = (temperature >> 2) & 0x03; + decimal *= (float)DS18B20_DECIMAL_STEP_10BIT; + } break; + case DS18B20_RESOLUTION_11BITS: { + decimal = (temperature >> 1) & 0x07; + decimal *= (float)DS18B20_DECIMAL_STEP_11BIT; + } break; + case DS18B20_RESOLUTION_12BITS: { + decimal = temperature & 0x0F; + decimal *= (float)DS18B20_DECIMAL_STEP_12BIT; + } break; + default: { + *Destination = 0; + return HAL_ERROR; + } + } + + /* Check for negative part */ + decimal = digit + decimal; + if (minus) { + decimal = 0 - decimal; + } + + /* Set to pointer */ + *Destination = decimal; + + /* Return HAL_OK, temperature valid */ + return HAL_OK; +} + + +/** + * @brief The function is used as read scratchpad from device + * @retval status in OK = 1, Failed = 0 + * @param OW OneWire HandleTypedef + * @param ROM Pointer to ROM number + * @param Destination Pointer to Scratchpad array + */ +HAL_StatusTypeDef DS18B20_ReadScratchpad(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad) +{ + if(OW == NULL) + return HAL_ERROR; + if(ROM == NULL) + return HAL_ERROR; + if(Scratchpad == NULL) + return HAL_ERROR; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Read scratchpad command by onewire protocol */ + OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD); + + /* Get data */ + for (int i = 0; i < 9; i++) { + /* Read byte by byte */ + Scratchpad[i] = OneWire_ReadByte(OW); + } + + /* Calculate CRC */ + uint8_t crc = OneWire_CRC8(Scratchpad, 8); + + /* Check if CRC is ok */ + if (crc != Scratchpad[8]) { + /* CRC invalid */ + return HAL_ERROR; + } + return HAL_OK; +} + + +/** + * @brief The function is used to wait for end of convertion + * @param OW OneWire HandleTypedef + */ +HAL_StatusTypeDef DS18B20_WaitForEndConvertion(OneWire_t* OW) +{ + if(OW == NULL) + return HAL_ERROR; + uint32_t tickstart = HAL_GetTick(); + + /* Wait until line is released, then coversion is completed */ + while(OneWire_ReadBit(OW) == 0) + { + if(HAL_GetTick() - tickstart > DS18B20_DELAY_MS_MAX) + return HAL_TIMEOUT; // end of convertion has not come + } + return HAL_OK; // convertion done +} + + +/** + * @brief The function is used to wait for end of convertion without blocking + * @param OW OneWire HandleTypedef + */ +HAL_StatusTypeDef DS18B20_WaitForEndConvertion_NonBlocking(OneWire_t* OW) +{ + if(OW == NULL) + return HAL_ERROR; + + /* If line is pull down - conversion is ongoing */ + if(OneWire_ReadBit(OW) == 0) + return HAL_BUSY; + else + return HAL_OK; // convertion done +} + + +/** + * @brief The function is used as set temperature alarm range on + * selected device + * @retval status in OK = 1, Failed = 0 + * @param OW OneWire HandleTypedef + * @param ROM Pointer to ROM number + * @param Low Low temperature alarm, value > -55, 0 = reset + * @param High High temperature alarm,, value < 125, 0 = reset + */ +HAL_StatusTypeDef DS18B20_SetTempAlarm(OneWire_t* OW, uint8_t *ROM, int8_t Low, + int8_t High) +{ + if(OW == NULL) + return HAL_ERROR; + if(ROM == NULL) + return HAL_ERROR; + + uint8_t tl, th, conf; + + /* Check if device is DS18B20 */ + if (DS18B20_IsValid(ROM) != HAL_OK) + return HAL_ERROR; + + Low = ((Low < -55) || (Low == 0)) ? -55 : Low; + High = ((High > 125) || (High == 0)) ? 125 : High; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Read scratchpad command by onewire protocol */ + OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD); + + /* Ignore first 2 bytes */ + OneWire_ReadByte(OW); + OneWire_ReadByte(OW); + + th = OneWire_ReadByte(OW); + tl = OneWire_ReadByte(OW); + conf = OneWire_ReadByte(OW); + + th = (uint8_t)High; + tl = (uint8_t)Low; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Write scratchpad command by onewire protocol, only th, tl and conf + * register can be written */ + OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD); + + /* Write bytes */ + OneWire_WriteByte(OW, th); + OneWire_WriteByte(OW, tl); + OneWire_WriteByte(OW, conf); + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Copy scratchpad to EEPROM of DS18B20 */ + OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD); + + return HAL_OK; +} + +/** + * @brief The function is used as set user bytes with mask + * @retval status in OK = 1, Failed = 0 + * @param OW OneWire HandleTypedef + * @param ROM Pointer to ROM number + * @param UserBytes12 First 2 User Bytes (tHigh and tLow) + * @param UserBytes34 Second 2 User Bytes + * @param UserBytesMask Which User Bytes write, and which ignore + */ +HAL_StatusTypeDef DS18B20_WriteUserBytes(OneWire_t* OW, uint8_t *ROM, int16_t UserBytes12, + int16_t UserBytes34, uint8_t UserBytesMask) +{ + if(OW == NULL) + return HAL_ERROR; + if(ROM == NULL) + return HAL_ERROR; + + uint8_t ub1, ub2, conf, ub3, ub4; + uint8_t UserByte1 = UserBytes12 & 0xFF; + uint8_t UserByte2 = UserBytes12 >> 8; + uint8_t UserByte3 = UserBytes34 & 0xFF; + uint8_t UserByte4 = UserBytes34 >> 8; + + /* Check if device is DS18B20 */ + if (DS18B20_IsValid(ROM) != HAL_OK) + return HAL_ERROR; + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Read scratchpad command by onewire protocol */ + OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD); + + /* Ignore first 2 bytes */ + OneWire_ReadByte(OW); + OneWire_ReadByte(OW); + + ub1 = OneWire_ReadByte(OW); + ub2 = OneWire_ReadByte(OW); + conf = OneWire_ReadByte(OW); + OneWire_ReadByte(OW); + ub3 = OneWire_ReadByte(OW); + ub4 = OneWire_ReadByte(OW); + + /* If user bytes in mask */ + if(UserBytesMask & (1<<0)) + { + ub1 = UserByte1; + } + if(UserBytesMask & (1<<1)) + { + ub2 = UserByte2; + } + if(UserBytesMask & (1<<2)) + { + ub3 = UserByte3; + } + if(UserBytesMask & (1<<3)) + { + ub4 = UserByte4; + } + + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Write scratchpad command by onewire protocol, only th, tl and conf + * register can be written */ + OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD); + + /* Write bytes */ + OneWire_WriteByte(OW, ub1); + OneWire_WriteByte(OW, ub2); + OneWire_WriteByte(OW, conf); + OneWire_WriteByte(OW, ub3); + OneWire_WriteByte(OW, ub4); + + /* Reset line */ + OneWire_Reset(OW); + + /* Select ROM number */ + OneWire_MatchROM(OW, ROM); + + /* Copy scratchpad to EEPROM of DS18B20 */ + OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD); + + return HAL_OK; +} + + +///** +// * @brief The function is used as search device that had temperature alarm +// * triggered and store it in DS18B20 alarm data structure +// * @retval status of search, OK = 1, Failed = 0 +// * @param DS DS18B20 HandleTypedef +// * @param OW OneWire HandleTypedef +// */ +//uint8_t DS18B20_AlarmSearch(DS18B20_Drv_t *DS, OneWire_t* OW) +//{ +// uint8_t t = 0; + +// /* Reset Alarm in DS */ +// for(uint8_t i = 0; i < OW->RomCnt; i++) +// { +// for(uint8_t j = 0; j < 8; j++) +// { +// DS->AlmAddr[i][j] = 0; +// } +// } + +// /* Start alarm search */ +// while (OneWire_Search(OW, DS18B20_CMD_ALARM_SEARCH)) +// { +// /* Store ROM of device which has alarm flag set */ +// OneWire_GetDevRom(OW, DS->AlmAddr[t]); +// t++; +// } +// return (t > 0) ? 1 : 0; +//} + +/** + * @brief The function is used to initialize the DS18B20 sensor, and search + * for all ROM along the line. Store in DS18B20 data structure + * @retval Rom detect status, OK = 1, No Rom detected = 0 + * @param DS DS18B20 HandleTypedef + * @param OW OneWire HandleTypedef + */ +HAL_StatusTypeDef DS18B20_Search(DS18B20_Drv_t *DS, OneWire_t *OW) +{ + if(OW == NULL) + return HAL_ERROR; + + + OW->RomCnt = 0; + /* Search all OneWire devices ROM */ + while(1) + { + /* Start searching for OneWire devices along the line */ + if(OneWire_Search(OW, ONEWIRE_CMD_SEARCHROM) != 1) break; + + /* Get device ROM */ + OneWire_GetDevRom(OW, DS->DevAddr[OW->RomCnt]); + + OW->RomCnt++; + } + for(int i = OW->RomCnt; i < DS18B20_DEVICE_AMOUNT; i++) + { + for(int j = 0; j < 8; j++) + DS->DevAddr[i][j] = 0; + } + + + if(OW->RomCnt > 0) + return HAL_OK; + else + return HAL_BUSY; +} diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/gpio.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/gpio.c new file mode 100644 index 0000000..9044674 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/gpio.c @@ -0,0 +1,105 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "gpio.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI +*/ +void MX_GPIO_Init(void) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1|GPIO_PIN_4 + |GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8 + |GPIO_PIN_9|Relay_dc5v_Pin|One_wire_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10 + |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 + |GPIO_PIN_15, GPIO_PIN_RESET); + + /*Configure GPIO pin : PC13 */ + GPIO_InitStruct.Pin = GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pin : PA0 */ + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pins : PA1 PA4 + PA5 PA6 PA7 PA8 + PA9 Relay_dc5v_Pin One_wire_Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4 + |GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8 + |GPIO_PIN_9|Relay_dc5v_Pin|One_wire_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pins : PB0 PB1 PB2 PB10 + PB11 PB12 PB13 PB14 + PB15 */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10 + |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 + |GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/i2c.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/i2c.c new file mode 100644 index 0000000..7516a32 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/i2c.c @@ -0,0 +1,117 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.c + * @brief This file provides code for the configuration + * of the I2C instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "i2c.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +I2C_HandleTypeDef hi2c1; + +/* I2C1 init function */ +void MX_I2C1_Init(void) +{ + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ + hi2c1.Instance = I2C1; + hi2c1.Init.ClockSpeed = 100000; + hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; + hi2c1.Init.OwnAddress1 = 0; + hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c1.Init.OwnAddress2 = 0; + hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if (HAL_I2C_Init(&hi2c1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ + +} + +void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(i2cHandle->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspInit 0 */ + + /* USER CODE END I2C1_MspInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB8 ------> I2C1_SCL + PB9 ------> I2C1_SDA + */ + GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + __HAL_AFIO_REMAP_I2C1_ENABLE(); + + /* I2C1 clock enable */ + __HAL_RCC_I2C1_CLK_ENABLE(); + /* USER CODE BEGIN I2C1_MspInit 1 */ + + /* USER CODE END I2C1_MspInit 1 */ + } +} + +void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle) +{ + + if(i2cHandle->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspDeInit 0 */ + + /* USER CODE END I2C1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C1_CLK_DISABLE(); + + /**I2C1 GPIO Configuration + PB8 ------> I2C1_SCL + PB9 ------> I2C1_SDA + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9); + + /* USER CODE BEGIN I2C1_MspDeInit 1 */ + + /* USER CODE END I2C1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c new file mode 100644 index 0000000..f280742 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c @@ -0,0 +1,763 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "main.h" +#include "adc.h" +#include "can.h" +#include "i2c.h" +#include "rtc.h" +#include "spi.h" +#include "tim.h" +#include "usart.h" +#include "gpio.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "dallas_tools.h" + +#include "def.h" +#include +#include "modbus.h" +#include "eeprom_emul.h" +#include "stdio.h" +#include "flash_ring.h" +#include "string.h" + + + + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +uint16_t iter, cnt = 5; +uint8_t init_retries = 5; +uint8_t ralay_5v_on_var = 0; +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ +float temperature; +uint8_t roms[MAX_DEVICES][8]; +Flags_TypeDef flag; +//extern uint8_t devices_found ; +uint8_t _debug_init = 0; +TEMP_TypeDef temp_sense[30]; +float set_temp_old[30]; +char rx_buffer[64]; +uint8_t rx_index = 0; +char command_ready = 0; +uint8_t uart_byte = 0; +uint8_t first_in = 1; +DALLAS_SensorHandleTypeDef sens[30]; +int init_sens = 0; +FlashRecord_t* record; +uint8_t flash_buff[RECORD_SIZE - 4]; + +RS_HandleTypeDef hmodbus_master; +RS_MsgTypeDef MODBUS_MASTER_MSG; +static uint8_t hmodbus_master_buffer[MSG_SIZE_MAX]; +static uint8_t rtc_modbus_hold_initialized = 0U; + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +int last_page_addr = LAST_PAGE_ADDR; + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ +static void RTC_ModbusService(MB_DataStructureTypeDef* mb_data); +static void RTC_ReadCalendarFromRegs(const MB_RtcCalendarRegsTypeDef* regs, RTC_CalendarTypeDef* calendar); +static void RTC_WriteCalendarToRegs(MB_RtcCalendarRegsTypeDef* regs, const RTC_CalendarTypeDef* calendar, uint16_t status); + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ +HAL_StatusTypeDef ModbusMaster_Request(RS_MsgTypeDef *request, + void (*callback)(RS_HandleTypeDef *, RS_MsgTypeDef *)) +{ + return MODBUS_MasterRequest(&hmodbus_master, request, callback); +} + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_TIM1_Init(); + MX_USART1_UART_Init(); + MX_USART2_UART_Init(); + MX_TIM2_Init(); + MX_TIM4_Init(); + MX_ADC1_Init(); + MX_CAN_Init(); + MX_I2C1_Init(); + MX_RTC_Init(); + MX_SPI1_Init(); + /* USER CODE BEGIN 2 */ + + + + led_blink(GPIOC, 13, rest_iter, reset_blink_delay); + MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim); + MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE); + // Запуск приема Modbus + MODBUS_SlaveStart(&hmodbus1, NULL); + if (MODBUS_FirstInit(&hmodbus_master, &huart2, &htim4) != HAL_OK) + { + Error_Handler(); + } + hmodbus_master.pBufferPtr = hmodbus_master_buffer; + if (MODBUS_Config(&hmodbus_master, 0, MODBUS_TIMEOUT, MODBUS_MODE_MASTER) != HAL_OK) + { + Error_Handler(); + } + uint8_t uart_byte = 0; + Dallas_BusFirstInit(&htim1); + // ������������� �� ������� ��������� �������� + // ������������� �� ������� (����������� ������ ���������� �������) + reinit_t_sens(); + init_setpoint_all_T_sense(temp_sense, hdallas.onewire->RomCnt); + + MB_DATA.InRegs.num_Tsens = hdallas.onewire->RomCnt; + RTC_ModbusService(&MB_DATA); + // BufferState_t buffer_state = buffer_init(); +for(int i=0;iODR |= 1 << 13; +// } + +// } + temp_sense[0].t_close = 1; + Field_modbus(&MB_DATA, &flag); + Check_Tconnect(&MB_DATA, &flag, &hdallas, 0); + value_control(); + init_setpoint_all_T_sense(temp_sense, hdallas.onewire->RomCnt); + // handle_valves(temp_sense[]); + Dallas_StartConvertTAll(&hdallas, DALLAS_WAIT_BUS, 0); + for(int i = 0; i < hdallas.onewire->RomCnt; i++) + { + if(sens[i].isLost) + { + sens[i].lost_cnt ++; + } + Dallas_ReadTemperature(&sens[i]); + MB_DATA.InRegs.sens_Temp[i] = sens[i].temperature * 10; +/////////////////////////заменить на define ralay_5v_on_var GPIOA->ODR|=1<<10; + ralay_5v_on_var = MB_DATA.Coils.coils[1].state_val_bit.state_val_05; + if (ralay_5v_on_var) + { + GPIOA->ODR |= 1 << 10; + } + else + { + GPIOA->ODR &= ~(1 << 10); + } + + + } + + + + + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + //iwdg_refresh(); + + //HAL_Delay(200); + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC; + PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ +static void RTC_ReadCalendarFromRegs(const MB_RtcCalendarRegsTypeDef* regs, RTC_CalendarTypeDef* calendar) +{ + if ((regs == NULL) || (calendar == NULL)) + { + return; + } + + calendar->hours = regs->hours; + calendar->minutes = regs->minutes; + calendar->seconds = regs->seconds; + calendar->date = regs->date; + calendar->month = regs->month; + calendar->year = regs->year; + calendar->weekday = regs->weekday; +} + +static void RTC_WriteCalendarToRegs(MB_RtcCalendarRegsTypeDef* regs, const RTC_CalendarTypeDef* calendar, uint16_t status) +{ + if ((regs == NULL) || (calendar == NULL)) + { + return; + } + + regs->hours = calendar->hours; + regs->minutes = calendar->minutes; + regs->seconds = calendar->seconds; + regs->date = calendar->date; + regs->month = calendar->month; + regs->year = calendar->year; + regs->weekday = calendar->weekday; + regs->apply = 0U; + regs->status = status; +} + +static void RTC_ModbusService(MB_DataStructureTypeDef* mb_data) +{ + RTC_CalendarTypeDef calendar = {0}; + uint16_t hold_status = MB_RTC_STATUS_IDLE; + uint8_t copy_current_to_holding = 0U; + + if (mb_data == NULL) + { + return; + } + + hold_status = mb_data->HoldRegs.rtc.status; + + if (mb_data->HoldRegs.rtc.apply == MB_RTC_APPLY_SET) + { + RTC_ReadCalendarFromRegs(&mb_data->HoldRegs.rtc, &calendar); + mb_data->HoldRegs.rtc.apply = 0U; + + if (RTC_CalendarIsValid(&calendar) == 0U) + { + hold_status = MB_RTC_STATUS_VALUE_ERROR; + } + else if (RTC_CalendarSet(&calendar) != HAL_OK) + { + hold_status = MB_RTC_STATUS_HAL_ERROR; + } + else + { + hold_status = MB_RTC_STATUS_SET_OK; + copy_current_to_holding = 1U; + } + } + + if (RTC_CalendarGet(&calendar) != HAL_OK) + { + mb_data->InRegs.rtc.status = MB_RTC_STATUS_HAL_ERROR; + mb_data->HoldRegs.rtc.status = MB_RTC_STATUS_HAL_ERROR; + return; + } + + RTC_WriteCalendarToRegs(&mb_data->InRegs.rtc, &calendar, MB_RTC_STATUS_IDLE); + + if ((rtc_modbus_hold_initialized == 0U) || (copy_current_to_holding != 0U)) + { + RTC_WriteCalendarToRegs(&mb_data->HoldRegs.rtc, &calendar, hold_status); + rtc_modbus_hold_initialized = 1U; + } + else + { + mb_data->HoldRegs.rtc.status = hold_status; + } +} + +void iwdg_refresh(void) +{ + IWDG->KR = 0xAAAA; // �������� ������ +} +void led_blink(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint8_t iter, uint16_t delay) +{ + for(int i = 0; i < iter; i++) + { + GPIOx->ODR ^= (1 << GPIO_Pin); + HAL_Delay(delay); + } +} + +void Check_Tconnect(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag, DALLAS_HandleTypeDef* hdallas, int a[0]) +{ + for(int i = 0; i < hdallas->onewire->RomCnt; i++) + { + if(sens[i].isLost) + { + //init_sens=1; + } + + } + if (init_sens || flag->init_tsens) + { + init_sens = 0; + flag->init_tsens = 0; + //Dallas_BusFirstInit(&htim1); + DS18B20_Search(&DS, &OW) ; + reinit_t_sens(); + MB_DATA->InRegs.num_Tsens = hdallas->onewire->RomCnt; + } +} + +void reinit_t_sens(void) +{ + for ( int i = 0; i < hdallas.onewire->RomCnt; i++) + { + // ������������� �� ROM-������ + //sens[i].Init.init_func = &Dallas_SensorInitByROM; + // sens[i].Init.InitParam.ROM = rom_address; + sens[i].Init.InitParam.Ind = i; + sens[i].Init.init_func = &Dallas_SensorInitByInd; + sens[i].Init.Resolution = DALLAS_CONFIG_9_BITS; sens[i].set_temp = 20.; + sens[i].hyst = 1; + MB_DATA.HoldRegs.set_Temp[i] = (uint16_t)(sens[i].set_temp * MB_ROOM_TEMP_SCALE); + MB_DATA.HoldRegs.set_hyst[i] = (uint16_t)(sens[i].hyst * MB_ROOM_TEMP_SCALE); + MB_DATA.HoldRegs.room_cfg[i].setpoint_x10 = MB_DATA.HoldRegs.set_Temp[i]; + MB_DATA.HoldRegs.room_cfg[i].hysteresis_x10 = MB_DATA.HoldRegs.set_hyst[i]; + MB_DATA.HoldRegs.room_cfg[i].valve_position_pct = 0; + MB_DATA.HoldRegs.room_cfg[i].valve_angle_max_deg = MB_ROOM_VALVE_ANGLE_MAX_DEFAULT; + MB_DATA.HoldRegs.room_cfg[i].mode = ROOM_MODE_AUTO; + MB_DATA.HoldRegs.room_cfg[i].command = ROOM_COMMAND_STOP; + MB_DATA.HoldRegs.room_cfg[i].location = 1; + MB_DATA.HoldRegs.room_cfg[i].apply = 0; + Dallas_AddNewSensors(&hdallas, &sens[i]); + + } +} +FuncStat packStruct(MB_DataStructureTypeDef* MB_DATA, int sizeARR) +{ + for(int i = 0; i < sizeARR; i++) + { + for(int sens_num = 0; sens_num < hdallas.onewire->RomCnt; sens_num++) + { + switch(sens_num) + { + case 0: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp1_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 1: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp2_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 2: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp3_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 3: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp4_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 4: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp5_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 5: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp6_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 6: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp7_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 7: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp8_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 8: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp9_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 9: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp10_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 10: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp11_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 11: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp12_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 12: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp13_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 13: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp14_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 14: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp15_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 15: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp16_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + } + } + } + return FuncOK; + +} + +static uint16_t clamp_room_percent(uint16_t value) +{ + return value > 100U ? 100U : value; +} + +static void update_room_modbus(MB_DataStructureTypeDef* MB_DATA) +{ + for (int i = 0; i < MAX_SENSE; i++) + { + MB_RoomInputRegsTypeDef* room = &MB_DATA->InRegs.room[i]; + MB_RoomHoldingRegsTypeDef* cfg = &MB_DATA->HoldRegs.room_cfg[i]; + uint16_t open_state = 0U; + uint16_t close_state = 0U; + uint16_t position_pct; + uint16_t angle_max; + + if (cfg->valve_angle_max_deg == 0U) + { + cfg->valve_angle_max_deg = MB_ROOM_VALVE_ANGLE_MAX_DEFAULT; + } + + if (i < 16) + { + open_state = (MB_DATA->Coils.relay_struct_on.all >> i) & 0x1U; + close_state = (MB_DATA->Coils.relay_struct_off.all >> i) & 0x1U; + } + + position_pct = clamp_room_percent(cfg->valve_position_pct); + if (cfg->mode == ROOM_MODE_AUTO) + { + if (open_state) + { + position_pct = 100U; + } + else if (close_state) + { + position_pct = 0U; + } + } + cfg->valve_position_pct = position_pct; + angle_max = cfg->valve_angle_max_deg; + + room->channel = (uint16_t)(i + 1); + room->location = cfg->location; + for (int reg = 0; reg < 4; reg++) + { + room->ds18b20_id[reg] = ((uint16_t)MB_DATA->InRegs.ID.DevAddr[i][reg * 2]) | + ((uint16_t)MB_DATA->InRegs.ID.DevAddr[i][reg * 2 + 1] << 8); + } + room->temperature_x10 = (i < hdallas.onewire->RomCnt) ? (uint16_t)((int16_t)(sens[i].temperature * MB_ROOM_TEMP_SCALE)) : 0U; + room->setpoint_x10 = MB_DATA->HoldRegs.set_Temp[i]; + room->hysteresis_x10 = MB_DATA->HoldRegs.set_hyst[i]; + room->valve_position_pct = position_pct; + room->valve_angle_deg = (uint16_t)((position_pct * angle_max) / 100U); + room->valve_angle_max_deg = angle_max; + room->is_connected = (i < hdallas.onewire->RomCnt) ? (uint16_t)sens[i].isConnected : 0U; + room->valve_open = open_state; + room->valve_close = close_state; + room->mode = cfg->mode; + room->command_state = cfg->command; + room->reserved = 0U; + } +} +FuncStat Field_modbus(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag) +{ + + MB_DATA->InRegs.ID = *hdallas.ds_devices; + RTC_ModbusService(MB_DATA); + flag->init_tsens = MB_DATA->Coils.init_Tsens; + packStruct(MB_DATA, MAX_SENSE / 16); + if (_debug_init || MB_DATA->Coils.init_param) + { + _debug_init = 0; + + MB_DATA->Coils.init_param = 0; + for(int i = 0; i < hdallas.onewire->RomCnt; i++) + { if (MB_DATA->HoldRegs.room_cfg[i].apply) + { + MB_DATA->HoldRegs.set_Temp[i] = MB_DATA->HoldRegs.room_cfg[i].setpoint_x10; + MB_DATA->HoldRegs.set_hyst[i] = MB_DATA->HoldRegs.room_cfg[i].hysteresis_x10; + MB_DATA->HoldRegs.room_cfg[i].apply = 0U; + } + MB_DATA->HoldRegs.room_cfg[i].setpoint_x10 = MB_DATA->HoldRegs.set_Temp[i]; + MB_DATA->HoldRegs.room_cfg[i].hysteresis_x10 = MB_DATA->HoldRegs.set_hyst[i]; + sens[i].set_temp = ((float)MB_DATA->HoldRegs.set_Temp[i]) / MB_ROOM_TEMP_SCALE; + sens[i].hyst = ((float)MB_DATA->HoldRegs.set_hyst[i]) / MB_ROOM_TEMP_SCALE; + } + + + + } + + update_room_modbus(MB_DATA); + return FuncOK; +}; + + +FuncStat value_control(void ) +{ + + for(int i = 0; i < hdallas.onewire->RomCnt; i++) + { + if (i < 16 && MB_DATA.HoldRegs.room_cfg[i].mode == ROOM_MODE_MANUAL) + { + uint16_t manual_pct = clamp_room_percent(MB_DATA.HoldRegs.room_cfg[i].valve_position_pct); + if (MB_DATA.HoldRegs.room_cfg[i].command == ROOM_COMMAND_CLOSE) + { + manual_pct = 0U; + } + else if (MB_DATA.HoldRegs.room_cfg[i].command == ROOM_COMMAND_OPEN && manual_pct == 0U) + { + manual_pct = 100U; + } + MB_DATA.HoldRegs.room_cfg[i].valve_position_pct = manual_pct; + if (manual_pct > 0U) + { + MB_DATA.Coils.relay_struct_off.all &= ~(1 << i); + MB_DATA.Coils.relay_struct_on.all |= 1 << i; + } + else + { + MB_DATA.Coils.relay_struct_on.all &= ~(1 << i); + MB_DATA.Coils.relay_struct_off.all |= 1 << i; + } + continue; + } + + if (sens[i].temperature < sens[i].set_temp - sens[i].hyst) + + { + + MB_DATA.Coils.relay_struct_off.all |= 1 << i; + MB_DATA.Coils.relay_struct_on.all &= ~(1 << i); + + + } + + else + + if (sens[i].temperature > sens[i].set_temp + sens[i].hyst) + { + + MB_DATA.Coils.relay_struct_off.all &= ~(1 << i); + MB_DATA.Coils.relay_struct_on.all |= 1 << i; + + } + + else + + if (sens[i].temperature == sens[i].set_temp ) + { + MB_DATA.Coils.relay_struct_on.all &= ~(1 << i); + MB_DATA.Coils.relay_struct_off.all &= ~(1 << i); + + } + + + } + + + return FuncOK; +} + + +uint16_t handle_valves(TEMP_TypeDef* temp_sense[MAX_SENSE] ) +{ + + if (temp_sense[0]->state == STATE_OPEN_VALVE) + { + GPIOC->ODR |= 1 << 14; + } + else if (temp_sense[0]->state == STATE_CLOSE_VALVE) + { + GPIOC->ODR &= ~(1 << 14); + } + + return 1; + +} + +void init_setpoint_all_T_sense(TEMP_TypeDef* temp_sense, int size_array) +{ + //ds_search_devices(); + for(int i = 0; i < size_array ; i++) + { + temp_sense[i].id[0] = roms[i][0] << 0 | roms[i][1] << 8 | roms[i][2] << 16 | roms[i][3] << 24; + temp_sense[i].id[1] = roms[i][4] << 0 | roms[i][5] << 8 | roms[i][6] << 16 | roms[i][7] << 24; + temp_sense[i].count = i + 1; + temp_sense[i].location = 1; + temp_sense[i].t_open = 22; + temp_sense[i].t_close = 18; + temp_sense[i].status_T_sense = 1; + } +} +/* USER CODE END 4 */ + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM3 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM3) + { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c.orig b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c.orig new file mode 100644 index 0000000..07af4fb --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/main.c.orig @@ -0,0 +1,540 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "main.h" +#include "adc.h" +#include "can.h" +#include "i2c.h" +#include "rtc.h" +#include "spi.h" +#include "tim.h" +#include "usart.h" +#include "gpio.h" + + + + + + + + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "dallas_tools.h" + +#include "def.h" +#include +#include "modbus.h" +#include "eeprom_emul.h" +#include "stdio.h" +#include "flash_ring.h" +#include "string.h" + + + + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +uint16_t iter, cnt = 5; +uint8_t init_retries = 5; +uint8_t ralay_5v_on_var = 0; +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ +float temperature; +uint8_t roms[MAX_DEVICES][8]; +Flags_TypeDef flag; +//extern uint8_t devices_found ; +uint8_t _debug_init = 0; +TEMP_TypeDef temp_sense[30]; +float set_temp_old[30]; +char rx_buffer[64]; +uint8_t rx_index = 0; +char command_ready = 0; +uint8_t uart_byte = 0; +uint8_t first_in = 1; +DALLAS_SensorHandleTypeDef sens[30]; +int init_sens = 0; +FlashRecord_t* record; +uint8_t flash_buff[RECORD_SIZE-4]; + + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +int last_page_addr=LAST_PAGE_ADDR; + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_TIM1_Init(); + MX_USART1_UART_Init(); + MX_TIM2_Init(); + MX_ADC1_Init(); + MX_CAN_Init(); + MX_I2C1_Init(); + MX_RTC_Init(); + MX_SPI1_Init(); + /* USER CODE BEGIN 2 */ + + + + led_blink(GPIOC, 13, rest_iter, reset_blink_delay); + MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim); + MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE); + // Запуск приема Modbus + MODBUS_SlaveStart(&hmodbus1, NULL); + uint8_t uart_byte = 0; + Dallas_BusFirstInit(&htim1); + // ������������� �� ������� ��������� �������� + // ������������� �� ������� (����������� ������ ���������� �������) + reinit_t_sens(); + init_setpoint_all_T_sense(temp_sense, hdallas.onewire->RomCnt); + + MB_DATA.InRegs.num_Tsens = hdallas.onewire->RomCnt; + BufferState_t buffer_state = buffer_init(); + + /* USER CODE END 2 */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + + +if (MB_DATA.Coils.relay_struct[0].state_val_bit.Temp11_relay_isOn) + { + MB_DATA.Coils.relay_struct[0].state_val_bit.Temp11_relay_isOn=0; + BufferState_t state = buffer_init(); + uint32_t idx = (state.write_index ) % RECORDS_PER_PAGE; + FlashRecord_t* record = buffer_read_record(idx); + + } + if (MB_DATA.Coils.relay_struct[0].state_val_bit.Temp10_relay_isOn) + { + MB_DATA.Coils.relay_struct[0].state_val_bit.Temp10_relay_isOn = 0; + FlashRecord_t new_record; + new_record.timestamp = HAL_GetTick(); + memset(new_record.data, (uint8_t)*flash_buff, sizeof(new_record.data)); + + HAL_StatusTypeDef status = buffer_write_record(&new_record, &buffer_state); + + if (status == HAL_OK) + { + // printf("Record written successfully\n"); + GPIOC->ODR|=1<<13; + } + + } + temp_sense[0].t_close = 1; + Field_modbus(&MB_DATA, &flag); + Check_Tconnect(&MB_DATA, &flag, &hdallas, 0); + value_control(); + init_setpoint_all_T_sense(temp_sense, hdallas.onewire->RomCnt); + // handle_valves(temp_sense[]); + Dallas_StartConvertTAll(&hdallas, DALLAS_WAIT_BUS, 0); + for(int i = 0; i < hdallas.onewire->RomCnt; i++) + { + if(sens[i].isLost) + { + sens[i].lost_cnt ++; + } + Dallas_ReadTemperature(&sens[i]); + MB_DATA.InRegs.sens_Temp[i] = sens[i].temperature * 10; +/////////////////////////заменить на define ralay_5v_on_var GPIOA->ODR|=1<<10; + ralay_5v_on_var = MB_DATA.Coils.coils[1].state_val_bit.state_val_05; + if (ralay_5v_on_var) + { + GPIOA->ODR |= 1 << 10; + } + else + { + GPIOA->ODR &= ~(1 << 10); + } + + + } + + + + + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + //iwdg_refresh(); + + //HAL_Delay(200); + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_ADC; + PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ +void iwdg_refresh(void) +{ + IWDG->KR = 0xAAAA; // �������� ������ +} +void led_blink(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint8_t iter, uint16_t delay) +{ + for(int i = 0; i < iter; i++) + { + GPIOx->ODR ^= (1 << GPIO_Pin); + HAL_Delay(delay); + } +} + +void Check_Tconnect(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag, DALLAS_HandleTypeDef* hdallas, int a[0]) +{ + for(int i = 0; i < hdallas->onewire->RomCnt; i++) + { + if(sens[i].isLost) + { + //init_sens=1; + } + + } + if (init_sens || flag->init_tsens) + { + init_sens = 0; + flag->init_tsens = 0; + //Dallas_BusFirstInit(&htim1); + DS18B20_Search(&DS, &OW) ; + reinit_t_sens(); + MB_DATA->InRegs.num_Tsens = hdallas->onewire->RomCnt; + } +} + +void reinit_t_sens(void) +{ + for ( int i = 0; i < hdallas.onewire->RomCnt; i++) + { + // ������������� �� ROM-������ + //sens[i].Init.init_func = &Dallas_SensorInitByROM; + // sens[i].Init.InitParam.ROM = rom_address; + sens[i].Init.InitParam.Ind = i; + sens[i].Init.init_func = &Dallas_SensorInitByInd; + sens[i].Init.Resolution = DALLAS_CONFIG_9_BITS; + MB_DATA.HoldRegs.set_Temp[i] = sens[i].set_temp = 20.; + MB_DATA.HoldRegs.set_hyst[i] = sens[i].hyst = 1; + Dallas_AddNewSensors(&hdallas, &sens[i]); + + } +} +FuncStat packStruct(MB_DataStructureTypeDef* MB_DATA, int sizeARR) +{ + for(int i = 0; i < sizeARR; i++) + { + for(int sens_num = 0; sens_num < hdallas.onewire->RomCnt; sens_num++) + { + switch(sens_num) + { + case 0: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp1_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 1: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp2_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 2: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp3_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 3: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp4_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 4: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp5_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 5: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp6_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 6: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp7_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 7: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp8_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 8: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp9_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 9: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp10_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 10: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp11_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 11: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp12_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 12: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp13_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 13: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp14_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 14: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp15_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + case 15: + MB_DATA->Coils.status_tSens[i].state_val_bit.Temp16_isConnected = sens[i * 16 + sens_num ].isConnected; + break; + } + } + } + return FuncOK; + +} +FuncStat Field_modbus(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag) +{ + + MB_DATA->InRegs.ID = *hdallas.ds_devices; + flag->init_tsens = MB_DATA->Coils.init_Tsens; + packStruct(MB_DATA, MAX_SENSE / 16); + if (_debug_init || MB_DATA->Coils.init_param) + { + _debug_init = 0; + + MB_DATA->Coils.init_param = 0; + for(int i = 0; i < hdallas.onewire->RomCnt; i++) + { + sens[i].set_temp = MB_DATA->HoldRegs.set_Temp[i]; + sens[i].hyst = MB_DATA->HoldRegs.set_hyst[i]; + } + + + + } + + return FuncOK; +}; + + +FuncStat value_control(void ) +{ + + for(int i = 0; i < hdallas.onewire->RomCnt; i++) + { + if (sens[i].temperature < sens[i].set_temp - sens[i].hyst) + + { + + MB_DATA.Coils.coils[0].all |= 1 << i; + MB_DATA.Coils.coils[1].all &= ~(1 << i); + + + } + + else + + if (sens[i].temperature > sens[i].set_temp + sens[i].hyst) + { + + MB_DATA.Coils.coils[0].all &= ~(1 << i); + MB_DATA.Coils.coils[1].all |= 1 << i; + + } + + + + } + + + return FuncOK; +} + + +uint16_t handle_valves(TEMP_TypeDef* temp_sense[MAX_SENSE] ) +{ + + if (temp_sense[0]->state == STATE_OPEN_VALVE) + { + GPIOC->ODR |= 1 << 14; + } + else if (temp_sense[0]->state == STATE_CLOSE_VALVE) + { + GPIOC->ODR &= ~(1 << 14); + } + + return 1; + +} + +void init_setpoint_all_T_sense(TEMP_TypeDef* temp_sense, int size_array) +{ + //ds_search_devices(); + for(int i = 0; i < size_array ; i++) + { + temp_sense[i].id[0] = roms[i][0] << 0 | roms[i][1] << 8 | roms[i][2] << 16 | roms[i][3] << 24; + temp_sense[i].id[1] = roms[i][4] << 0 | roms[i][5] << 8 | roms[i][6] << 16 | roms[i][7] << 24; + temp_sense[i].count = i + 1; + temp_sense[i].location = 1; + temp_sense[i].t_open = 22; + temp_sense[i].t_close = 18; + temp_sense[i].status_T_sense = 1; + } +} +/* USER CODE END 4 */ + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM3 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM3) + { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/onewire.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/onewire.c new file mode 100644 index 0000000..930cc6d --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/onewire.c @@ -0,0 +1,379 @@ +/** +****************************************************************************** +* @file onewire.c +* @brief This file includes the HAL/LL driver for OneWire devices +****************************************************************************** +*/ +#include "onewire.h" + +/** + * @brief The internal function is used to write bit + * @param OW OneWire HandleTypedef + * @param bit bit in 0 or 1 + */ +void OneWire_WriteBit(OneWire_t* OW, uint8_t bit) +{ + if(OW == NULL) + return; +#ifndef ONEWIRE_UART_H + __disable_irq(); + if(bit) + { + /* Set line low */ + OneWire_Pin_Level(OW, 0); + OneWire_Pin_Mode(OW, Output); + + /* Forming pulse */ + OneWire_Delay_us(ONEWIRE_WRITE_1_US); + + /* Release line (pull up line) */ + OneWire_Pin_Mode(OW, Input); + + /* Wait for 55 us and release the line */ + OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_1_US); + OneWire_Pin_Mode(OW, Input); + }else{ + /* Set line low */ + OneWire_Pin_Level(OW, 0); + OneWire_Pin_Mode(OW, Output); + + /* Forming pulse */ + OneWire_Delay_us(ONEWIRE_WRITE_0_US); + + /* Release line (pull up line) */ + OneWire_Pin_Mode(OW, Input); + + /* Wait for 5 us and release the line */ + OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_0_US); + OneWire_Pin_Mode(OW, Input); + } + __enable_irq(); +#else + OneWireUART_ProcessBit(onewire_uart, bit); +#endif +} + +/** + * @brief The function is used to read bit + * @retval bit + * @param OW OneWire HandleTypedef + */ +uint8_t OneWire_ReadBit(OneWire_t* OW) +{ + if(OW == NULL) + return 0; + + __disable_irq(); + uint8_t bit = 0; +#ifndef ONEWIRE_UART_H + /* Line low */ + OneWire_Pin_Level(OW, 0); + OneWire_Pin_Mode(OW, Output); + OneWire_Delay_us(ONEWIRE_READ_CMD_US); + + /* Release line */ + OneWire_Pin_Mode(OW, Input); + OneWire_Delay_us(ONEWIRE_READ_DELAY_US); + + /* Read line value */ + bit = OneWire_Pin_Read(OW); + + /* Wait 50us to complete 60us period */ + OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_READ_CMD_US - ONEWIRE_READ_DELAY_US); + __enable_irq(); +#else + bit = OneWireUART_ProcessBit(onewire_uart, 1); +#endif + /* Return bit value */ + return bit; +} + +/** + * @brief The function is used to write byte + * @param OW OneWire HandleTypedef + * @param byte byte to write + */ +void OneWire_WriteByte(OneWire_t* OW, uint8_t byte) +{ + if(OW == NULL) + return; + +#ifndef ONEWIRE_UART_H + uint8_t bit = 8; + /* Write 8 bits */ + while (bit--) { + /* LSB bit is first */ + OneWire_WriteBit(OW, byte & 0x01); + byte >>= 1; + } +#else + OneWireUART_ProcessByte(onewire_uart, byte); +#endif +} + +/** + * @brief The function is used to read byte + * @retval byte from device + * @param OW OneWire HandleTypedef + */ +uint8_t OneWire_ReadByte(OneWire_t* OW) +{ + if(OW == NULL) + return 0; + + uint8_t byte = 0; +#ifndef ONEWIRE_UART_H + uint8_t bit = 8; + while (bit--) { + byte >>= 1; + byte |= (OneWire_ReadBit(OW) << 7); + } +#else + byte = OneWireUART_ProcessByte(onewire_uart, 0xFF); +#endif + + return byte; +} + +/** + * @brief The function is used to reset device + * @retval respond from device + * @param OW OneWire HandleTypedef + */ +uint8_t OneWire_Reset(OneWire_t* OW) +{ + if(OW == NULL) + return 1; + +#ifndef ONEWIRE_UART_H + /* Line low, and wait 480us */ + OneWire_Pin_Level(OW, 0); + OneWire_Pin_Mode(OW, Output); + OneWire_Delay_us(ONEWIRE_RESET_PULSE_US); + + /* Release line and wait for 70us */ + OneWire_Pin_Mode(OW, Input); + OneWire_Delay_us(ONEWIRE_PRESENCE_WAIT_US); + + /* Check bit value */ + uint8_t rslt = OneWire_Pin_Read(OW); + + /* Delay for 410 us */ + OneWire_Delay_us(ONEWIRE_PRESENCE_DURATION_US); +#else + + uint8_t rslt = 0; + if(OneWireUART_Reset(onewire_uart) == HAL_OK) + rslt = 0; + else + rslt = 1; +#endif + + return rslt; +} + +/** + * @brief The function is used to search device + * @retval Search result + * @param OW OneWire HandleTypedef + */ +uint8_t OneWire_Search(OneWire_t* OW, uint8_t Cmd) +{ + if(OW == NULL) + return 0; + + uint8_t id_bit_number = 1; + uint8_t last_zero = 0; + uint8_t rom_byte_number = 0; + uint8_t search_result = 0; + uint8_t rom_byte_mask = 1; + uint8_t id_bit, cmp_id_bit, search_direction; + + /* if the last call was not the last one */ + if (!OW->LastDeviceFlag) + { + if (OneWire_Reset(OW)) + { + OW->LastDiscrepancy = 0; + OW->LastDeviceFlag = 0; + OW->LastFamilyDiscrepancy = 0; + return 0; + } + + // issue the search command + OneWire_WriteByte(OW, Cmd); + + // loop to do the search + do { + // read a bit and its complement + id_bit = OneWire_ReadBit(OW); + cmp_id_bit = OneWire_ReadBit(OW); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + { + break; + } else { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + { + search_direction = id_bit; // bit write value for search + } else { + /* if this discrepancy if before the Last Discrepancy + * on a previous next then pick the same as last time */ + if (id_bit_number < OW->LastDiscrepancy) + { + search_direction = ((OW->RomByte[rom_byte_number] & rom_byte_mask) > 0); + } else { + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == OW->LastDiscrepancy); + } + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) + { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) + { + OW->LastFamilyDiscrepancy = last_zero; + } + } + } + + /* set or clear the bit in the ROM byte rom_byte_number + * with mask rom_byte_mask */ + if (search_direction == 1) + { + OW->RomByte[rom_byte_number] |= rom_byte_mask; + } else { + OW->RomByte[rom_byte_number] &= ~rom_byte_mask; + } + + // serial number search direction write bit + OneWire_WriteBit(OW, search_direction); + + /* increment the byte counter id_bit_number and shift the + * mask rom_byte_mask */ + id_bit_number++; + rom_byte_mask <<= 1; + + /* if the mask is 0 then go to new SerialNum byte + * rom_byte_number and reset mask */ + if (rom_byte_mask == 0) + { + rom_byte_number++; + rom_byte_mask = 1; + } + } + } while (rom_byte_number < 8); /* loop until through all ROM bytes 0-7 + if the search was successful then */ + + if (!(id_bit_number < 65)) + { + /* search successful so set LastDiscrepancy, LastDeviceFlag, + * search_result */ + OW->LastDiscrepancy = last_zero; + // check for last device + if (OW->LastDiscrepancy == 0) { + OW->LastDeviceFlag = 1; + } + search_result = 1; + } + } + + /* if no device found then reset counters so next 'search' will be like a + * first */ + if (!search_result || !OW->RomByte[0]) + { + OW->LastDiscrepancy = 0; + OW->LastDeviceFlag = 0; + OW->LastFamilyDiscrepancy = 0; + search_result = 0; + } + + return search_result; +} + +/** + * @brief The function is used get ROM full address + * @param OW OneWire HandleTypedef + * @param ROM Pointer to device ROM + */ +void OneWire_GetDevRom(OneWire_t* OW, uint8_t *ROM) +{ + for (uint8_t i = 0; i < 8; i++) { + *(ROM + i) = OW->RomByte[i]; + } +} + +/** + * @brief The function is used to initialize OneWire Communication + * @param OW OneWire HandleTypedef + */ +void OneWire_Init(OneWire_t* OW) +{ + OneWire_Pin_Mode(OW, Output); + OneWire_Pin_Level(OW, 1); + OneWire_Delay_us(1000); + OneWire_Pin_Level(OW, 0); + OneWire_Delay_us(1000); + OneWire_Pin_Level(OW, 1); + OneWire_Delay_us(2000); + + /* Reset the search state */ + OW->LastDiscrepancy = 0; + OW->LastDeviceFlag = 0; + OW->LastFamilyDiscrepancy = 0; + OW->RomCnt = 0; +} + +/** + * @brief The function is used selected specific device ROM + * @param OW OneWire HandleTypedef + * @param ROM Pointer to device ROM + */ +void OneWire_MatchROM(OneWire_t* OW, uint8_t *ROM) +{ + OneWire_WriteByte(OW, ONEWIRE_CMD_MATCHROM); + + for (uint8_t i = 0; i < 8; i++) + { + OneWire_WriteByte(OW, *(ROM + i)); + } +} + +/** + * @brief The function is used to access to all ROM + * @param OW OneWire HandleTypedef + */ +void OneWire_Skip(OneWire_t* OW) +{ + OneWire_WriteByte(OW, ONEWIRE_CMD_SKIPROM); +} + +/** + * @brief The function is used check CRC + * @param Addr Pointer to address + * @param ROM Number of byte + */ +uint8_t OneWire_CRC8(uint8_t *Addr, uint8_t Len) +{ + uint8_t crc = 0; + uint8_t inbyte, i, mix; + + while (Len--) + { + inbyte = *Addr++; + + for (i = 8; i; i--) + { + mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + crc ^= (mix) ? 0x8C : 0; + inbyte >>= 1; + } + } + return crc; +} diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ow_port.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ow_port.c new file mode 100644 index 0000000..430dcec --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/ow_port.c @@ -0,0 +1,122 @@ +/** +****************************************************************************** +* @file ow_port.c +* @brief This file includes the driver for port for OneWire purposes +****************************************************************************** +*/ +#include "ow_port.h" +#include "onewire.h" +#include "tim.h" +uint32_t pin_pos = (OW_Pin_Numb < 8) ? (OW_Pin_Numb * 4) : ((OW_Pin_Numb - 8) * 4); + +/** + * @brief The internal function is used as gpio pin mode + * @param OW OneWire HandleTypedef + * @param Mode Input or Output + */ +void OneWire_Pin_Mode(OneWire_t* OW, PinMode Mode) +{ +#ifdef CMSIS_Driver +volatile uint32_t *config_reg = (OW_Pin_Numb < 8) ? &(OW->DataPort->CRL) : &(OW->DataPort->CRH); + // —брос текущих 4 бит (CNF + MODE) + *config_reg &= ~(0xF << pin_pos); + + if (Mode == Input) + { + // ¬ход с подт¤жкой или без Ц например, CNF = 0b01, MODE = 0b00 + // «десь устанавливаем вход с подт¤жкой: + *config_reg |= (0x8 << pin_pos); // CNF=10, MODE=00 (вход с подт¤жкой) + OW->DataPort->ODR |= (1 << OW_Pin_Numb); // ¬ключить подт¤жку вверх + } + else + { + // ¬ыход push-pull, 2 ћ√ц Ц MODE = 0b10, CNF = 0b00 + *config_reg |= (0x2 << pin_pos); + } +#else +#ifdef LL_Driver + if(Mode == Input) + { + LL_GPIO_SetPinMode(OW->DataPort, OW->DataPin, LL_GPIO_MODE_INPUT); + }else{ + LL_GPIO_SetPinMode(OW->DataPort, OW->DataPin, LL_GPIO_MODE_OUTPUT); + } +#else + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = OW->DataPin; + if(Mode == Input) + { + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + }else{ + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + } + HAL_GPIO_Init(OW->DataPort, &GPIO_InitStruct); +#endif +#endif +} + +/** + * @brief The internal function is used as gpio pin level + * @param OW OneWire HandleTypedef + * @param Mode Level: Set/High = 1, Reset/Low = 0 + */ +void OneWire_Pin_Level(OneWire_t* OW, uint8_t Level) +{ +#ifdef CMSIS_Driver + if (Level != GPIO_PIN_RESET) + { + OW->DataPort->BSRR = OW->DataPin; + } + else + { + OW->DataPort->BSRR = (uint32_t)OW->DataPin << 16u; + } +#else +#ifdef LL_Driver + if(Level == 1) + { + LL_GPIO_SetOutputPin(OW->DataPort, OW->DataPin); + }else{ + LL_GPIO_ResetOutputPin(OW->DataPort, OW->DataPin); + } +#else + HAL_GPIO_WritePin(OW->DataPort, OW->DataPin, Level); +#endif +#endif +} + +/** + * @brief The internal function is used to read data pin + * @retval Pin level status + * @param OW OneWire HandleTypedef + */ +uint8_t OneWire_Pin_Read(OneWire_t* OW) +{ +#ifdef CMSIS_Driver + return ((OW->DataPort->IDR & OW->DataPin) != 0x00U) ? 1 : 0; +#else +#ifdef LL_Driver + return ((OW->DataPort->IDR & OW->DataPin) != 0x00U) ? 1 : 0; +#else + return HAL_GPIO_ReadPin(OW->DataPort, OW->DataPin); +#endif +#endif +} + +uint32_t tim_1us_period = OW_TIM_1US_PERIOD; +void OneWire_Delay_us(uint32_t us) +{ + uint32_t ticks = us * tim_1us_period; + uint16_t start = OW_TIM->CNT; + uint32_t elapsed = 0; + uint16_t prev = start; + + while (elapsed < ticks) + { + uint16_t curr = OW_TIM->CNT; + uint16_t delta = (uint16_t)(curr - prev); // учЄт переполнени¤ + elapsed += delta; + prev = curr; + } +} diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/rtc.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/rtc.c new file mode 100644 index 0000000..20fdfc7 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/rtc.c @@ -0,0 +1,333 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file rtc.c + * @brief This file provides code for the configuration + * of the RTC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "rtc.h" + +/* USER CODE BEGIN 0 */ +#define RTC_BKP_CONFIGURED_MARKER 0x32A5U +#define RTC_BKP_MARKER_REG RTC_BKP_DR1 +#define RTC_BKP_YEAR_MONTH_REG RTC_BKP_DR2 +#define RTC_BKP_DATE_WEEKDAY_REG RTC_BKP_DR3 + +static uint8_t RTC_NormalizeYear(uint16_t year, uint8_t *normalized_year) +{ + if (year <= 99U) + { + *normalized_year = (uint8_t)year; + return 1U; + } + + if ((year >= 2000U) && (year <= 2099U)) + { + *normalized_year = (uint8_t)(year - 2000U); + return 1U; + } + + return 0U; +} + +static uint8_t RTC_IsLeapYearFull(uint16_t year) +{ + return (uint8_t)(((year % 4U) == 0U) && (((year % 100U) != 0U) || ((year % 400U) == 0U))); +} + +static uint8_t RTC_DaysInMonth(uint16_t year, uint8_t month) +{ + static const uint8_t days_in_month[] = { 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U }; + + if ((month == 0U) || (month > 12U)) + { + return 0U; + } + + if ((month == 2U) && RTC_IsLeapYearFull(year)) + { + return 29U; + } + + return days_in_month[month - 1U]; +} + +static uint8_t RTC_IsDateValid(uint16_t year, uint8_t month, uint8_t date) +{ + uint8_t normalized_year = 0U; + uint16_t full_year = year; + uint8_t max_day = 0U; + + if (RTC_NormalizeYear(year, &normalized_year) == 0U) + { + return 0U; + } + + if (year <= 99U) + { + full_year = 2000U + year; + } + + max_day = RTC_DaysInMonth(full_year, month); + return (uint8_t)((date >= 1U) && (date <= max_day)); +} + +static void RTC_SaveDateToBackup(const RTC_DateTypeDef *date) +{ + uint32_t year_month = (((uint32_t)date->Year) << 8U) | date->Month; + uint32_t date_weekday = (((uint32_t)date->Date) << 8U) | date->WeekDay; + + if ((HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_YEAR_MONTH_REG) != year_month) || + (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DATE_WEEKDAY_REG) != date_weekday)) + { + HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_YEAR_MONTH_REG, year_month); + HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DATE_WEEKDAY_REG, date_weekday); + } + + if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_MARKER_REG) != RTC_BKP_CONFIGURED_MARKER) + { + HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_MARKER_REG, RTC_BKP_CONFIGURED_MARKER); + } +} + +static uint8_t RTC_RestoreDateFromBackup(void) +{ + RTC_DateTypeDef restored_date = {0}; + uint32_t year_month = 0U; + uint32_t date_weekday = 0U; + + if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_MARKER_REG) != RTC_BKP_CONFIGURED_MARKER) + { + return 0U; + } + + year_month = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_YEAR_MONTH_REG); + date_weekday = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DATE_WEEKDAY_REG); + + restored_date.Year = (uint8_t)((year_month >> 8U) & 0xFFU); + restored_date.Month = (uint8_t)(year_month & 0xFFU); + restored_date.Date = (uint8_t)((date_weekday >> 8U) & 0xFFU); + restored_date.WeekDay = (uint8_t)(date_weekday & 0xFFU); + + if (RTC_IsDateValid(restored_date.Year, restored_date.Month, restored_date.Date) == 0U) + { + return 0U; + } + + if (restored_date.WeekDay > RTC_WEEKDAY_SATURDAY) + { + restored_date.WeekDay = RTC_WEEKDAY_MONDAY; + } + + hrtc.DateToUpdate = restored_date; + return 1U; +} + +/* USER CODE END 0 */ + +RTC_HandleTypeDef hrtc; + +/* RTC init function */ +void MX_RTC_Init(void) +{ + + /* USER CODE BEGIN RTC_Init 0 */ + + /* USER CODE END RTC_Init 0 */ + + RTC_TimeTypeDef sTime = {0}; + RTC_DateTypeDef DateToUpdate = {0}; + + /* USER CODE BEGIN RTC_Init 1 */ + uint8_t rtc_backup_ready = 0U; + + /* USER CODE END RTC_Init 1 */ + + /** Initialize RTC Only + */ + hrtc.Instance = RTC; + hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND; + hrtc.Init.OutPut = RTC_OUTPUTSOURCE_SECOND; + if (HAL_RTC_Init(&hrtc) != HAL_OK) + { + Error_Handler(); + } + + /* USER CODE BEGIN Check_RTC_BKUP */ + rtc_backup_ready = RTC_RestoreDateFromBackup(); + + /* USER CODE END Check_RTC_BKUP */ + + /** Initialize RTC and set the Time and Date + */ + if (rtc_backup_ready == 0U) + { + sTime.Hours = 0U; + sTime.Minutes = 0U; + sTime.Seconds = 0U; + + if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) + { + Error_Handler(); + } + DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; + DateToUpdate.Month = RTC_MONTH_JANUARY; + DateToUpdate.Date = 1U; + DateToUpdate.Year = 0U; + + if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK) + { + Error_Handler(); + } + + RTC_SaveDateToBackup(&DateToUpdate); + } + /* USER CODE BEGIN RTC_Init 2 */ + + /* USER CODE END RTC_Init 2 */ + +} + +void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle) +{ + + if(rtcHandle->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspInit 0 */ + + /* USER CODE END RTC_MspInit 0 */ + HAL_PWR_EnableBkUpAccess(); + /* Enable BKP CLK enable for backup registers */ + __HAL_RCC_BKP_CLK_ENABLE(); + /* RTC clock enable */ + __HAL_RCC_RTC_ENABLE(); + + /* RTC interrupt Init */ + HAL_NVIC_SetPriority(RTC_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(RTC_IRQn); + /* USER CODE BEGIN RTC_MspInit 1 */ + + /* USER CODE END RTC_MspInit 1 */ + } +} + +void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle) +{ + + if(rtcHandle->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspDeInit 0 */ + + /* USER CODE END RTC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RTC_DISABLE(); + + /* RTC interrupt Deinit */ + HAL_NVIC_DisableIRQ(RTC_IRQn); + /* USER CODE BEGIN RTC_MspDeInit 1 */ + + /* USER CODE END RTC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ +uint8_t RTC_CalendarIsValid(const RTC_CalendarTypeDef *calendar) +{ + if (calendar == NULL) + { + return 0U; + } + + return (uint8_t)((calendar->hours <= 23U) && + (calendar->minutes <= 59U) && + (calendar->seconds <= 59U) && + RTC_IsDateValid(calendar->year, calendar->month, calendar->date)); +} + +HAL_StatusTypeDef RTC_CalendarGet(RTC_CalendarTypeDef *calendar) +{ + RTC_TimeTypeDef time = {0}; + RTC_DateTypeDef date = {0}; + + if (calendar == NULL) + { + return HAL_ERROR; + } + + if (HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN) != HAL_OK) + { + return HAL_ERROR; + } + + if (HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN) != HAL_OK) + { + return HAL_ERROR; + } + + RTC_SaveDateToBackup(&date); + + calendar->hours = time.Hours; + calendar->minutes = time.Minutes; + calendar->seconds = time.Seconds; + calendar->date = date.Date; + calendar->month = date.Month; + calendar->year = 2000U + date.Year; + calendar->weekday = date.WeekDay; + + return HAL_OK; +} + +HAL_StatusTypeDef RTC_CalendarSet(const RTC_CalendarTypeDef *calendar) +{ + RTC_TimeTypeDef time = {0}; + RTC_DateTypeDef date = {0}; + uint8_t normalized_year = 0U; + + if ((calendar == NULL) || (RTC_CalendarIsValid(calendar) == 0U)) + { + return HAL_ERROR; + } + + if (RTC_NormalizeYear(calendar->year, &normalized_year) == 0U) + { + return HAL_ERROR; + } + + time.Hours = (uint8_t)calendar->hours; + time.Minutes = (uint8_t)calendar->minutes; + time.Seconds = (uint8_t)calendar->seconds; + + date.Year = normalized_year; + date.Month = (uint8_t)calendar->month; + date.Date = (uint8_t)calendar->date; + date.WeekDay = RTC_WEEKDAY_MONDAY; + + if (HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BIN) != HAL_OK) + { + return HAL_ERROR; + } + + if (HAL_RTC_SetDate(&hrtc, &date, RTC_FORMAT_BIN) != HAL_OK) + { + return HAL_ERROR; + } + + RTC_SaveDateToBackup(&date); + + return HAL_OK; +} + +/* USER CODE END 1 */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/spi.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/spi.c new file mode 100644 index 0000000..0b82c16 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/spi.c @@ -0,0 +1,124 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.c + * @brief This file provides code for the configuration + * of the SPI instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "spi.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +SPI_HandleTypeDef hspi1; + +/* SPI1 init function */ +void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ + +} + +void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(spiHandle->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + /* SPI1 clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PB3 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_4; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + __HAL_AFIO_REMAP_SPI1_ENABLE(); + + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_MspInit 1 */ + } +} + +void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) +{ + + if(spiHandle->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PB3 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5); + + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_msp.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_msp.c new file mode 100644 index 0000000..4a8307a --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_msp.c @@ -0,0 +1,86 @@ +/** + ****************************************************************************** + * @file Templates/Src/stm32f4xx_hal_msp.c + * @author MCD Application Team + * @brief HAL MSP module. + * + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + This file is generated automatically by STM32CubeMX and eventually modified + by the user + + @endverbatim + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL_MSP + * @brief HAL MSP module. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HAL_MSP_Private_Functions + * @{ + */ + +/** + * @brief Initializes the Global MSP. + * @param None + * @retval None + */ +void HAL_MspInit(void) +{ + /* NOTE : This function is generated automatically by STM32CubeMX and eventually + modified by the user + */ +} + +/** + * @brief DeInitializes the Global MSP. + * @param None + * @retval None + */ +void HAL_MspDeInit(void) +{ + /* NOTE : This function is generated automatically by STM32CubeMX and eventually + modified by the user + */ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_timebase_tim.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_timebase_tim.c new file mode 100644 index 0000000..affb884 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_hal_timebase_tim.c @@ -0,0 +1,177 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_timebase_tim_template.c + * @author MCD Application Team + * @brief HAL time base based on the hardware TIM Template. + * + * This file overrides the native HAL time base functions (defined as weak) + * the TIM time base: + * + Intializes the TIM peripheral generate a Period elapsed Event each 1ms + * + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms + * + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup HAL_TimeBase_TIM + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +TIM_HandleTypeDef TimHandle; +/* Private function prototypes -----------------------------------------------*/ +void TIM6_DAC_IRQHandler(void); +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief This function configures the TIM6 as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority) +{ + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock, uwAPB1Prescaler = 0U; + uint32_t uwPrescalerValue = 0U; + uint32_t pFLatency; + HAL_StatusTypeDef status; + + /* Enable TIM6 clock */ + __HAL_RCC_TIM6_CLK_ENABLE(); + + /* Get clock configuration */ + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + + /* Get APB1 prescaler */ + uwAPB1Prescaler = clkconfig.APB1CLKDivider; + + /* Compute TIM6 clock */ + if (uwAPB1Prescaler == RCC_HCLK_DIV1) + { + uwTimclock = HAL_RCC_GetPCLK1Freq(); + } + else + { + uwTimclock = 2 * HAL_RCC_GetPCLK1Freq(); + } + + /* Compute the prescaler value to have TIM6 counter clock equal to 1MHz */ + uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U); + + /* Initialize TIM6 */ + TimHandle.Instance = TIM6; + + /* Initialize TIMx peripheral as follow: + + Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base. + + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. + + ClockDivision = 0 + + Counter direction = Up + */ + TimHandle.Init.Period = (1000000U / 1000U) - 1U; + TimHandle.Init.Prescaler = uwPrescalerValue; + TimHandle.Init.ClockDivision = 0U; + TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + status = HAL_TIM_Base_Init(&TimHandle); + if (status == HAL_OK) + { + /* Start the TIM time Base generation in interrupt mode */ + status = HAL_TIM_Base_Start_IT(&TimHandle); + if (status == HAL_OK) + { + /* Enable the TIM6 global Interrupt */ + HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); + + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + /* Enable the TIM6 global Interrupt */ + HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority, 0); + uwTickPrio = TickPriority; + } + else + { + status = HAL_ERROR; + } + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Suspend Tick increment. + * @note Disable the tick increment by disabling TIM6 update interrupt. + * @retval None + */ +void HAL_SuspendTick(void) +{ + /* Disable TIM6 update Interrupt */ + __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE); +} + +/** + * @brief Resume Tick increment. + * @note Enable the tick increment by Enabling TIM6 update interrupt. + * @retval None + */ +void HAL_ResumeTick(void) +{ + /* Enable TIM6 Update interrupt */ + __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE); +} + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM6 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + HAL_IncTick(); +} + +/** + * @brief This function handles TIM interrupt request. + * @retval None + */ +void TIM6_DAC_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&TimHandle); +} + +/** + * @} + */ + +/** + * @} + */ + + diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_it.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_it.c new file mode 100644 index 0000000..5b2175b --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/stm32f4xx_it.c @@ -0,0 +1,178 @@ +/** + ****************************************************************************** + * @file Templates/Src/stm32f4xx_it.c + * @author MCD Application Team + * @brief Main Interrupt Service Routines. + * This file provides template for all exceptions handler and + * peripherals interrupt service routine. + * + * @note modified by ARM + * The modifications allow to use this file as User Code Template + * within the Device Family Pack. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f4xx_it.h" + +#ifdef _RTE_ +#include "RTE_Components.h" /* Component selection */ +#endif + +/** @addtogroup STM32F4xx_HAL_Examples + * @{ + */ + +/** @addtogroup Templates + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + * @param None + * @retval None + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard Fault exception. + * @param None + * @retval None + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Memory Manage exception. + * @param None + * @retval None + */ +void MemManage_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +#ifndef RTE_CMSIS_RTOS2_RTX5 +void SVC_Handler(void) +{ +} +#endif + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +#ifndef RTE_CMSIS_RTOS2_RTX5 +void PendSV_Handler(void) +{ +} +#endif + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +#ifndef RTE_CMSIS_RTOS2_RTX5 +void SysTick_Handler(void) +{ + HAL_IncTick(); +} +#endif + +/******************************************************************************/ +/* STM32F4xx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32f4xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles PPP interrupt request. + * @param None + * @retval None + */ +/*void PPP_IRQHandler(void) +{ +}*/ + +/** + * @} + */ + +/** + * @} + */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/system_stm32f4xx.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/system_stm32f4xx.c new file mode 100644 index 0000000..3bd40f7 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/system_stm32f4xx.c @@ -0,0 +1,747 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + + +#include "stm32f4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) +/* #define DATA_IN_ExtSRAM */ +#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\ + STM32F412Zx || STM32F412Vx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +/* #define DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\ + STM32F479xx */ + +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate the vector table + anywhere in Flash or Sram, else the vector table is kept at the automatic + remap of boot address selected */ +/* #define USER_VECT_TAB_ADDRESS */ + +#if defined(USER_VECT_TAB_ADDRESS) +/*!< Uncomment the following line if you need to relocate your vector Table + in Sram else user remap will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +#endif /* VECT_TAB_SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = 16000000; +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + + /* Configure the Vector Table location -------------------------------------*/ +#if defined(USER_VECT_TAB_ADDRESS) + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that HSE_VALUE + * is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM) +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; + + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */ + RCC->AHB1ENR |= 0x000001F8; + + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + FMC_Bank5_6->SDCR[0] = 0x000019E4; + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ + FMC_Bank5_6->SDCMR = 0x00000073; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ + FMC_Bank5_6->SDCMR = 0x00046014; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ + + (void)(tmp); +} +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ +#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#if defined (DATA_IN_ExtSDRAM) + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + +#if defined(STM32F446xx) + /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface + clock */ + RCC->AHB1ENR |= 0x0000007D; +#else + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB1ENR |= 0x000001F8; +#endif /* STM32F446xx */ + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + +#if defined(STM32F446xx) + /* Connect PAx pins to FMC Alternate function */ + GPIOA->AFR[0] |= 0xC0000000; + GPIOA->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOA->MODER |= 0x00008000; + /* Configure PDx pins speed to 50 MHz */ + GPIOA->OSPEEDR |= 0x00008000; + /* Configure PDx pins Output type to push-pull */ + GPIOA->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOA->PUPDR |= 0x00000000; + + /* Connect PCx pins to FMC Alternate function */ + GPIOC->AFR[0] |= 0x00CC0000; + GPIOC->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOC->MODER |= 0x00000A00; + /* Configure PDx pins speed to 50 MHz */ + GPIOC->OSPEEDR |= 0x00000A00; + /* Configure PDx pins Output type to push-pull */ + GPIOC->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOC->PUPDR |= 0x00000000; +#endif /* STM32F446xx */ + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xA02A000A; + /* Configure PDx pins speed to 50 MHz */ + GPIOD->OSPEEDR = 0xA02A000A; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 50 MHz */ + GPIOE->OSPEEDR = 0xAAAA800A; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + /* Configure and enable SDRAM bank1 */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCR[0] = 0x00001954; +#else + FMC_Bank5_6->SDCR[0] = 0x000019E4; +#endif /* STM32F446xx */ + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x000000F3; +#else + FMC_Bank5_6->SDCMR = 0x00000073; +#endif /* STM32F446xx */ + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x00044014; +#else + FMC_Bank5_6->SDCMR = 0x00046014; +#endif /* STM32F446xx */ + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; +#if defined(STM32F446xx) + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1)); +#else + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); +#endif /* STM32F446xx */ + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); +#endif /* DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) + +#if defined(DATA_IN_ExtSRAM) +/*-- GPIOs Configuration -----------------------------------------------------*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA000AAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x000000C0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00085AAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000CAFFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FMC/FSMC Configuration --------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\ + || defined(STM32F412Zx) || defined(STM32F412Vx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN); + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF; +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */ + +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ + STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */ + (void)(tmp); +} +#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/tim.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/tim.c new file mode 100644 index 0000000..5f0525b --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/tim.c @@ -0,0 +1,262 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "tim.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim2; +TIM_HandleTypeDef htim4; + +/* TIM1 init function */ +void MX_TIM1_Init(void) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + htim1.Instance = TIM1; + htim1.Init.Prescaler = 0; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 65535; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + +} +/* TIM2 init function */ +void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + htim2.Instance = TIM2; + htim2.Init.Prescaler = 7199; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 65535; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + +} + +/* TIM4 init function */ +void MX_TIM4_Init(void) +{ + + /* USER CODE BEGIN TIM4_Init 0 */ + + /* USER CODE END TIM4_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM4_Init 1 */ + + /* USER CODE END TIM4_Init 1 */ + htim4.Instance = TIM4; + htim4.Init.Prescaler = 7199; + htim4.Init.CounterMode = TIM_COUNTERMODE_UP; + htim4.Init.Period = 65535; + htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim4) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM4_Init 2 */ + + /* USER CODE END TIM4_Init 2 */ + +} + +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspInit 0 */ + + /* USER CODE END TIM1_MspInit 0 */ + /* TIM1 clock enable */ + __HAL_RCC_TIM1_CLK_ENABLE(); + + /* TIM1 interrupt Init */ + HAL_NVIC_SetPriority(TIM1_BRK_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM1_BRK_IRQn); + HAL_NVIC_SetPriority(TIM1_UP_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); + HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM1_TRG_COM_IRQn); + HAL_NVIC_SetPriority(TIM1_CC_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + /* USER CODE BEGIN TIM1_MspInit 1 */ + + /* USER CODE END TIM1_MspInit 1 */ + } + else if(tim_baseHandle->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspInit 0 */ + + /* USER CODE END TIM2_MspInit 0 */ + /* TIM2 clock enable */ + __HAL_RCC_TIM2_CLK_ENABLE(); + + /* TIM2 interrupt Init */ + HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM2_IRQn); + /* USER CODE BEGIN TIM2_MspInit 1 */ + + /* USER CODE END TIM2_MspInit 1 */ + } + else if(tim_baseHandle->Instance==TIM4) + { + /* USER CODE BEGIN TIM4_MspInit 0 */ + + /* USER CODE END TIM4_MspInit 0 */ + /* TIM4 clock enable */ + __HAL_RCC_TIM4_CLK_ENABLE(); + + /* TIM4 interrupt Init */ + HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM4_IRQn); + /* USER CODE BEGIN TIM4_MspInit 1 */ + + /* USER CODE END TIM4_MspInit 1 */ + } +} + +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspDeInit 0 */ + + /* USER CODE END TIM1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM1_CLK_DISABLE(); + + /* TIM1 interrupt Deinit */ + HAL_NVIC_DisableIRQ(TIM1_BRK_IRQn); + HAL_NVIC_DisableIRQ(TIM1_UP_IRQn); + HAL_NVIC_DisableIRQ(TIM1_TRG_COM_IRQn); + HAL_NVIC_DisableIRQ(TIM1_CC_IRQn); + /* USER CODE BEGIN TIM1_MspDeInit 1 */ + + /* USER CODE END TIM1_MspDeInit 1 */ + } + else if(tim_baseHandle->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspDeInit 0 */ + + /* USER CODE END TIM2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM2_CLK_DISABLE(); + + /* TIM2 interrupt Deinit */ + HAL_NVIC_DisableIRQ(TIM2_IRQn); + /* USER CODE BEGIN TIM2_MspDeInit 1 */ + + /* USER CODE END TIM2_MspDeInit 1 */ + } + else if(tim_baseHandle->Instance==TIM4) + { + /* USER CODE BEGIN TIM4_MspDeInit 0 */ + + /* USER CODE END TIM4_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM4_CLK_DISABLE(); + + /* TIM4 interrupt Deinit */ + HAL_NVIC_DisableIRQ(TIM4_IRQn); + /* USER CODE BEGIN TIM4_MspDeInit 1 */ + + /* USER CODE END TIM4_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/usart.c b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/usart.c new file mode 100644 index 0000000..d8f0593 --- /dev/null +++ b/john103C6T6NewVer/john103C6T6_JZ-F407VET6_F4/Core/Src/usart.c @@ -0,0 +1,205 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.c + * @brief This file provides code for the configuration + * of the USART instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 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 "usart.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +UART_HandleTypeDef huart1; +UART_HandleTypeDef huart2; + +/* USART1 init function */ + +void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + /* USER CODE BEGIN USART1_Init 1 */ + huart1.ReceptionType=HAL_UART_RECEPTION_TOIDLE; + /* USER CODE END USART1_Init 1 */ + huart1.Instance = USART1; + huart1.Init.BaudRate = 115200; + huart1.Init.WordLength = UART_WORDLENGTH_8B; + huart1.Init.StopBits = UART_STOPBITS_1; + huart1.Init.Parity = UART_PARITY_NONE; + huart1.Init.Mode = UART_MODE_TX_RX; + huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart1.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ + +} + +/* USART2 init function */ + +void MX_USART2_UART_Init(void) +{ + + /* USER CODE BEGIN USART2_Init 0 */ + + /* USER CODE END USART2_Init 0 */ + + /* USER CODE BEGIN USART2_Init 1 */ + huart2.ReceptionType = HAL_UART_RECEPTION_TOIDLE; + /* USER CODE END USART2_Init 1 */ + huart2.Instance = USART2; + huart2.Init.BaudRate = 115200; + huart2.Init.WordLength = UART_WORDLENGTH_8B; + huart2.Init.StopBits = UART_STOPBITS_1; + huart2.Init.Parity = UART_PARITY_NONE; + huart2.Init.Mode = UART_MODE_TX_RX; + huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart2.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart2) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART2_Init 2 */ + + /* USER CODE END USART2_Init 2 */ + +} + +void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(uartHandle->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspInit 0 */ + + /* USER CODE END USART1_MspInit 0 */ + /* USART1 clock enable */ + __HAL_RCC_USART1_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**USART1 GPIO Configuration + PB6 ------> USART1_TX + PB7 ------> USART1_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + __HAL_AFIO_REMAP_USART1_ENABLE(); + + /* USART1 interrupt Init */ + HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(USART1_IRQn); + /* USER CODE BEGIN USART1_MspInit 1 */ + + /* USER CODE END USART1_MspInit 1 */ + } + else if(uartHandle->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspInit 0 */ + + /* USER CODE END USART2_MspInit 0 */ + /* USART2 clock enable */ + __HAL_RCC_USART2_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USART2 interrupt Init */ + HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(USART2_IRQn); + /* USER CODE BEGIN USART2_MspInit 1 */ + + /* USER CODE END USART2_MspInit 1 */ + } +} + +void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) +{ + + if(uartHandle->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspDeInit 0 */ + + /* USER CODE END USART1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART1_CLK_DISABLE(); + + /**USART1 GPIO Configuration + PB6 ------> USART1_TX + PB7 ------> USART1_RX + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7); + + /* USART1 interrupt Deinit */ + HAL_NVIC_DisableIRQ(USART1_IRQn); + /* USER CODE BEGIN USART1_MspDeInit 1 */ + + /* USER CODE END USART1_MspDeInit 1 */ + } + else if(uartHandle->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspDeInit 0 */ + + /* USER CODE END USART2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART2_CLK_DISABLE(); + + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); + + /* USART2 interrupt Deinit */ + HAL_NVIC_DisableIRQ(USART2_IRQn); + /* USER CODE BEGIN USART2_MspDeInit 1 */ + + /* USER CODE END USART2_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */