CAN Protocol

This commit is contained in:
2026-03-03 18:30:20 +03:00
parent 34f14b6b25
commit 5d08a6e026
276 changed files with 15838 additions and 226576 deletions

52
Core/Inc/can.h Normal file
View File

@@ -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) 2026 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__ */

49
Core/Inc/gpio.h Normal file
View File

@@ -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) 2026 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__ */

View File

@@ -31,7 +31,7 @@ extern "C" {
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "requester.h"
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/

343
Core/Inc/requester.h Normal file
View File

@@ -0,0 +1,343 @@
#ifndef _requester
#define _requester
#include "main.h"
#include "can.h"
#include "rtc.h"
#include "tim.h"
#define _DEMO
#define ONLINE 1;
#define OFFLINE 0;
// TIM defines
#define TIM_REQUESTER_Prescaler 64000
//CAN Settings
#define _HCAN hcan
//CAN Speed
#define CAN_SPEED_PRSC_1000KB 2
#define CAN_SPEED_PRSC_500KB 4
#define CAN_SPEED_PRSC_250KB 8
#define CAN_SPEED_PRSC_125KB 16
#define CAN_SPEED_PRSC_50KB 40
#define CAN_CURRENT_SPEED CAN_SPEED_PRSC_250KB
//CAN Filter
#define ID_MAIN_DEVICE 0x000
#define CURRENT_TYPE_DEVICE 0b001
#define CURRENT_ID_DEVICE 0b0010
#define CAN_IDE_32 0b00000100 // Для 32-х битного масштаба
#define CAN_DATA_TYPE_FILTER 0x1F000000
#define CAN_DEVICE_ID_FILTER 0x000000FF
#define CAN_SENSOR_TYPE_FILTER 0x00F80000
#define CAN_SENSOR_ID_FILTER 0x0007FF00
typedef union{
struct bitfield{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
}Bitfield;
char AllBit;
}Byte;
/**
* @brief HAL Status structures definition
*/
typedef enum
{
CRR_OK = 0x00U,
CRR_ERROR = 0x01U,
CRR_BUSY = 0x02U,
CRR_TIMEOUT = 0x03U
} CRR_Status;
_Bool IsLeapYear(uint8_t year);
#define COUNT_OF_MODBUS_SECTIONS 1
#define MODBUS_SECTION_MASK 0
#define MODBUS_SECTION_FILTER 1
#define SensorToModbusRegister(SensorType, SensorID) SensorType << 11 | SensorID
#define HighByteOfWord(WORD) (WORD>>8)&0xFF
#define LowByteOfWord(WORD) WORD&0xFF
//Priority level
#define PRIORITY_CRITICAL 0
#define PRIORITY_STANDARD 1
//Route mode
#define ROUTE_MASTER 1
#define ROUTE_SLAVE 0
//Data Types
#define DATA_TYPE_BROADCAST 0b0000
#define DATA_TYPE_DISCRETE 0b0001
#define DATA_TYPE_ANALOG 0b0010
#define DATA_TYPE_MODBUS_COIL 0b0011
#define DATA_TYPE_GENERAL_ADDRESS_SPACE 0b0100
#define DATA_TYPE_MODBUS_DISCRETE 0b0101
#define DATA_TYPE_MODBUS_HOLDING 0b0110
#define DATA_TYPE_MODBUS_INPUT 0b0111
#define DATA_TYPE_ERROR 0b1000
#define DATA_TYPE_PULSE 0b1111
//Sensor Types for DATA_TYPE_BROADCAST
#define SENSOR_TYPE_BROADCAST_STATUS 0b000000000000
#define SENSOR_TYPE_BROADCAST_ONOFF 0b000000000001
#define SENSOR_TYPE_BROADCAST_RESTARTDEVICE 0b000000000010
#define SENSOR_TYPE_BROADCAST_RTCSETUP 0b000000000011
//Sensor Types for DATA_TYPE_DISCRETE
#define SENSOR_TYPE_DISCRETE_ACCIDENT 0b0000
#define SENSOR_TYPE_DISCRETE_WARNING 0b0001
#define SENSOR_TYPE_DISCRETE_CONTROL_SIGNALS 0b0010
#define SENSOR_TYPE_DISCRETE_FLAGS 0b0011
#define SENSOR_TYPE_DISCRETE_RESET 0b0100
#define SENSOR_TYPE_DISCRETE_CHANGE_MODE 0b0101
#define SENSOR_TYPE_DISCRETE_REQUEST_LIST_OF_PARAMETERS 0b0110
//Sensor Types for DATA_TYPE_ANALOG
#define SENSOR_TYPE_ANALOG_UNIVERSAL 0b0000
#define SENSOR_TYPE_ANALOG_USTAVKI 0b0001
#define SENSOR_TYPE_ANALOG_U 0b0010
#define SENSOR_TYPE_ANALOG_I 0b0011
#define SENSOR_TYPE_ANALOG_T 0b0100
//Error Code
#define NONEXISTENT_ELEMENT 0x01
#define HighIdFilter(x) x<<24
struct controlflags{
unsigned IsPulse:1;
unsigned IsRtrMode:1;
};
//Device settings
typedef union{
struct msgBody_Broadcast{
unsigned Page:4;
unsigned BroadcastType:12;
}Fields;
unsigned Body:16;
}msgBroadcastType;
typedef union{
struct msgBody_Discrete{
unsigned Body:12;
unsigned Type:4;
}Fields;
unsigned Body:16;
}msgDiscreteType;
typedef union{
struct msgBody_Analog{
unsigned SensorID:12;
unsigned SensorType:4;
}Fields;
unsigned Body:16;
}msgAnalogType;
typedef union{
struct msgBody_Modbus{
unsigned RegCount:4;
unsigned StrAdr:12;
}Fields;
unsigned Body:16;
}msgModbusType;
typedef union{
struct msgBody_Error{
unsigned ErrorCode:8;
unsigned Info:8;
}Fields;
unsigned Body:16;
}msgErrorType;
typedef union{
struct extID_Fields{
unsigned MsgBody:16;
unsigned MsgType:4;
unsigned DeviceID:4;
unsigned DeviceType:3;
unsigned Route:1;
unsigned Priority:1;
}Fields;
unsigned int BitAll:29;
}extID;
// typedef union{
// struct extID_Fields{
// union{
// msgBodyBroadcast Broadcast;
// msgBodyDiscrete Discrete;
// msgBodyAnalog Analog;
// msgBodyModbus Modbus;
// msgBodyError Error;
// unsigned Body:16;
// }Msg;
// unsigned MsgType:4;
// unsigned DeviceID:4;
// unsigned DeviceType:3;
// unsigned Route:1;
// unsigned Priority:1;
// }Fields;
// unsigned int BitAll:29;
//}extID;
struct device{
unsigned Status:1;
extID ExtID;
unsigned TimeFromLastPulse;
unsigned LastPulseStep;
};
struct data{
struct T_sens{
char info[256];
unsigned SensID;
unsigned AvrgValue;
unsigned LastTenValues[10];
}TS;
struct U_sens{
char info[256];
unsigned SensID;
unsigned AvrgValue;
unsigned LastTenValues[10];
}Uu, Uv, Uw;
struct I_sens{
char info[256];
unsigned SensID;
unsigned AvrgValue;
unsigned LastTenValues[10];
}Iu, Iv, Iw;
};
struct received_request{
extID RequestedExtID;
unsigned RequestedDLC;
uint8_t RxData[8];
//DATA_TYPE_DISCRETIC
union discreticflags{
struct discretictype{
unsigned Request_Accident:1;
unsigned Request_Warning:1;
unsigned Request_Control_Signals:1;
unsigned Request_Flags:1;
unsigned Request_Reset:1;
unsigned Request_List_of_Parameters:1;
}DiscreticType;
unsigned AllFlags:5;
}DiscreticFlags;
//DATA_TYPE_BROADCAST
union broadcastflags{
struct broadcasttype{
unsigned Request_Status:1;
unsigned Request_OnOff:1;
unsigned Request_RTC_Setup:1;
}BroadcastType;
unsigned AllFlags:3;
}BroadcastFlags;
//DATA_TYPE_ANALOG
union analogflags{
struct analogtype{
unsigned Request_Universal_Sens:1;
unsigned Request_U_Sens:1;
unsigned Request_I_Sens:1;
unsigned Request_T_Sens:1;
}AnalogType;
unsigned AllFlags:4;
}AnalogFlags;
//DATA_TYPE_MODBUS
union modbusflags{
struct modbustype{
unsigned Coil:1;
unsigned Discrete:1;
unsigned Holding:1;
unsigned Input:1;
}ModbusType;
unsigned AllFlags:4;
}ModbusFlags;
union sensor_To_Modbus{
struct modbus{
unsigned Count:8;
unsigned StrAdr:8;
}Modbus;
unsigned Sensor:16;
}SensorToModbus;
unsigned ModbusFlag:1;
};
#define CAN_RX_BUFFER_SIZE 128
struct RXMsg{
struct INFO{
unsigned EXT:1;
unsigned RTR:1;
}info;
extID eID;
uint16_t DLC;
uint8_t Data[8];
};
uint16_t AvailableCanRxMsg(void);
void REQUESTER_Init(void);
void REQUESTER_MainWhile(void);
void Boot_SystemClock_Config(void);
CRR_Status REQUESTER_AnalogProcessing(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToAnalogUniversal(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToAnalogUSTAVKI(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToAnalogUSens(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToAnalogISens(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToAnalogTSens(struct RXMsg _rxMsg);
CRR_Status REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToBroadcastStatus(struct RXMsg _rxMsg);
void CanRequestToBroadcastOnOff(struct RXMsg _rxMsg);
void CanRequestToBroadcastRestart(struct RXMsg _rxMsg);
void CanRequestToBroadcastRtcSetup(struct RXMsg _rxMsg);
CRR_Status REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg);
void CanRequestToDiscreteAccident(struct RXMsg _rxMsg);
void CanRequestToDiscreteWarning(struct RXMsg _rxMsg);
void CanRequestToDiscreteControlSignals(struct RXMsg _rxMsg);
void CanRequestToDiscreteFlags(struct RXMsg _rxMsg);
void CanRequestToDiscreteReset(struct RXMsg _rxMsg);
void CanRequestToDiscreteChangeMode(struct RXMsg _rxMsg);
void CanRequestToDiscreteRequestListOfParameters(struct RXMsg _rxMsg);
void REQUESTER_GeneralAddressSpace_Answer(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestError(struct RXMsg _rxMsg);
CRR_Status REQUESTER_ModbusProcessing(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToModbusCoil(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToModbusDiscrete(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToModbusHolding(struct RXMsg _rxMsg);
HAL_StatusTypeDef CanRequestToModbusInput(struct RXMsg _rxMsg);
void REQUESTER_RTC_SYNC(uint8_t *data);
void REQUESTER_Pulse_TIM_Handler(void);
void Boot_SystemClock_Config(void);
void REQUESTER_CAN_FILTERS(void);
#endif

52
Core/Inc/rtc.h Normal file
View File

@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file rtc.h
* @brief This file contains all the function prototypes for
* the rtc.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 __RTC_H__
#define __RTC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern RTC_HandleTypeDef hrtc;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_RTC_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __RTC_H__ */

View File

@@ -36,7 +36,7 @@
#define HAL_MODULE_ENABLED
/*#define HAL_ADC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
/*#define HAL_CAN_MODULE_ENABLED */
#define HAL_CAN_MODULE_ENABLED
/*#define HAL_CAN_LEGACY_MODULE_ENABLED */
/*#define HAL_CEC_MODULE_ENABLED */
/*#define HAL_CORTEX_MODULE_ENABLED */
@@ -45,7 +45,7 @@
/*#define HAL_DMA_MODULE_ENABLED */
/*#define HAL_ETH_MODULE_ENABLED */
/*#define HAL_FLASH_MODULE_ENABLED */
/*#define HAL_GPIO_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
/*#define HAL_I2C_MODULE_ENABLED */
/*#define HAL_I2S_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */
@@ -57,14 +57,14 @@
/*#define HAL_HCD_MODULE_ENABLED */
/*#define HAL_PWR_MODULE_ENABLED */
/*#define HAL_RCC_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */
#define HAL_RTC_MODULE_ENABLED
/*#define HAL_SD_MODULE_ENABLED */
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_SDRAM_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
/*#define HAL_SPI_MODULE_ENABLED */
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_TIM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
/*#define HAL_UART_MODULE_ENABLED */
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */

View File

@@ -55,6 +55,11 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void USB_HP_CAN1_TX_IRQHandler(void);
void USB_LP_CAN1_RX0_IRQHandler(void);
void CAN1_RX1_IRQHandler(void);
void CAN1_SCE_IRQHandler(void);
void TIM4_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

52
Core/Inc/tim.h Normal file
View File

@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file tim.h
* @brief This file contains all the function prototypes for
* the tim.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 __TIM_H__
#define __TIM_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern TIM_HandleTypeDef htim4;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_TIM4_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __TIM_H__ */

134
Core/Src/can.c Normal file
View File

@@ -0,0 +1,134 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file can.c
* @brief This file provides code for the configuration
* of the CAN instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 = CAN_CURRENT_SPEED;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = ENABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = ENABLE;
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);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
/* 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);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn);
HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

56
Core/Src/gpio.c Normal file
View File

@@ -0,0 +1,56 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.c
* @brief This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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
PA8 ------> RCC_MCO
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin : PA8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */

View File

@@ -18,10 +18,14 @@
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "rtc.h"
#include "tim.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
//#include "requester.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -63,7 +67,9 @@ void SystemClock_Config(void);
int main(void)
{
/* USER CODE BEGIN 1 */
SystemClock_Config();
REQUESTER_Init();
REQUESTER_MainWhile();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
@@ -83,6 +89,10 @@ int main(void)
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
MX_RTC_Init();
MX_TIM4_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
@@ -106,13 +116,15 @@ 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_HSI;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
@@ -134,6 +146,13 @@ void SystemClock_Config(void)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
HAL_RCC_MCOConfig(RCC_MCO, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_1);
}
/* USER CODE BEGIN 4 */

934
Core/Src/requester.c Normal file
View File

@@ -0,0 +1,934 @@
#include "requester.h"
struct device CurrentDevice;
struct device Device_on_the_Network[8][16];
struct controlflags ControlFlags;
uint8_t CurrentStep = 0;
uint8_t LastStep = 0;
struct RXMsg rxMsg[CAN_RX_BUFFER_SIZE];
_Bool IsLeapYear(uint8_t year)
{
year+=2000;
return (year%400==0)||((year%4==0)&&(year%100!=0));
}
uint16_t AvailableCanRxMsg(void)
{
return ((uint16_t)(CAN_RX_BUFFER_SIZE + LastStep - CurrentStep))%CAN_RX_BUFFER_SIZE;
}
/**
* @brief Инициализация переферии
* @details Инициализация HAL, CAN, TIM7, RTC.
* @note Фильтры CAN описаны в разделе REQUESTER_CAN_FILTERS().
*/
void REQUESTER_Init(void)
{
HAL_Init();
MX_CAN_Init();
HAL_CAN_Start(&_HCAN);
REQUESTER_CAN_FILTERS();
HAL_CAN_ActivateNotification(&_HCAN, CAN_IT_RX_FIFO0_MSG_PENDING);
ControlFlags.IsPulse = 1;
MX_TIM4_Init();
MX_RTC_Init();
}
/**
* @brief Функция с обработкой полученных запросов
* @details В бесконечном цикле функция ожидает приёма сообщения. После этого сообщение распределяется в зависимости от DataType.
* Обработка запроса аналоговых значений - REQUESTER_AnalogProcessing().
* Обработка широковещательных запросов - REQUESTER_BroadcastProcessing().
* Обработка запроса дискретных значений - REQUESTER_DiscreticProcessing().
* Обработка Modbus - REQUESTER_ModbusProcessing().
*/
void REQUESTER_MainWhile(void)
{
HAL_TIM_Base_Start_IT(&htim4);
unsigned currentAttemptCount;
while(1)
{
if(AvailableCanRxMsg())
{
currentAttemptCount = 0;
if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ANALOG)
{
REQUESTER_AnalogProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_BROADCAST)
{
REQUESTER_BroadcastProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_DISCRETE)
{
REQUESTER_DiscreticProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_GENERAL_ADDRESS_SPACE)
{
REQUESTER_GeneralAddressSpace_Answer(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_COIL ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_DISCRETE ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_HOLDING ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_INPUT)
{
REQUESTER_ModbusProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ERROR)
{
CanRequestError(rxMsg[CurrentStep]);
}
CurrentStep = (uint16_t)(CurrentStep + 1) % CAN_RX_BUFFER_SIZE;
}
}
}
/**
* @brief Функция обработки аналоговых запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура.
*/
CRR_Status REQUESTER_AnalogProcessing(struct RXMsg _rxMsg)
{
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
switch (msg.Fields.SensorType)
{
case SENSOR_TYPE_ANALOG_UNIVERSAL:
{
return (CRR_Status)CanRequestToAnalogUniversal(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_USTAVKI:
{
return (CRR_Status)CanRequestToAnalogUSTAVKI(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_U:
{
return (CRR_Status)CanRequestToAnalogUSens(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_I:
{
return (CRR_Status)CanRequestToAnalogISens(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_T:
{
return (CRR_Status)CanRequestToAnalogTSens(_rxMsg);
break;
}
default:
//RESERVE SENSOR TYPE
return CRR_ERROR;
break;
}
return CRR_ERROR;
}
__weak HAL_StatusTypeDef CanRequestToAnalogUniversal(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'U';
data[1] = 'N';
data[2] = 'I';
data[3] = 'V';
data[4] = 'E';
data[5] = 'R';
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestToAnalogUSTAVKI(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 7;
data[0] = 'U';
data[1] = 'S';
data[2] = 'T';
data[3] = 'A';
data[4] = 'V';
data[5] = 'K';
data[6] = 'I';
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestToAnalogUSens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'U';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestToAnalogISens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'I';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestToAnalogTSens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'T';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция обработки широковещательных запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, выполняющая команды, переданные в широковещательном формате с головного (master) устройства. Типы команд: Запрос статуса, запрос на включение или выключение, рестарт устройств, установка времени.
*/
CRR_Status REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg)
{
msgBroadcastType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
switch(msg.Fields.BroadcastType)
{
case SENSOR_TYPE_BROADCAST_STATUS:
{
//Обработка запроса статуса устройства
if(CanRequestToBroadcastStatus(_rxMsg)!=HAL_OK)
{
return CRR_ERROR;
}
break;
}
case SENSOR_TYPE_BROADCAST_ONOFF:
{
//Обработка запроса на вкл/выкл
CanRequestToBroadcastOnOff(_rxMsg);
break;
}
case SENSOR_TYPE_BROADCAST_RESTARTDEVICE:
{
CanRequestToBroadcastRestart(_rxMsg);
break;
}
case SENSOR_TYPE_BROADCAST_RTCSETUP:
{
//Обработка запроса на синхронизацию времени
//С головным устройством
CanRequestToBroadcastRtcSetup(_rxMsg);
break;;
}
default:
//RESERVE SENSOR TYPE.
return CRR_ERROR;
break;
}
return CRR_OK;
}
__weak HAL_StatusTypeDef CanRequestToBroadcastStatus(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.DLC = 7;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
tmp_eID.Fields.DeviceID = CURRENT_ID_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
RTC_TimeTypeDef sTime = {0};
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
data[0] = sTime.Hours;
data[1] = sTime.Minutes;
data[2] = sTime.Seconds;
RTC_DateTypeDef DateToUpdate = {0};
HAL_RTC_GetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN);
data[3] = DateToUpdate.Year;
data[4] = DateToUpdate.Month;
data[5] = DateToUpdate.Date;
data[6] = DateToUpdate.WeekDay;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak void CanRequestToBroadcastOnOff(struct RXMsg _rxMsg)
{
ControlFlags.IsPulse = !ControlFlags.IsPulse;
}
__weak void CanRequestToBroadcastRestart(struct RXMsg _rxMsg)
{
if(_rxMsg.DLC == 0)
{
return;
}
msgBroadcastType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
if(msg.Fields.Page == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8)))
{
uint64_t page = 0;
for(int i = 0; i < _rxMsg.DLC; i++)
{
page+=(_rxMsg.Data[i]<<(i*8));
}
if((page>>CURRENT_ID_DEVICE)&0b1)
{
NVIC_SystemReset();
}
}
return;
}
__weak void CanRequestToBroadcastRtcSetup(struct RXMsg _rxMsg)
{
if(_rxMsg.DLC > 7)
{
//ERROR
}
else
{
int DaysCount_Normal[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
if (_rxMsg.Data[0]>23 ||
_rxMsg.Data[1]>59 ||
_rxMsg.Data[2]>59 ||
_rxMsg.Data[3]>99 ||
_rxMsg.Data[4]>12 ||
_rxMsg.Data[5] > DaysCount_Normal[IsLeapYear(_rxMsg.Data[3])][_rxMsg.Data[4]] ||
_rxMsg.Data[6]>6)
{
//ERROR
}
else
{
REQUESTER_RTC_SYNC(_rxMsg.Data);
}
}
}
/**
* @brief Функция обработки дискретных запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Аварии, Предупреждения, Управляющие сигналы, Флаги, Рестарт устройства, Изменение режима работы устройства, Запрос на устройство.
* @note Запрос на устройство. Головное (master) устройство запрашивает некоторое колличество параметров. В Data - 64 битовых адресса параметров, тип которых задаётся в Sensor ID. Имеется возможность запрашивать непоследовательные параметры.
*/
CRR_Status REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg)
{
msgDiscreteType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
switch(msg.Fields.Type){
case SENSOR_TYPE_DISCRETE_ACCIDENT:
{
CanRequestToDiscreteAccident(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_WARNING:
{
CanRequestToDiscreteWarning(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_CONTROL_SIGNALS:
{
CanRequestToDiscreteControlSignals(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_FLAGS:
{
CanRequestToDiscreteFlags(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_RESET:
{
CanRequestToDiscreteReset(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_CHANGE_MODE:
{
CanRequestToDiscreteChangeMode(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_REQUEST_LIST_OF_PARAMETERS:
{
CanRequestToDiscreteRequestListOfParameters(_rxMsg);
break;
}
default:
//RESERVE SENSOR TYPE.
return CRR_ERROR;
break;
}
return CRR_OK;
}
__weak void CanRequestToDiscreteAccident(struct RXMsg _rxMsg)
{
return;
}
__weak void CanRequestToDiscreteWarning(struct RXMsg _rxMsg)
{
return;
}
__weak void CanRequestToDiscreteControlSignals(struct RXMsg _rxMsg)
{
return;
}
__weak void CanRequestToDiscreteFlags(struct RXMsg _rxMsg)
{
return;
}
__weak void CanRequestToDiscreteReset(struct RXMsg _rxMsg)
{
NVIC_SystemReset();
}
__weak void CanRequestToDiscreteChangeMode(struct RXMsg _rxMsg)
{
return;
}
__weak void CanRequestToDiscreteRequestListOfParameters(struct RXMsg _rxMsg)
{
return;
}
void REQUESTER_GeneralAddressSpace_Answer(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
data[0] = 'G';
data[1] = 'A';
data[2] = 'S';
data[3] = '-';
for(int i = 0; i < 4; i++) {
unsigned sym = (_rxMsg.eID.Fields.MsgBody>>(12-(i*4)))&0xF;
if(sym >= 10)
data[4+i] = sym%10+'A';
else
data[4+i] = sym+'0';
}
HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция обработки Modbus запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, формирующая и отправляющая ответ на запросы.
*/
CRR_Status REQUESTER_ModbusProcessing(struct RXMsg _rxMsg)
{
switch(_rxMsg.eID.Fields.MsgType)
{
case DATA_TYPE_MODBUS_COIL:
{
return (CRR_Status)CanRequestToModbusCoil(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_DISCRETE:
{
return (CRR_Status)CanRequestToModbusDiscrete(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_HOLDING:
{
return (CRR_Status)CanRequestToModbusHolding(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_INPUT:
{
return (CRR_Status)CanRequestToModbusInput(_rxMsg);
break;
}
default:
//ERROR
return CRR_ERROR;
break;
}
return CRR_ERROR;
}
__weak HAL_StatusTypeDef CanRequestToModbusCoil(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'C';
data[2] = ' ';
data[3] = 'S';
data[4] = msg.Fields.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestToModbusDiscrete(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'D';
data[2] = ' ';
data[3] = 'S';
data[4] = msg.Fields.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestToModbusHolding(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'H';
data[2] = ' ';
data[3] = 'S';
data[4] = msg.Fields.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestToModbusInput(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'I';
data[2] = ' ';
data[3] = 'S';
data[4] = msg.Fields.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak HAL_StatusTypeDef CanRequestError(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.MsgType = DATA_TYPE_ERROR;
msgErrorType msg;
msg.Fields.ErrorCode = 0xFF;
msg.Fields.Info = 0;
tmp_eID.Fields.MsgBody = msg.Body;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 0;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief
* @param extID tmp_eID
* @param uint32_t tmp_IDE
* @param uint32_t tmp_RTR
* @param uint32_t tmp_DLC
* @param uint8_t *tmp_DATA
* @param uint16_t tmp_LastStep
* @details
*/
void TakeRxMsgToBuffer(extID tmp_eID, uint32_t tmp_IDE, uint32_t tmp_RTR, uint32_t tmp_DLC, uint8_t *tmp_DATA, uint16_t tmp_LastStep)
{
rxMsg[tmp_LastStep].eID.BitAll = tmp_eID.BitAll;
rxMsg[tmp_LastStep].info.EXT = tmp_IDE;
rxMsg[tmp_LastStep].info.RTR = tmp_RTR;
rxMsg[tmp_LastStep].DLC = tmp_DLC;
for(int i = 0; i < tmp_DLC; i++)
{
rxMsg[tmp_LastStep].Data[i] = tmp_DATA[i];
}
LastStep = tmp_LastStep;
}
/**
* @brief Callback-Функция обработки приёма.
* @details Функция, сигнализирующая через флаги в бесконечный цикл REQUESTER_MainWhile о приёме запроса.
*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef RxHeader;
uint8_t RCAN_Data[8];
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RCAN_Data);
//Расширенный ID
if(RxHeader.IDE == CAN_ID_EXT)
{
uint16_t tmp_LastStep = (uint16_t)(LastStep + 1) % CAN_RX_BUFFER_SIZE;
if(tmp_LastStep == CurrentStep)
{
//Буффер переполнен
return;
}
extID ExtID_Of_RX_MSG;
ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId;
//Полученное сообщение - широковещательное
if (ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_BROADCAST)
{
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
//Если ID запроса соответствует ID устройства
if((ExtID_Of_RX_MSG.Fields.DeviceType == CURRENT_TYPE_DEVICE) && (ExtID_Of_RX_MSG.Fields.DeviceID == CURRENT_ID_DEVICE))
{
if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_DISCRETE)
{
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_ANALOG)
{
//Является ли полученное сообщение - запросом
if(RxHeader.RTR)
{
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
}
if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_COIL ||
ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_DISCRETE ||
ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_HOLDING ||
ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_INPUT)
{
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
}
//Полученное сообщение - пульс устройств в сети
if (ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_PULSE)
{
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].Status = ONLINE;
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].TimeFromLastPulse = 0;
}
}
}
/**
* @brief Функция отправки пульса устройства.
* @details Пульс устройства. Есть возможность отключить пульс по запросу.
*/
void REQUESTER_Pulse_TIM_Handler()
{
if(ControlFlags.IsPulse)
{
static unsigned PulseStage = 0;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
extID currentID;
currentID.BitAll = 0;
currentID.Fields.MsgBody = 0;
currentID.Fields.DeviceID = CURRENT_ID_DEVICE;
currentID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
currentID.Fields.MsgType = DATA_TYPE_PULSE;
currentID.Fields.Route = ROUTE_SLAVE;
currentID.Fields.Priority = PRIORITY_STANDARD;
TxHeader.ExtId = currentID.BitAll;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = 1;
PulseStage++;
unsigned int debugID;
debugID = currentID.BitAll;
if(PulseStage > 0xFF){
PulseStage = 0;
}
data[0] = PulseStage;
HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
}
/**
* @brief Функция установки в RTC полученной даты/время из запроса.
* @param uint8_t *data - Байтовый массив, 7 элементов. [0] - Часы. [1] - Минуты. [2] - Секунды. [3] - Год. [4] - Месяц. [5] - Дата. [6] - День недели.
*/
void REQUESTER_RTC_SYNC(uint8_t *data)
{
__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef DateToUpdate = {0};
sTime.Hours = data[0];
sTime.Minutes = data[1];
sTime.Seconds = data[2];
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
DateToUpdate.Year = data[3];
DateToUpdate.Month = data[4];
DateToUpdate.Date = data[5];
DateToUpdate.WeekDay = data[6];
if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);
}
/**
* @brief Функция настройки фильтров CAN.
* @details Настройка фильтров. Фильр для приёма сообщений с главного устройства. Фильтр для приёма на текущее устройство. Фильтр для приёма пульса других устройств в сети.
*/
void CONFIG_CAN_FILTER(uint8_t filterBank, uint32_t idFilter, uint32_t idMask)
{
CAN_FilterTypeDef canFilterConfig;
canFilterConfig.FilterBank = filterBank;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.SlaveStartFilterBank = 14;
// Разбиваем 32-битный ID и маску для фильтрации на High и Low 16 бит
canFilterConfig.FilterIdHigh = (uint16_t)( ((idFilter) >> 13) ); // верхние 16 бит
canFilterConfig.FilterIdLow = (uint16_t)( (((idFilter) << 3) ) | CAN_IDE_32 ); // низкие 16 бит,
canFilterConfig.FilterMaskIdHigh = (uint16_t)(((idMask) >> 13) );
canFilterConfig.FilterMaskIdLow = (uint16_t)( (((idMask) << 3) ) | CAN_IDE_32 );
if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
#define BIT27 (1UL << 27)
#define BITS_20_23_MASK (0xFUL << 20) // 4 бита (20..23)
#define BITS_24_26_MASK (0x7UL << 24) // 3 бита (24..26)
uint32_t filter1_id = BIT27 | (CURRENT_TYPE_DEVICE << 24) | (CURRENT_ID_DEVICE << 20);
uint32_t filter1_mask = BIT27 | BITS_24_26_MASK | BITS_20_23_MASK; // все проверяемые биты
#define BITS_16_19_MASK (0xFUL << 16)
uint32_t filter2_id = DATA_TYPE_BROADCAST << 16;
uint32_t filter2_mask = BITS_16_19_MASK;
uint32_t filter3_id = DATA_TYPE_PULSE << 16;
uint32_t filter3_mask = BITS_16_19_MASK;
void REQUESTER_CAN_FILTERS()
{
// Первый фильтр: проверяем 20-27 биты, где 27-й всегда 1
CONFIG_CAN_FILTER(0, filter1_id, filter1_mask);
// Второй фильтр: проверяем 16-19 биты, равны DATA_TYPE_BROADCASTE
CONFIG_CAN_FILTER(1, filter2_id, filter2_mask);
// Третий фильтр: проверяем 16-19 биты, равны DATA_TYPE_PULSE
CONFIG_CAN_FILTER(2, filter3_id, filter3_mask);
CONFIG_CAN_FILTER(3, 0, 0);
}
//void REQUESTER_CAN_FILTERS()
//{
// //MAIN DEVICE
// CAN_FilterTypeDef canFilterConfig;
// canFilterConfig.FilterBank = 0;
// canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
// canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
// /*Для ID устройства используются восемь младших битов.
// Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
// canFilterConfig.FilterIdHigh = (uint16_t)(ID_MAIN_DEVICE>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(ID_MAIN_DEVICE<<5) | CAN_IDE_32;
// /*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
// canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
// canFilterConfig.FilterActivation = ENABLE;
// canFilterConfig.SlaveStartFilterBank = 14;
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //CURRENT DEVICE
// canFilterConfig.FilterBank = 1;
// /*Для ID устройства используются восемь младших битов.
// Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
// canFilterConfig.FilterIdHigh = (uint16_t)(CURRENT_ID_DEVICE>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(CURRENT_ID_DEVICE<<5) | CAN_IDE_32;
// /*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //MODBUS
// canFilterConfig.FilterBank = 2;
// canFilterConfig.FilterIdHigh = (uint16_t)(0x03000000>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(0x03000000<<5) | CAN_IDE_32;
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //PULSE
// canFilterConfig.FilterBank = 3;
// canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)<<5) | CAN_IDE_32;
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //DEBUG FILTER "ALL IDE WELCOME"
// canFilterConfig.FilterBank = 4;
// canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(0)>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(0)<<5) | CAN_IDE_32;
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(0>>13); // we're checking only high 13 bits, that contained "key"
// canFilterConfig.FilterMaskIdLow = (uint16_t)(0<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//}

120
Core/Src/rtc.c Normal file
View File

@@ -0,0 +1,120 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file rtc.c
* @brief This file provides code for the configuration
* of the RTC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* 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 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
DateToUpdate.Month = RTC_MONTH_JANUARY;
DateToUpdate.Date = 0x1;
DateToUpdate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
/* 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();
/* 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();
/* USER CODE BEGIN RTC_MspDeInit 1 */
/* USER CODE END RTC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -55,7 +55,8 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan;
extern TIM_HandleTypeDef htim4;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@@ -198,6 +199,76 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
/**
* @brief This function handles USB high priority or CAN TX interrupts.
*/
void USB_HP_CAN1_TX_IRQHandler(void)
{
/* USER CODE BEGIN USB_HP_CAN1_TX_IRQn 0 */
/* USER CODE END USB_HP_CAN1_TX_IRQn 0 */
HAL_CAN_IRQHandler(&hcan);
/* USER CODE BEGIN USB_HP_CAN1_TX_IRQn 1 */
/* USER CODE END USB_HP_CAN1_TX_IRQn 1 */
}
/**
* @brief This function handles USB low priority or CAN RX0 interrupts.
*/
void USB_LP_CAN1_RX0_IRQHandler(void)
{
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan);
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */
}
/**
* @brief This function handles CAN RX1 interrupt.
*/
void CAN1_RX1_IRQHandler(void)
{
/* USER CODE BEGIN CAN1_RX1_IRQn 0 */
/* USER CODE END CAN1_RX1_IRQn 0 */
HAL_CAN_IRQHandler(&hcan);
/* USER CODE BEGIN CAN1_RX1_IRQn 1 */
/* USER CODE END CAN1_RX1_IRQn 1 */
}
/**
* @brief This function handles CAN SCE interrupt.
*/
void CAN1_SCE_IRQHandler(void)
{
/* USER CODE BEGIN CAN1_SCE_IRQn 0 */
/* USER CODE END CAN1_SCE_IRQn 0 */
HAL_CAN_IRQHandler(&hcan);
/* USER CODE BEGIN CAN1_SCE_IRQn 1 */
/* USER CODE END CAN1_SCE_IRQn 1 */
}
/**
* @brief This function handles TIM4 global interrupt.
*/
void TIM4_IRQHandler(void)
{
/* USER CODE BEGIN TIM4_IRQn 0 */
REQUESTER_Pulse_TIM_Handler();
/* USER CODE END TIM4_IRQn 0 */
HAL_TIM_IRQHandler(&htim4);
/* USER CODE BEGIN TIM4_IRQn 1 */
/* USER CODE END TIM4_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

111
Core/Src/tim.c Normal file
View File

@@ -0,0 +1,111 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file tim.c
* @brief This file provides code for the configuration
* of the TIM instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 htim4;
/* 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 = TIM_REQUESTER_Prescaler-1;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 1000;
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==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==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 */