├── .gitignore ├── Core ├── Inc │ ├── ModbusRTU_Master.h │ ├── main.h │ ├── stm32f4xx_hal_conf.h │ └── stm32f4xx_it.h └── Src │ ├── ModbusRTU_Master.c │ ├── main.c │ ├── stm32f4xx_hal_msp.c │ ├── stm32f4xx_it.c │ ├── syscalls.c │ ├── sysmem.c │ └── system_stm32f4xx.c ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | STM32F407VGTX_RAM.ld 2 | STM32F407VGTX_FLASH.ld 3 | Modbus_Master.ioc 4 | Modbus_Master Debug.launch 5 | Drivers/ 6 | Debug/ 7 | .cproject 8 | .project 9 | .settings/ 10 | .mxproject 11 | Core/Startup -------------------------------------------------------------------------------- /Core/Inc/ModbusRTU_Master.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModbusRTU_Master.h 3 | * 4 | * Created on: Feb 17, 2022 5 | * Author: Ümit Can Güveren 6 | */ 7 | 8 | #ifndef INC_MODBUSRTU_MASTER_H_ 9 | #define INC_MODBUSRTU_MASTER_H_ 10 | 11 | #include "stdbool.h" 12 | #include "stdio.h" 13 | #include "stdint.h" 14 | #include "string.h" 15 | #include "stdbool.h" 16 | 17 | #define SLAVEID 1 18 | #define NUMBER_OF_REGISTER 10 19 | #define NUMBER_OF_COIL 16 20 | #define BUFFERSIZE (NUMBER_OF_REGISTER * 2 + 5) 21 | 22 | uint16_t ModbusRegister[NUMBER_OF_REGISTER]; 23 | bool ModbusCoil[NUMBER_OF_COIL]; 24 | 25 | enum 26 | { 27 | ReadCoil = 0x01, 28 | ReadHoldingRegister = 0x03, 29 | WriteSingleCoil = 0x05, 30 | WriteSingleRegister = 0x06, 31 | WriteMultipleCoils = 0x0F, 32 | WriteMultipleRegisters = 0x10, 33 | }; 34 | 35 | typedef enum 36 | { 37 | uartOkState, 38 | uartErrState, 39 | }uartState_t; 40 | 41 | typedef enum 42 | { 43 | crcOk, 44 | crcErr, 45 | }crcState_t; 46 | 47 | typedef enum 48 | { 49 | funcOk, 50 | funcErr, 51 | }funcState_t; 52 | 53 | typedef enum 54 | { 55 | coilOff = 0x00, 56 | coilOn = 0xFF, 57 | }coilState_t; 58 | 59 | /*Data transmit and receive func*/ 60 | funcState_t sendMessage(char *msg, uint16_t len); 61 | funcState_t takeMessage(char *msg, uint16_t len, uint8_t SlaveID); 62 | 63 | /****************************************** MODBUS Command Function ******************************************************/ 64 | funcState_t Modbus_ReadHoldingRegister(uint8_t SlaveID, uint16_t StartAddress, uint16_t NumberOfReg); 65 | funcState_t Modbus_WriteSingleRegister(uint8_t SlaveID, uint16_t RegAddress, uint16_t RegValue); 66 | 67 | funcState_t Modbus_ReadCoil(uint8_t SlaveID, uint16_t StartAddress, int16_t NumberOfCoil); 68 | funcState_t Modbus_WriteSingleCoil(uint8_t SlaveID, uint16_t RegAddress, coilState_t CoilState); 69 | 70 | funcState_t Modbus_WriteMultipleCoils(uint8_t SlaveID, uint16_t StartAddress, uint16_t NumberOfCoils, char *coilValue); 71 | funcState_t Modbus_WriteMultipleRegisters(uint8_t SlaveID, uint16_t StartAddress, uint16_t NumberOfReg, uint16_t *regValue); 72 | /**************************************************************************************************************************/ 73 | uint8_t findByte(int16_t NumberOfCoil); 74 | uint16_t MODBUS_CRC16(char *buf, uint8_t len ); 75 | 76 | #endif /* INC_MODBUSRTU_MASTER_H_ */ 77 | -------------------------------------------------------------------------------- /Core/Inc/main.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.h 5 | * @brief : Header for main.c file. 6 | * This file contains the common defines of the application. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2022 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Define to prevent recursive inclusion -------------------------------------*/ 23 | #ifndef __MAIN_H 24 | #define __MAIN_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include "stm32f4xx_hal.h" 32 | 33 | /* Private includes ----------------------------------------------------------*/ 34 | /* USER CODE BEGIN Includes */ 35 | 36 | /* USER CODE END Includes */ 37 | 38 | /* Exported types ------------------------------------------------------------*/ 39 | /* USER CODE BEGIN ET */ 40 | 41 | /* USER CODE END ET */ 42 | 43 | /* Exported constants --------------------------------------------------------*/ 44 | /* USER CODE BEGIN EC */ 45 | 46 | /* USER CODE END EC */ 47 | 48 | /* Exported macro ------------------------------------------------------------*/ 49 | /* USER CODE BEGIN EM */ 50 | 51 | /* USER CODE END EM */ 52 | 53 | /* Exported functions prototypes ---------------------------------------------*/ 54 | void Error_Handler(void); 55 | 56 | /* USER CODE BEGIN EFP */ 57 | 58 | /* USER CODE END EFP */ 59 | 60 | /* Private defines -----------------------------------------------------------*/ 61 | /* USER CODE BEGIN Private defines */ 62 | 63 | /* USER CODE END Private defines */ 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif /* __MAIN_H */ 70 | 71 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 72 | -------------------------------------------------------------------------------- /Core/Inc/stm32f4xx_hal_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_conf_template.h 4 | * @author MCD Application Team 5 | * @brief HAL configuration template file. 6 | * This file should be copied to the application folder and renamed 7 | * to stm32f4xx_hal_conf.h. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© Copyright (c) 2017 STMicroelectronics. 12 | * All rights reserved.

13 | * 14 | * This software component is licensed by ST under BSD 3-Clause license, 15 | * the "License"; You may not use this file except in compliance with the 16 | * License. You may obtain a copy of the License at: 17 | * opensource.org/licenses/BSD-3-Clause 18 | * 19 | ****************************************************************************** 20 | */ 21 | 22 | /* Define to prevent recursive inclusion -------------------------------------*/ 23 | #ifndef __STM32F4xx_HAL_CONF_H 24 | #define __STM32F4xx_HAL_CONF_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Exported types ------------------------------------------------------------*/ 31 | /* Exported constants --------------------------------------------------------*/ 32 | 33 | /* ########################## Module Selection ############################## */ 34 | /** 35 | * @brief This is the list of modules to be used in the HAL driver 36 | */ 37 | #define HAL_MODULE_ENABLED 38 | 39 | /* #define HAL_ADC_MODULE_ENABLED */ 40 | /* #define HAL_CRYP_MODULE_ENABLED */ 41 | /* #define HAL_CAN_MODULE_ENABLED */ 42 | /* #define HAL_CRC_MODULE_ENABLED */ 43 | /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ 44 | /* #define HAL_CRYP_MODULE_ENABLED */ 45 | /* #define HAL_DAC_MODULE_ENABLED */ 46 | /* #define HAL_DCMI_MODULE_ENABLED */ 47 | /* #define HAL_DMA2D_MODULE_ENABLED */ 48 | /* #define HAL_ETH_MODULE_ENABLED */ 49 | /* #define HAL_NAND_MODULE_ENABLED */ 50 | /* #define HAL_NOR_MODULE_ENABLED */ 51 | /* #define HAL_PCCARD_MODULE_ENABLED */ 52 | /* #define HAL_SRAM_MODULE_ENABLED */ 53 | /* #define HAL_SDRAM_MODULE_ENABLED */ 54 | /* #define HAL_HASH_MODULE_ENABLED */ 55 | /* #define HAL_I2C_MODULE_ENABLED */ 56 | /* #define HAL_I2S_MODULE_ENABLED */ 57 | /* #define HAL_IWDG_MODULE_ENABLED */ 58 | /* #define HAL_LTDC_MODULE_ENABLED */ 59 | /* #define HAL_RNG_MODULE_ENABLED */ 60 | /* #define HAL_RTC_MODULE_ENABLED */ 61 | /* #define HAL_SAI_MODULE_ENABLED */ 62 | /* #define HAL_SD_MODULE_ENABLED */ 63 | /* #define HAL_MMC_MODULE_ENABLED */ 64 | /* #define HAL_SPI_MODULE_ENABLED */ 65 | /* #define HAL_TIM_MODULE_ENABLED */ 66 | #define HAL_UART_MODULE_ENABLED 67 | /* #define HAL_USART_MODULE_ENABLED */ 68 | /* #define HAL_IRDA_MODULE_ENABLED */ 69 | /* #define HAL_SMARTCARD_MODULE_ENABLED */ 70 | /* #define HAL_SMBUS_MODULE_ENABLED */ 71 | /* #define HAL_WWDG_MODULE_ENABLED */ 72 | /* #define HAL_PCD_MODULE_ENABLED */ 73 | /* #define HAL_HCD_MODULE_ENABLED */ 74 | /* #define HAL_DSI_MODULE_ENABLED */ 75 | /* #define HAL_QSPI_MODULE_ENABLED */ 76 | /* #define HAL_QSPI_MODULE_ENABLED */ 77 | /* #define HAL_CEC_MODULE_ENABLED */ 78 | /* #define HAL_FMPI2C_MODULE_ENABLED */ 79 | /* #define HAL_FMPSMBUS_MODULE_ENABLED */ 80 | /* #define HAL_SPDIFRX_MODULE_ENABLED */ 81 | /* #define HAL_DFSDM_MODULE_ENABLED */ 82 | /* #define HAL_LPTIM_MODULE_ENABLED */ 83 | #define HAL_GPIO_MODULE_ENABLED 84 | #define HAL_EXTI_MODULE_ENABLED 85 | #define HAL_DMA_MODULE_ENABLED 86 | #define HAL_RCC_MODULE_ENABLED 87 | #define HAL_FLASH_MODULE_ENABLED 88 | #define HAL_PWR_MODULE_ENABLED 89 | #define HAL_CORTEX_MODULE_ENABLED 90 | 91 | /* ########################## HSE/HSI Values adaptation ##################### */ 92 | /** 93 | * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. 94 | * This value is used by the RCC HAL module to compute the system frequency 95 | * (when HSE is used as system clock source, directly or through the PLL). 96 | */ 97 | #if !defined (HSE_VALUE) 98 | #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ 99 | #endif /* HSE_VALUE */ 100 | 101 | #if !defined (HSE_STARTUP_TIMEOUT) 102 | #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ 103 | #endif /* HSE_STARTUP_TIMEOUT */ 104 | 105 | /** 106 | * @brief Internal High Speed oscillator (HSI) value. 107 | * This value is used by the RCC HAL module to compute the system frequency 108 | * (when HSI is used as system clock source, directly or through the PLL). 109 | */ 110 | #if !defined (HSI_VALUE) 111 | #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ 112 | #endif /* HSI_VALUE */ 113 | 114 | /** 115 | * @brief Internal Low Speed oscillator (LSI) value. 116 | */ 117 | #if !defined (LSI_VALUE) 118 | #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/ 119 | #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz 120 | The real value may vary depending on the variations 121 | in voltage and temperature.*/ 122 | /** 123 | * @brief External Low Speed oscillator (LSE) value. 124 | */ 125 | #if !defined (LSE_VALUE) 126 | #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ 127 | #endif /* LSE_VALUE */ 128 | 129 | #if !defined (LSE_STARTUP_TIMEOUT) 130 | #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ 131 | #endif /* LSE_STARTUP_TIMEOUT */ 132 | 133 | /** 134 | * @brief External clock source for I2S peripheral 135 | * This value is used by the I2S HAL module to compute the I2S clock source 136 | * frequency, this source is inserted directly through I2S_CKIN pad. 137 | */ 138 | #if !defined (EXTERNAL_CLOCK_VALUE) 139 | #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External audio frequency in Hz*/ 140 | #endif /* EXTERNAL_CLOCK_VALUE */ 141 | 142 | /* Tip: To avoid modifying this file each time you need to use different HSE, 143 | === you can define the HSE value in your toolchain compiler preprocessor. */ 144 | 145 | /* ########################### System Configuration ######################### */ 146 | /** 147 | * @brief This is the HAL system configuration section 148 | */ 149 | #define VDD_VALUE 3300U /*!< Value of VDD in mv */ 150 | #define TICK_INT_PRIORITY 15U /*!< tick interrupt priority */ 151 | #define USE_RTOS 0U 152 | #define PREFETCH_ENABLE 1U 153 | #define INSTRUCTION_CACHE_ENABLE 1U 154 | #define DATA_CACHE_ENABLE 1U 155 | 156 | #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ 157 | #define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ 158 | #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ 159 | #define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ 160 | #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ 161 | #define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ 162 | #define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ 163 | #define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ 164 | #define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ 165 | #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ 166 | #define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ 167 | #define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ 168 | #define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ 169 | #define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ 170 | #define USE_HAL_FMPSMBUS_REGISTER_CALLBACKS 0U /* FMPSMBUS register callback disabled */ 171 | #define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ 172 | #define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ 173 | #define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ 174 | #define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ 175 | #define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ 176 | #define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ 177 | #define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ 178 | #define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ 179 | #define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ 180 | #define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ 181 | #define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ 182 | #define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ 183 | #define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ 184 | #define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ 185 | #define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ 186 | #define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ 187 | #define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ 188 | #define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ 189 | #define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ 190 | #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ 191 | #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ 192 | #define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ 193 | #define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ 194 | #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ 195 | 196 | /* ########################## Assert Selection ############################## */ 197 | /** 198 | * @brief Uncomment the line below to expanse the "assert_param" macro in the 199 | * HAL drivers code 200 | */ 201 | /* #define USE_FULL_ASSERT 1U */ 202 | 203 | /* ################## Ethernet peripheral configuration ##################### */ 204 | 205 | /* Section 1 : Ethernet peripheral configuration */ 206 | 207 | /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ 208 | #define MAC_ADDR0 2U 209 | #define MAC_ADDR1 0U 210 | #define MAC_ADDR2 0U 211 | #define MAC_ADDR3 0U 212 | #define MAC_ADDR4 0U 213 | #define MAC_ADDR5 0U 214 | 215 | /* Definition of the Ethernet driver buffers size and count */ 216 | #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ 217 | #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ 218 | #define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ 219 | #define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ 220 | 221 | /* Section 2: PHY configuration section */ 222 | 223 | /* DP83848_PHY_ADDRESS Address*/ 224 | #define DP83848_PHY_ADDRESS 0x01U 225 | /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ 226 | #define PHY_RESET_DELAY 0x000000FFU 227 | /* PHY Configuration delay */ 228 | #define PHY_CONFIG_DELAY 0x00000FFFU 229 | 230 | #define PHY_READ_TO 0x0000FFFFU 231 | #define PHY_WRITE_TO 0x0000FFFFU 232 | 233 | /* Section 3: Common PHY Registers */ 234 | 235 | #define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */ 236 | #define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */ 237 | 238 | #define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ 239 | #define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ 240 | #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ 241 | #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ 242 | #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ 243 | #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ 244 | #define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ 245 | #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ 246 | #define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ 247 | #define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ 248 | 249 | #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ 250 | #define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ 251 | #define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ 252 | 253 | /* Section 4: Extended PHY Registers */ 254 | #define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ 255 | 256 | #define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ 257 | #define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ 258 | 259 | /* ################## SPI peripheral configuration ########################## */ 260 | 261 | /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver 262 | * Activated: CRC code is present inside driver 263 | * Deactivated: CRC code cleaned from driver 264 | */ 265 | 266 | #define USE_SPI_CRC 0U 267 | 268 | /* Includes ------------------------------------------------------------------*/ 269 | /** 270 | * @brief Include module's header file 271 | */ 272 | 273 | #ifdef HAL_RCC_MODULE_ENABLED 274 | #include "stm32f4xx_hal_rcc.h" 275 | #endif /* HAL_RCC_MODULE_ENABLED */ 276 | 277 | #ifdef HAL_GPIO_MODULE_ENABLED 278 | #include "stm32f4xx_hal_gpio.h" 279 | #endif /* HAL_GPIO_MODULE_ENABLED */ 280 | 281 | #ifdef HAL_EXTI_MODULE_ENABLED 282 | #include "stm32f4xx_hal_exti.h" 283 | #endif /* HAL_EXTI_MODULE_ENABLED */ 284 | 285 | #ifdef HAL_DMA_MODULE_ENABLED 286 | #include "stm32f4xx_hal_dma.h" 287 | #endif /* HAL_DMA_MODULE_ENABLED */ 288 | 289 | #ifdef HAL_CORTEX_MODULE_ENABLED 290 | #include "stm32f4xx_hal_cortex.h" 291 | #endif /* HAL_CORTEX_MODULE_ENABLED */ 292 | 293 | #ifdef HAL_ADC_MODULE_ENABLED 294 | #include "stm32f4xx_hal_adc.h" 295 | #endif /* HAL_ADC_MODULE_ENABLED */ 296 | 297 | #ifdef HAL_CAN_MODULE_ENABLED 298 | #include "stm32f4xx_hal_can.h" 299 | #endif /* HAL_CAN_MODULE_ENABLED */ 300 | 301 | #ifdef HAL_CAN_LEGACY_MODULE_ENABLED 302 | #include "stm32f4xx_hal_can_legacy.h" 303 | #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ 304 | 305 | #ifdef HAL_CRC_MODULE_ENABLED 306 | #include "stm32f4xx_hal_crc.h" 307 | #endif /* HAL_CRC_MODULE_ENABLED */ 308 | 309 | #ifdef HAL_CRYP_MODULE_ENABLED 310 | #include "stm32f4xx_hal_cryp.h" 311 | #endif /* HAL_CRYP_MODULE_ENABLED */ 312 | 313 | #ifdef HAL_DMA2D_MODULE_ENABLED 314 | #include "stm32f4xx_hal_dma2d.h" 315 | #endif /* HAL_DMA2D_MODULE_ENABLED */ 316 | 317 | #ifdef HAL_DAC_MODULE_ENABLED 318 | #include "stm32f4xx_hal_dac.h" 319 | #endif /* HAL_DAC_MODULE_ENABLED */ 320 | 321 | #ifdef HAL_DCMI_MODULE_ENABLED 322 | #include "stm32f4xx_hal_dcmi.h" 323 | #endif /* HAL_DCMI_MODULE_ENABLED */ 324 | 325 | #ifdef HAL_ETH_MODULE_ENABLED 326 | #include "stm32f4xx_hal_eth.h" 327 | #endif /* HAL_ETH_MODULE_ENABLED */ 328 | 329 | #ifdef HAL_FLASH_MODULE_ENABLED 330 | #include "stm32f4xx_hal_flash.h" 331 | #endif /* HAL_FLASH_MODULE_ENABLED */ 332 | 333 | #ifdef HAL_SRAM_MODULE_ENABLED 334 | #include "stm32f4xx_hal_sram.h" 335 | #endif /* HAL_SRAM_MODULE_ENABLED */ 336 | 337 | #ifdef HAL_NOR_MODULE_ENABLED 338 | #include "stm32f4xx_hal_nor.h" 339 | #endif /* HAL_NOR_MODULE_ENABLED */ 340 | 341 | #ifdef HAL_NAND_MODULE_ENABLED 342 | #include "stm32f4xx_hal_nand.h" 343 | #endif /* HAL_NAND_MODULE_ENABLED */ 344 | 345 | #ifdef HAL_PCCARD_MODULE_ENABLED 346 | #include "stm32f4xx_hal_pccard.h" 347 | #endif /* HAL_PCCARD_MODULE_ENABLED */ 348 | 349 | #ifdef HAL_SDRAM_MODULE_ENABLED 350 | #include "stm32f4xx_hal_sdram.h" 351 | #endif /* HAL_SDRAM_MODULE_ENABLED */ 352 | 353 | #ifdef HAL_HASH_MODULE_ENABLED 354 | #include "stm32f4xx_hal_hash.h" 355 | #endif /* HAL_HASH_MODULE_ENABLED */ 356 | 357 | #ifdef HAL_I2C_MODULE_ENABLED 358 | #include "stm32f4xx_hal_i2c.h" 359 | #endif /* HAL_I2C_MODULE_ENABLED */ 360 | 361 | #ifdef HAL_SMBUS_MODULE_ENABLED 362 | #include "stm32f4xx_hal_smbus.h" 363 | #endif /* HAL_SMBUS_MODULE_ENABLED */ 364 | 365 | #ifdef HAL_I2S_MODULE_ENABLED 366 | #include "stm32f4xx_hal_i2s.h" 367 | #endif /* HAL_I2S_MODULE_ENABLED */ 368 | 369 | #ifdef HAL_IWDG_MODULE_ENABLED 370 | #include "stm32f4xx_hal_iwdg.h" 371 | #endif /* HAL_IWDG_MODULE_ENABLED */ 372 | 373 | #ifdef HAL_LTDC_MODULE_ENABLED 374 | #include "stm32f4xx_hal_ltdc.h" 375 | #endif /* HAL_LTDC_MODULE_ENABLED */ 376 | 377 | #ifdef HAL_PWR_MODULE_ENABLED 378 | #include "stm32f4xx_hal_pwr.h" 379 | #endif /* HAL_PWR_MODULE_ENABLED */ 380 | 381 | #ifdef HAL_RNG_MODULE_ENABLED 382 | #include "stm32f4xx_hal_rng.h" 383 | #endif /* HAL_RNG_MODULE_ENABLED */ 384 | 385 | #ifdef HAL_RTC_MODULE_ENABLED 386 | #include "stm32f4xx_hal_rtc.h" 387 | #endif /* HAL_RTC_MODULE_ENABLED */ 388 | 389 | #ifdef HAL_SAI_MODULE_ENABLED 390 | #include "stm32f4xx_hal_sai.h" 391 | #endif /* HAL_SAI_MODULE_ENABLED */ 392 | 393 | #ifdef HAL_SD_MODULE_ENABLED 394 | #include "stm32f4xx_hal_sd.h" 395 | #endif /* HAL_SD_MODULE_ENABLED */ 396 | 397 | #ifdef HAL_SPI_MODULE_ENABLED 398 | #include "stm32f4xx_hal_spi.h" 399 | #endif /* HAL_SPI_MODULE_ENABLED */ 400 | 401 | #ifdef HAL_TIM_MODULE_ENABLED 402 | #include "stm32f4xx_hal_tim.h" 403 | #endif /* HAL_TIM_MODULE_ENABLED */ 404 | 405 | #ifdef HAL_UART_MODULE_ENABLED 406 | #include "stm32f4xx_hal_uart.h" 407 | #endif /* HAL_UART_MODULE_ENABLED */ 408 | 409 | #ifdef HAL_USART_MODULE_ENABLED 410 | #include "stm32f4xx_hal_usart.h" 411 | #endif /* HAL_USART_MODULE_ENABLED */ 412 | 413 | #ifdef HAL_IRDA_MODULE_ENABLED 414 | #include "stm32f4xx_hal_irda.h" 415 | #endif /* HAL_IRDA_MODULE_ENABLED */ 416 | 417 | #ifdef HAL_SMARTCARD_MODULE_ENABLED 418 | #include "stm32f4xx_hal_smartcard.h" 419 | #endif /* HAL_SMARTCARD_MODULE_ENABLED */ 420 | 421 | #ifdef HAL_WWDG_MODULE_ENABLED 422 | #include "stm32f4xx_hal_wwdg.h" 423 | #endif /* HAL_WWDG_MODULE_ENABLED */ 424 | 425 | #ifdef HAL_PCD_MODULE_ENABLED 426 | #include "stm32f4xx_hal_pcd.h" 427 | #endif /* HAL_PCD_MODULE_ENABLED */ 428 | 429 | #ifdef HAL_HCD_MODULE_ENABLED 430 | #include "stm32f4xx_hal_hcd.h" 431 | #endif /* HAL_HCD_MODULE_ENABLED */ 432 | 433 | #ifdef HAL_DSI_MODULE_ENABLED 434 | #include "stm32f4xx_hal_dsi.h" 435 | #endif /* HAL_DSI_MODULE_ENABLED */ 436 | 437 | #ifdef HAL_QSPI_MODULE_ENABLED 438 | #include "stm32f4xx_hal_qspi.h" 439 | #endif /* HAL_QSPI_MODULE_ENABLED */ 440 | 441 | #ifdef HAL_CEC_MODULE_ENABLED 442 | #include "stm32f4xx_hal_cec.h" 443 | #endif /* HAL_CEC_MODULE_ENABLED */ 444 | 445 | #ifdef HAL_FMPI2C_MODULE_ENABLED 446 | #include "stm32f4xx_hal_fmpi2c.h" 447 | #endif /* HAL_FMPI2C_MODULE_ENABLED */ 448 | 449 | #ifdef HAL_FMPSMBUS_MODULE_ENABLED 450 | #include "stm32f4xx_hal_fmpsmbus.h" 451 | #endif /* HAL_FMPSMBUS_MODULE_ENABLED */ 452 | 453 | #ifdef HAL_SPDIFRX_MODULE_ENABLED 454 | #include "stm32f4xx_hal_spdifrx.h" 455 | #endif /* HAL_SPDIFRX_MODULE_ENABLED */ 456 | 457 | #ifdef HAL_DFSDM_MODULE_ENABLED 458 | #include "stm32f4xx_hal_dfsdm.h" 459 | #endif /* HAL_DFSDM_MODULE_ENABLED */ 460 | 461 | #ifdef HAL_LPTIM_MODULE_ENABLED 462 | #include "stm32f4xx_hal_lptim.h" 463 | #endif /* HAL_LPTIM_MODULE_ENABLED */ 464 | 465 | #ifdef HAL_MMC_MODULE_ENABLED 466 | #include "stm32f4xx_hal_mmc.h" 467 | #endif /* HAL_MMC_MODULE_ENABLED */ 468 | 469 | /* Exported macro ------------------------------------------------------------*/ 470 | #ifdef USE_FULL_ASSERT 471 | /** 472 | * @brief The assert_param macro is used for function's parameters check. 473 | * @param expr If expr is false, it calls assert_failed function 474 | * which reports the name of the source file and the source 475 | * line number of the call that failed. 476 | * If expr is true, it returns no value. 477 | * @retval None 478 | */ 479 | #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) 480 | /* Exported functions ------------------------------------------------------- */ 481 | void assert_failed(uint8_t* file, uint32_t line); 482 | #else 483 | #define assert_param(expr) ((void)0U) 484 | #endif /* USE_FULL_ASSERT */ 485 | 486 | #ifdef __cplusplus 487 | } 488 | #endif 489 | 490 | #endif /* __STM32F4xx_HAL_CONF_H */ 491 | 492 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 493 | -------------------------------------------------------------------------------- /Core/Inc/stm32f4xx_it.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_it.h 5 | * @brief This file contains the headers of the interrupt handlers. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2022 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F4xx_IT_H 23 | #define __STM32F4xx_IT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* Private includes ----------------------------------------------------------*/ 30 | /* USER CODE BEGIN Includes */ 31 | 32 | /* USER CODE END Includes */ 33 | 34 | /* Exported types ------------------------------------------------------------*/ 35 | /* USER CODE BEGIN ET */ 36 | 37 | /* USER CODE END ET */ 38 | 39 | /* Exported constants --------------------------------------------------------*/ 40 | /* USER CODE BEGIN EC */ 41 | 42 | /* USER CODE END EC */ 43 | 44 | /* Exported macro ------------------------------------------------------------*/ 45 | /* USER CODE BEGIN EM */ 46 | 47 | /* USER CODE END EM */ 48 | 49 | /* Exported functions prototypes ---------------------------------------------*/ 50 | void NMI_Handler(void); 51 | void HardFault_Handler(void); 52 | void MemManage_Handler(void); 53 | void BusFault_Handler(void); 54 | void UsageFault_Handler(void); 55 | void SVC_Handler(void); 56 | void DebugMon_Handler(void); 57 | void PendSV_Handler(void); 58 | void SysTick_Handler(void); 59 | void USART2_IRQHandler(void); 60 | /* USER CODE BEGIN EFP */ 61 | 62 | /* USER CODE END EFP */ 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif /* __STM32F4xx_IT_H */ 69 | 70 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 71 | -------------------------------------------------------------------------------- /Core/Src/ModbusRTU_Master.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ModbusRTU_Master.c 3 | * 4 | * Created on: Feb 17, 2022 5 | * Author: Ümit Can Güveren 6 | */ 7 | 8 | #include 9 | #include "main.h" 10 | 11 | 12 | extern UART_HandleTypeDef huart2; 13 | uint8_t BytetoBit[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; 14 | 15 | 16 | funcState_t sendMessage(char *msg, uint16_t len) 17 | { 18 | uartState_t stateTx; 19 | 20 | stateTx = HAL_UART_Transmit_IT(&huart2, (uint8_t *)msg, len); 21 | 22 | if(stateTx == uartOkState) 23 | { 24 | return funcOk; 25 | } 26 | else 27 | { 28 | return funcErr; 29 | } 30 | } 31 | 32 | funcState_t takeMessage(char *msg, uint16_t len, uint8_t SlaveID) 33 | { 34 | uartState_t stateRx; 35 | crcState_t crcCheck; 36 | uint16_t CRCVal, rxCRC; 37 | 38 | stateRx = HAL_UART_Receive(&huart2, (uint8_t *)msg, len, 100); 39 | 40 | 41 | rxCRC = (msg[len -1] << 8) | (msg[len - 2]); 42 | CRCVal = MODBUS_CRC16(msg, len - 2); 43 | 44 | if(CRCVal == rxCRC) 45 | { 46 | crcCheck = crcOk; 47 | } 48 | else 49 | { 50 | crcCheck = crcErr; 51 | } 52 | 53 | if(stateRx == uartOkState && crcCheck == crcOk && msg[0] == SLAVEID) 54 | { 55 | return funcOk; 56 | } 57 | else 58 | { 59 | return funcErr; 60 | } 61 | 62 | } 63 | 64 | 65 | /* 66 | * @brief Modbus_ReadHoldingRegister, Reads Holding Register #0x03 67 | * 68 | * @param SlaveID = Slave address to be read 69 | * 70 | * @param StartAddress = First address of the register to be read 71 | * 72 | * @param NumberOfReg = Number of register to be read 73 | * 74 | * @funcState_t returns funcOk if the received data CRC and SlaveID is true after the sent data 75 | */ 76 | funcState_t Modbus_ReadHoldingRegister(uint8_t SlaveID, uint16_t StartAddress, uint16_t NumberOfReg) 77 | { 78 | uint16_t CRCVal = 0; 79 | funcState_t funcTxState, funcRxState; 80 | uint8_t i, m = 0; 81 | 82 | char ModbusRx[BUFFERSIZE]; 83 | char ModbusTx[8]; 84 | 85 | memset(ModbusTx, 0, 8); 86 | 87 | ModbusTx[0] = SlaveID; 88 | ModbusTx[1] = ReadHoldingRegister; 89 | ModbusTx[2] = StartAddress >> 8; 90 | ModbusTx[3] = (uint8_t)(StartAddress & 0x00FF); 91 | ModbusTx[4] = NumberOfReg >> 8; 92 | ModbusTx[5] = (uint8_t)(NumberOfReg & 0x00FF); 93 | 94 | CRCVal = MODBUS_CRC16(ModbusTx, 6); 95 | 96 | ModbusTx[6] = (uint8_t)(CRCVal & 0x00FF); 97 | ModbusTx[7] = CRCVal >> 8; 98 | 99 | funcTxState = sendMessage(&ModbusTx[0], 8); 100 | 101 | if(funcTxState == funcOk) 102 | { 103 | funcRxState = takeMessage(ModbusRx, 5 + (NumberOfReg * 2), SlaveID); 104 | } 105 | if(funcRxState == funcOk) 106 | { 107 | for(i = 0; i < NumberOfReg; i++) 108 | { 109 | ModbusRegister[StartAddress + i] = (uint16_t)((ModbusRx[3 + m] << 8) | (ModbusRx[4 + m])); 110 | m += 2; 111 | } 112 | } 113 | 114 | return funcRxState; 115 | } 116 | 117 | /* 118 | * @brief Modbus_ReadHoldingRegister, Reads Holding Register #0x03 119 | * 120 | * @param SlaveID = Slave address to be read 121 | * 122 | * @param RegAddress = Address of the register to be write 123 | * 124 | * @param RegValue = Value to be write to register 125 | * 126 | * @funcState_t returns funcOk if the received data CRC and SlaveID is true after the sent data 127 | */ 128 | funcState_t Modbus_WriteSingleRegister(uint8_t SlaveID, uint16_t RegAddress, uint16_t RegValue) 129 | { 130 | uint16_t CRCVal = 0; 131 | funcState_t funcTxState, funcRxState; 132 | 133 | char ModbusRx[BUFFERSIZE]; 134 | char ModbusTx[8]; 135 | 136 | memset(ModbusTx, 0, 8); 137 | 138 | ModbusTx[0] = SlaveID; 139 | ModbusTx[1] = WriteSingleRegister; 140 | ModbusTx[2] = (uint8_t)(RegAddress >> 8); 141 | ModbusTx[3] = (uint8_t)(RegAddress & 0x00FF); 142 | ModbusTx[4] = (uint8_t)(RegValue >> 8); 143 | ModbusTx[5] = (uint8_t)(RegValue & 0x00FF); 144 | 145 | CRCVal = MODBUS_CRC16(ModbusTx, 6); 146 | 147 | ModbusTx[6] = (uint8_t)(CRCVal & 0x00FF); 148 | ModbusTx[7] = CRCVal >> 8; 149 | 150 | funcTxState = sendMessage(&ModbusTx[0], 8); 151 | 152 | if(funcTxState == funcOk) 153 | { 154 | funcRxState = takeMessage(ModbusRx, 8, SlaveID); 155 | } 156 | 157 | return funcRxState; //CRC and ID is true. 158 | } 159 | 160 | 161 | /* 162 | * @brief Modbus_ReadCoil, Reads Coils #0x01 163 | * 164 | * @param SlaveID = Slave address to be read 165 | * 166 | * @param StartAddress = First address of the coil to be read 167 | * 168 | * @param NumberOfCoil = Number of coils to be read 169 | * 170 | * @funcState_t returns funcOk if the received data CRC and SlaveID is true after the sent data 171 | */ 172 | funcState_t Modbus_ReadCoil(uint8_t SlaveID, uint16_t StartAddress, int16_t NumberOfCoil) 173 | { 174 | uint16_t CRCVal = 0, Modbus_i, ByteCounter = 0, BitCounter = 0; 175 | 176 | funcState_t funcTxState, funcRxState; 177 | char ModbusRx[BUFFERSIZE]; 178 | char ModbusTx[8]; 179 | 180 | uint8_t NumberOfByte; 181 | 182 | NumberOfByte = findByte(NumberOfCoil); 183 | 184 | ModbusTx[0] = SlaveID; 185 | ModbusTx[1] = ReadCoil; 186 | ModbusTx[2] = (uint8_t)(StartAddress >> 8); 187 | ModbusTx[3] = (uint8_t)(StartAddress & 0x00FF); 188 | ModbusTx[4] = (uint8_t)(NumberOfCoil >> 8); 189 | ModbusTx[5] = (uint8_t)(NumberOfCoil & 0x00FF); 190 | 191 | CRCVal = MODBUS_CRC16(ModbusTx, 6); 192 | 193 | ModbusTx[6] = (uint8_t)(CRCVal & 0x00FF); 194 | ModbusTx[7] = CRCVal >> 8; 195 | 196 | funcTxState = sendMessage(&ModbusTx[0], 8); 197 | 198 | if(funcTxState == funcOk) 199 | { 200 | funcRxState = takeMessage(ModbusRx, 5 + NumberOfByte, SlaveID); 201 | } 202 | 203 | if(funcRxState == funcOk) 204 | { 205 | for(Modbus_i = 0; Modbus_i < NumberOfCoil; Modbus_i++) 206 | { 207 | ModbusCoil[StartAddress + Modbus_i] = (bool)(ModbusRx[3 + ByteCounter] & BytetoBit[BitCounter]); 208 | 209 | BitCounter++; 210 | 211 | if(Modbus_i % 8 == 7) 212 | { 213 | ByteCounter++; 214 | BitCounter = 0; 215 | } 216 | } 217 | } 218 | return funcRxState; 219 | } 220 | 221 | /* 222 | * @brief Modbus_WriteSingleCoil, Writes Holding Register #0x05 223 | * 224 | * @param SlaveID = Slave address to be read 225 | * 226 | * @param RegAddress = First address of the coil to be write 227 | * 228 | * @param CoilState = coilOn or coilOff @def group coilState_t 229 | * 230 | * @funcState_t returns funcOk if the received data CRC and SlaveID is true after the sent data 231 | */ 232 | funcState_t Modbus_WriteSingleCoil(uint8_t SlaveID, uint16_t RegAddress, coilState_t CoilState) 233 | { 234 | uint16_t CRCVal = 0; 235 | 236 | funcState_t funcTxState, funcRxState; 237 | char ModbusRx[BUFFERSIZE]; 238 | char ModbusTx[8]; 239 | 240 | ModbusTx[0] = SlaveID; 241 | ModbusTx[1] = WriteSingleCoil; 242 | ModbusTx[2] = (uint8_t)(RegAddress >> 8); 243 | ModbusTx[3] = (uint8_t)(RegAddress & 0x00FF); 244 | ModbusTx[4] = CoilState; 245 | ModbusTx[5] = 0x00; 246 | 247 | CRCVal = MODBUS_CRC16(ModbusTx, 6); 248 | 249 | ModbusTx[6] = (uint8_t)(CRCVal & 0x00FF); 250 | ModbusTx[7] = CRCVal >> 8; 251 | 252 | funcTxState = sendMessage(&ModbusTx[0], 8); 253 | 254 | if(funcTxState == funcOk) 255 | { 256 | funcRxState = takeMessage(ModbusRx, 8, SlaveID); 257 | } 258 | 259 | return funcRxState; //CRC and ID is true. 260 | } 261 | 262 | /* 263 | * @brief Modbus_WriteSingleCoil, Writes Holding Register #0x15 264 | * 265 | * @param SlaveID = Slave address to be read 266 | * 267 | * @param StartAddress = First address of the coil to be read 268 | * 269 | * @param NumberOfCoils = Number of coils to be write 270 | * 271 | * @param coilValue = Array of values to write to coils 272 | * 273 | * @funcState_t returns funcOk if the received data CRC and SlaveID is true after the sent data 274 | */ 275 | funcState_t Modbus_WriteMultipleCoils(uint8_t SlaveID, uint16_t StartAddress, uint16_t NumberOfCoils, char *coilValue) 276 | { 277 | uint16_t CRCVal = 0; 278 | uint8_t i, NumberOfByte; 279 | funcState_t funcTxState, funcRxState; 280 | char ModbusRx[BUFFERSIZE]; 281 | char ModbusTx[8]; 282 | 283 | ModbusTx[0] = SlaveID; 284 | ModbusTx[1] = WriteMultipleCoils; 285 | ModbusTx[2] = (uint8_t)(StartAddress >> 8); 286 | ModbusTx[3] = (uint8_t)(StartAddress & 0x00FF); 287 | ModbusTx[4] = (uint8_t)(NumberOfCoils >> 8); 288 | ModbusTx[5] = (uint8_t)(NumberOfCoils & 0x00FF); 289 | 290 | NumberOfByte = findByte(NumberOfCoils - 1); 291 | 292 | ModbusTx[6] = NumberOfByte; 293 | 294 | for(i = 0; i < NumberOfByte ; i++) 295 | { 296 | ModbusTx[7 + i] = coilValue[i]; 297 | } 298 | 299 | CRCVal = MODBUS_CRC16(ModbusTx, 8 + i); 300 | 301 | ModbusTx[8 + i] = (uint8_t)(CRCVal & 0x00FF); 302 | ModbusTx[9 + i] = CRCVal >> 8; 303 | 304 | funcTxState = sendMessage(&ModbusTx[0], 10 + i); 305 | 306 | if(funcTxState == funcOk) 307 | { 308 | funcRxState = takeMessage(ModbusRx, 8, SlaveID); 309 | } 310 | 311 | return funcRxState; //CRC and ID is true. 312 | } 313 | 314 | /* 315 | * @brief Modbus_WriteSingleCoil, Writes Holding Register #0x16 316 | * 317 | * @param SlaveID = Slave address to be read 318 | * 319 | * @param StartAddress = First address of the coil to be read 320 | * 321 | * @param NumberOfReg = Number of registers to be write 322 | * 323 | * @param regValue = Array of values to write to registers 324 | * 325 | * @funcState_t returns funcOk if the received data CRC and SlaveID is true after the sent data 326 | */ 327 | funcState_t Modbus_WriteMultipleRegisters(uint8_t SlaveID, uint16_t StartAddress, uint16_t NumberOfReg, uint16_t *regValue) 328 | { 329 | uint16_t CRCVal = 0; 330 | uint8_t i, m = 0; 331 | funcState_t funcTxState, funcRxState; 332 | char ModbusRx[BUFFERSIZE]; 333 | char ModbusTx[8]; 334 | 335 | ModbusTx[0] = SlaveID; 336 | ModbusTx[1] = WriteMultipleRegisters; 337 | ModbusTx[2] = (uint8_t)(StartAddress >> 8); 338 | ModbusTx[3] = (uint8_t)(StartAddress & 0x00FF); 339 | ModbusTx[4] = (uint8_t)(NumberOfReg >> 8); 340 | ModbusTx[5] = (uint8_t)(NumberOfReg & 0x00FF); 341 | ModbusTx[6] = NumberOfReg * 2; 342 | 343 | for(i = 0; i < NumberOfReg * 2 ; i += 2) 344 | { 345 | ModbusTx[7 + i] = (uint8_t)(regValue[m] >> 8); 346 | ModbusTx[8 + i] = (uint8_t)(regValue[m] & 0x00FF); 347 | m++; 348 | } 349 | 350 | CRCVal = MODBUS_CRC16(ModbusTx, 8 + i); 351 | 352 | ModbusTx[8 + i] = (uint8_t)(CRCVal & 0x00FF); 353 | ModbusTx[9 + i] = CRCVal >> 8; 354 | 355 | funcTxState = sendMessage(&ModbusTx[0], 10 + i); 356 | 357 | if(funcTxState == funcOk) 358 | { 359 | funcRxState = takeMessage(ModbusRx, 8, SlaveID); 360 | } 361 | 362 | return funcRxState; //CRC and ID is true. 363 | } 364 | 365 | 366 | uint8_t findByte(int16_t NumberOfCoil) 367 | { 368 | volatile uint8_t NumberOfByte = 0; 369 | 370 | while(NumberOfCoil >= 0) 371 | { 372 | NumberOfCoil -= 8; 373 | 374 | NumberOfByte++; 375 | if(NumberOfCoil < 0) 376 | { 377 | break; 378 | } 379 | } 380 | return NumberOfByte; 381 | } 382 | 383 | uint16_t MODBUS_CRC16(char *buf, uint8_t len ) 384 | { 385 | static const uint16_t table[2] = { 0x0000, 0xA001 }; 386 | uint16_t crc = 0xFFFF; 387 | unsigned int i = 0; 388 | char bit = 0; 389 | unsigned int xor = 0; 390 | 391 | for( i = 0; i < len; i++ ) 392 | { 393 | crc ^= buf[i]; 394 | 395 | for( bit = 0; bit < 8; bit++ ) 396 | { 397 | xor = crc & 0x01; 398 | crc >>= 1; 399 | crc ^= table[xor]; 400 | } 401 | } 402 | 403 | return crc; 404 | } 405 | -------------------------------------------------------------------------------- /Core/Src/main.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.c 5 | * @brief : Main program body 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2022 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "main.h" 22 | 23 | /* Private includes ----------------------------------------------------------*/ 24 | /* USER CODE BEGIN Includes */ 25 | #include "ModbusRTU_Master.h" 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN PTD */ 30 | 31 | /* USER CODE END PTD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN PD */ 35 | /* USER CODE END PD */ 36 | 37 | /* Private macro -------------------------------------------------------------*/ 38 | /* USER CODE BEGIN PM */ 39 | 40 | /* USER CODE END PM */ 41 | 42 | /* Private variables ---------------------------------------------------------*/ 43 | UART_HandleTypeDef huart2; 44 | 45 | /* USER CODE BEGIN PV */ 46 | 47 | /* USER CODE END PV */ 48 | 49 | /* Private function prototypes -----------------------------------------------*/ 50 | void SystemClock_Config(void); 51 | static void MX_GPIO_Init(void); 52 | static void MX_USART2_UART_Init(void); 53 | /* USER CODE BEGIN PFP */ 54 | 55 | /* USER CODE END PFP */ 56 | 57 | /* Private user code ---------------------------------------------------------*/ 58 | /* USER CODE BEGIN 0 */ 59 | uint8_t count; 60 | char coilValue[1] = {0x0F}; 61 | uint16_t regValue[2] = {5, 10}; 62 | /* USER CODE END 0 */ 63 | 64 | /** 65 | * @brief The application entry point. 66 | * @retval int 67 | */ 68 | int main(void) 69 | { 70 | /* USER CODE BEGIN 1 */ 71 | 72 | /* USER CODE END 1 */ 73 | 74 | /* MCU Configuration--------------------------------------------------------*/ 75 | 76 | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 77 | HAL_Init(); 78 | 79 | /* USER CODE BEGIN Init */ 80 | 81 | /* USER CODE END Init */ 82 | 83 | /* Configure the system clock */ 84 | SystemClock_Config(); 85 | 86 | /* USER CODE BEGIN SysInit */ 87 | 88 | /* USER CODE END SysInit */ 89 | 90 | /* Initialize all configured peripherals */ 91 | MX_GPIO_Init(); 92 | MX_USART2_UART_Init(); 93 | /* USER CODE BEGIN 2 */ 94 | 95 | /* USER CODE END 2 */ 96 | 97 | /* Infinite loop */ 98 | /* USER CODE BEGIN WHILE */ 99 | while (1) 100 | { 101 | /* USER CODE END WHILE */ 102 | 103 | /* USER CODE BEGIN 3 */ 104 | HAL_Delay(1000); 105 | Modbus_WriteMultipleRegisters(1, 0, 2, ®Value[0]); 106 | //Modbus_WriteMultipleCoils(1, 0, 8, &coilValue[0]); 107 | //Modbus_ReadCoil(1, 0, 10); 108 | //HAL_Delay(1000); 109 | //Modbus_WriteSingleCoil(1, 5, coilOn); 110 | //Modbus_ReadHoldingRegister(1, 0, 5); 111 | //HAL_Delay(1000); 112 | //Modbus_WriteSingleRegister(1, 3, count++); 113 | } 114 | /* USER CODE END 3 */ 115 | } 116 | 117 | /** 118 | * @brief System Clock Configuration 119 | * @retval None 120 | */ 121 | void SystemClock_Config(void) 122 | { 123 | RCC_OscInitTypeDef RCC_OscInitStruct = {0}; 124 | RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; 125 | 126 | /** Configure the main internal regulator output voltage 127 | */ 128 | __HAL_RCC_PWR_CLK_ENABLE(); 129 | __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); 130 | /** Initializes the RCC Oscillators according to the specified parameters 131 | * in the RCC_OscInitTypeDef structure. 132 | */ 133 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; 134 | RCC_OscInitStruct.HSIState = RCC_HSI_ON; 135 | RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; 136 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 137 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 138 | { 139 | Error_Handler(); 140 | } 141 | /** Initializes the CPU, AHB and APB buses clocks 142 | */ 143 | RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 144 | |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; 145 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; 146 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 147 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; 148 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 149 | 150 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) 151 | { 152 | Error_Handler(); 153 | } 154 | } 155 | 156 | /** 157 | * @brief USART2 Initialization Function 158 | * @param None 159 | * @retval None 160 | */ 161 | static void MX_USART2_UART_Init(void) 162 | { 163 | 164 | /* USER CODE BEGIN USART2_Init 0 */ 165 | 166 | /* USER CODE END USART2_Init 0 */ 167 | 168 | /* USER CODE BEGIN USART2_Init 1 */ 169 | 170 | /* USER CODE END USART2_Init 1 */ 171 | huart2.Instance = USART2; 172 | huart2.Init.BaudRate = 115200; 173 | huart2.Init.WordLength = UART_WORDLENGTH_8B; 174 | huart2.Init.StopBits = UART_STOPBITS_1; 175 | huart2.Init.Parity = UART_PARITY_NONE; 176 | huart2.Init.Mode = UART_MODE_TX_RX; 177 | huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; 178 | huart2.Init.OverSampling = UART_OVERSAMPLING_16; 179 | if (HAL_UART_Init(&huart2) != HAL_OK) 180 | { 181 | Error_Handler(); 182 | } 183 | /* USER CODE BEGIN USART2_Init 2 */ 184 | 185 | /* USER CODE END USART2_Init 2 */ 186 | 187 | } 188 | 189 | /** 190 | * @brief GPIO Initialization Function 191 | * @param None 192 | * @retval None 193 | */ 194 | static void MX_GPIO_Init(void) 195 | { 196 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 197 | 198 | /* GPIO Ports Clock Enable */ 199 | __HAL_RCC_GPIOA_CLK_ENABLE(); 200 | __HAL_RCC_GPIOD_CLK_ENABLE(); 201 | 202 | /*Configure GPIO pin Output Level */ 203 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET); 204 | 205 | /*Configure GPIO pins : PD12 PD13 PD14 PD15 */ 206 | GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; 207 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 208 | GPIO_InitStruct.Pull = GPIO_NOPULL; 209 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 210 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 211 | 212 | } 213 | 214 | /* USER CODE BEGIN 4 */ 215 | 216 | /* USER CODE END 4 */ 217 | 218 | /** 219 | * @brief This function is executed in case of error occurrence. 220 | * @retval None 221 | */ 222 | void Error_Handler(void) 223 | { 224 | /* USER CODE BEGIN Error_Handler_Debug */ 225 | /* User can add his own implementation to report the HAL error return state */ 226 | __disable_irq(); 227 | while (1) 228 | { 229 | } 230 | /* USER CODE END Error_Handler_Debug */ 231 | } 232 | 233 | #ifdef USE_FULL_ASSERT 234 | /** 235 | * @brief Reports the name of the source file and the source line number 236 | * where the assert_param error has occurred. 237 | * @param file: pointer to the source file name 238 | * @param line: assert_param error line source number 239 | * @retval None 240 | */ 241 | void assert_failed(uint8_t *file, uint32_t line) 242 | { 243 | /* USER CODE BEGIN 6 */ 244 | /* User can add his own implementation to report the file name and line number, 245 | ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 246 | /* USER CODE END 6 */ 247 | } 248 | #endif /* USE_FULL_ASSERT */ 249 | 250 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 251 | -------------------------------------------------------------------------------- /Core/Src/stm32f4xx_hal_msp.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_hal_msp.c 5 | * @brief This file provides code for the MSP Initialization 6 | * and de-Initialization codes. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2022 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Includes ------------------------------------------------------------------*/ 23 | #include "main.h" 24 | /* USER CODE BEGIN Includes */ 25 | 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN Define */ 35 | 36 | /* USER CODE END Define */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN Macro */ 40 | 41 | /* USER CODE END Macro */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* External functions --------------------------------------------------------*/ 54 | /* USER CODE BEGIN ExternalFunctions */ 55 | 56 | /* USER CODE END ExternalFunctions */ 57 | 58 | /* USER CODE BEGIN 0 */ 59 | 60 | /* USER CODE END 0 */ 61 | /** 62 | * Initializes the Global MSP. 63 | */ 64 | void HAL_MspInit(void) 65 | { 66 | /* USER CODE BEGIN MspInit 0 */ 67 | 68 | /* USER CODE END MspInit 0 */ 69 | 70 | __HAL_RCC_SYSCFG_CLK_ENABLE(); 71 | __HAL_RCC_PWR_CLK_ENABLE(); 72 | 73 | /* System interrupt init*/ 74 | 75 | /* USER CODE BEGIN MspInit 1 */ 76 | 77 | /* USER CODE END MspInit 1 */ 78 | } 79 | 80 | /** 81 | * @brief UART MSP Initialization 82 | * This function configures the hardware resources used in this example 83 | * @param huart: UART handle pointer 84 | * @retval None 85 | */ 86 | void HAL_UART_MspInit(UART_HandleTypeDef* huart) 87 | { 88 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 89 | if(huart->Instance==USART2) 90 | { 91 | /* USER CODE BEGIN USART2_MspInit 0 */ 92 | 93 | /* USER CODE END USART2_MspInit 0 */ 94 | /* Peripheral clock enable */ 95 | __HAL_RCC_USART2_CLK_ENABLE(); 96 | 97 | __HAL_RCC_GPIOA_CLK_ENABLE(); 98 | /**USART2 GPIO Configuration 99 | PA2 ------> USART2_TX 100 | PA3 ------> USART2_RX 101 | */ 102 | GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; 103 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 104 | GPIO_InitStruct.Pull = GPIO_NOPULL; 105 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; 106 | GPIO_InitStruct.Alternate = GPIO_AF7_USART2; 107 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 108 | 109 | /* USART2 interrupt Init */ 110 | HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); 111 | HAL_NVIC_EnableIRQ(USART2_IRQn); 112 | /* USER CODE BEGIN USART2_MspInit 1 */ 113 | 114 | /* USER CODE END USART2_MspInit 1 */ 115 | } 116 | 117 | } 118 | 119 | /** 120 | * @brief UART MSP De-Initialization 121 | * This function freeze the hardware resources used in this example 122 | * @param huart: UART handle pointer 123 | * @retval None 124 | */ 125 | void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) 126 | { 127 | if(huart->Instance==USART2) 128 | { 129 | /* USER CODE BEGIN USART2_MspDeInit 0 */ 130 | 131 | /* USER CODE END USART2_MspDeInit 0 */ 132 | /* Peripheral clock disable */ 133 | __HAL_RCC_USART2_CLK_DISABLE(); 134 | 135 | /**USART2 GPIO Configuration 136 | PA2 ------> USART2_TX 137 | PA3 ------> USART2_RX 138 | */ 139 | HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); 140 | 141 | /* USART2 interrupt DeInit */ 142 | HAL_NVIC_DisableIRQ(USART2_IRQn); 143 | /* USER CODE BEGIN USART2_MspDeInit 1 */ 144 | 145 | /* USER CODE END USART2_MspDeInit 1 */ 146 | } 147 | 148 | } 149 | 150 | /* USER CODE BEGIN 1 */ 151 | 152 | /* USER CODE END 1 */ 153 | 154 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 155 | -------------------------------------------------------------------------------- /Core/Src/stm32f4xx_it.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_it.c 5 | * @brief Interrupt Service Routines. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2022 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "main.h" 23 | #include "stm32f4xx_it.h" 24 | /* Private includes ----------------------------------------------------------*/ 25 | /* USER CODE BEGIN Includes */ 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN PD */ 35 | 36 | /* USER CODE END PD */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN PM */ 40 | 41 | /* USER CODE END PM */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* Private user code ---------------------------------------------------------*/ 54 | /* USER CODE BEGIN 0 */ 55 | 56 | /* USER CODE END 0 */ 57 | 58 | /* External variables --------------------------------------------------------*/ 59 | extern UART_HandleTypeDef huart2; 60 | /* USER CODE BEGIN EV */ 61 | 62 | /* USER CODE END EV */ 63 | 64 | /******************************************************************************/ 65 | /* Cortex-M4 Processor Interruption and Exception Handlers */ 66 | /******************************************************************************/ 67 | /** 68 | * @brief This function handles Non maskable interrupt. 69 | */ 70 | void NMI_Handler(void) 71 | { 72 | /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ 73 | 74 | /* USER CODE END NonMaskableInt_IRQn 0 */ 75 | /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ 76 | while (1) 77 | { 78 | } 79 | /* USER CODE END NonMaskableInt_IRQn 1 */ 80 | } 81 | 82 | /** 83 | * @brief This function handles Hard fault interrupt. 84 | */ 85 | void HardFault_Handler(void) 86 | { 87 | /* USER CODE BEGIN HardFault_IRQn 0 */ 88 | 89 | /* USER CODE END HardFault_IRQn 0 */ 90 | while (1) 91 | { 92 | /* USER CODE BEGIN W1_HardFault_IRQn 0 */ 93 | /* USER CODE END W1_HardFault_IRQn 0 */ 94 | } 95 | } 96 | 97 | /** 98 | * @brief This function handles Memory management fault. 99 | */ 100 | void MemManage_Handler(void) 101 | { 102 | /* USER CODE BEGIN MemoryManagement_IRQn 0 */ 103 | 104 | /* USER CODE END MemoryManagement_IRQn 0 */ 105 | while (1) 106 | { 107 | /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ 108 | /* USER CODE END W1_MemoryManagement_IRQn 0 */ 109 | } 110 | } 111 | 112 | /** 113 | * @brief This function handles Pre-fetch fault, memory access fault. 114 | */ 115 | void BusFault_Handler(void) 116 | { 117 | /* USER CODE BEGIN BusFault_IRQn 0 */ 118 | 119 | /* USER CODE END BusFault_IRQn 0 */ 120 | while (1) 121 | { 122 | /* USER CODE BEGIN W1_BusFault_IRQn 0 */ 123 | /* USER CODE END W1_BusFault_IRQn 0 */ 124 | } 125 | } 126 | 127 | /** 128 | * @brief This function handles Undefined instruction or illegal state. 129 | */ 130 | void UsageFault_Handler(void) 131 | { 132 | /* USER CODE BEGIN UsageFault_IRQn 0 */ 133 | 134 | /* USER CODE END UsageFault_IRQn 0 */ 135 | while (1) 136 | { 137 | /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ 138 | /* USER CODE END W1_UsageFault_IRQn 0 */ 139 | } 140 | } 141 | 142 | /** 143 | * @brief This function handles System service call via SWI instruction. 144 | */ 145 | void SVC_Handler(void) 146 | { 147 | /* USER CODE BEGIN SVCall_IRQn 0 */ 148 | 149 | /* USER CODE END SVCall_IRQn 0 */ 150 | /* USER CODE BEGIN SVCall_IRQn 1 */ 151 | 152 | /* USER CODE END SVCall_IRQn 1 */ 153 | } 154 | 155 | /** 156 | * @brief This function handles Debug monitor. 157 | */ 158 | void DebugMon_Handler(void) 159 | { 160 | /* USER CODE BEGIN DebugMonitor_IRQn 0 */ 161 | 162 | /* USER CODE END DebugMonitor_IRQn 0 */ 163 | /* USER CODE BEGIN DebugMonitor_IRQn 1 */ 164 | 165 | /* USER CODE END DebugMonitor_IRQn 1 */ 166 | } 167 | 168 | /** 169 | * @brief This function handles Pendable request for system service. 170 | */ 171 | void PendSV_Handler(void) 172 | { 173 | /* USER CODE BEGIN PendSV_IRQn 0 */ 174 | 175 | /* USER CODE END PendSV_IRQn 0 */ 176 | /* USER CODE BEGIN PendSV_IRQn 1 */ 177 | 178 | /* USER CODE END PendSV_IRQn 1 */ 179 | } 180 | 181 | /** 182 | * @brief This function handles System tick timer. 183 | */ 184 | void SysTick_Handler(void) 185 | { 186 | /* USER CODE BEGIN SysTick_IRQn 0 */ 187 | 188 | /* USER CODE END SysTick_IRQn 0 */ 189 | HAL_IncTick(); 190 | /* USER CODE BEGIN SysTick_IRQn 1 */ 191 | 192 | /* USER CODE END SysTick_IRQn 1 */ 193 | } 194 | 195 | /******************************************************************************/ 196 | /* STM32F4xx Peripheral Interrupt Handlers */ 197 | /* Add here the Interrupt Handlers for the used peripherals. */ 198 | /* For the available peripheral interrupt handler names, */ 199 | /* please refer to the startup file (startup_stm32f4xx.s). */ 200 | /******************************************************************************/ 201 | 202 | /** 203 | * @brief This function handles USART2 global interrupt. 204 | */ 205 | void USART2_IRQHandler(void) 206 | { 207 | /* USER CODE BEGIN USART2_IRQn 0 */ 208 | 209 | /* USER CODE END USART2_IRQn 0 */ 210 | HAL_UART_IRQHandler(&huart2); 211 | /* USER CODE BEGIN USART2_IRQn 1 */ 212 | 213 | /* USER CODE END USART2_IRQn 1 */ 214 | } 215 | 216 | /* USER CODE BEGIN 1 */ 217 | 218 | /* USER CODE END 1 */ 219 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 220 | -------------------------------------------------------------------------------- /Core/Src/syscalls.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file syscalls.c 4 | * @author Auto-generated by STM32CubeIDE 5 | * @brief STM32CubeIDE Minimal System calls file 6 | * 7 | * For more information about which c-functions 8 | * need which of these lowlevel functions 9 | * please consult the Newlib libc-manual 10 | ****************************************************************************** 11 | * @attention 12 | * 13 | *

© Copyright (c) 2020 STMicroelectronics. 14 | * All rights reserved.

15 | * 16 | * This software component is licensed by ST under BSD 3-Clause license, 17 | * the "License"; You may not use this file except in compliance with the 18 | * License. You may obtain a copy of the License at: 19 | * opensource.org/licenses/BSD-3-Clause 20 | * 21 | ****************************************************************************** 22 | */ 23 | 24 | /* Includes */ 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | 35 | /* Variables */ 36 | extern int __io_putchar(int ch) __attribute__((weak)); 37 | extern int __io_getchar(void) __attribute__((weak)); 38 | 39 | 40 | char *__env[1] = { 0 }; 41 | char **environ = __env; 42 | 43 | 44 | /* Functions */ 45 | void initialise_monitor_handles() 46 | { 47 | } 48 | 49 | int _getpid(void) 50 | { 51 | return 1; 52 | } 53 | 54 | int _kill(int pid, int sig) 55 | { 56 | errno = EINVAL; 57 | return -1; 58 | } 59 | 60 | void _exit (int status) 61 | { 62 | _kill(status, -1); 63 | while (1) {} /* Make sure we hang here */ 64 | } 65 | 66 | __attribute__((weak)) int _read(int file, char *ptr, int len) 67 | { 68 | int DataIdx; 69 | 70 | for (DataIdx = 0; DataIdx < len; DataIdx++) 71 | { 72 | *ptr++ = __io_getchar(); 73 | } 74 | 75 | return len; 76 | } 77 | 78 | __attribute__((weak)) int _write(int file, char *ptr, int len) 79 | { 80 | int DataIdx; 81 | 82 | for (DataIdx = 0; DataIdx < len; DataIdx++) 83 | { 84 | __io_putchar(*ptr++); 85 | } 86 | return len; 87 | } 88 | 89 | int _close(int file) 90 | { 91 | return -1; 92 | } 93 | 94 | 95 | int _fstat(int file, struct stat *st) 96 | { 97 | st->st_mode = S_IFCHR; 98 | return 0; 99 | } 100 | 101 | int _isatty(int file) 102 | { 103 | return 1; 104 | } 105 | 106 | int _lseek(int file, int ptr, int dir) 107 | { 108 | return 0; 109 | } 110 | 111 | int _open(char *path, int flags, ...) 112 | { 113 | /* Pretend like we always fail */ 114 | return -1; 115 | } 116 | 117 | int _wait(int *status) 118 | { 119 | errno = ECHILD; 120 | return -1; 121 | } 122 | 123 | int _unlink(char *name) 124 | { 125 | errno = ENOENT; 126 | return -1; 127 | } 128 | 129 | int _times(struct tms *buf) 130 | { 131 | return -1; 132 | } 133 | 134 | int _stat(char *file, struct stat *st) 135 | { 136 | st->st_mode = S_IFCHR; 137 | return 0; 138 | } 139 | 140 | int _link(char *old, char *new) 141 | { 142 | errno = EMLINK; 143 | return -1; 144 | } 145 | 146 | int _fork(void) 147 | { 148 | errno = EAGAIN; 149 | return -1; 150 | } 151 | 152 | int _execve(char *name, char **argv, char **env) 153 | { 154 | errno = ENOMEM; 155 | return -1; 156 | } 157 | -------------------------------------------------------------------------------- /Core/Src/sysmem.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file sysmem.c 4 | * @author Generated by STM32CubeIDE 5 | * @brief STM32CubeIDE System Memory calls file 6 | * 7 | * For more information about which C functions 8 | * need which of these lowlevel functions 9 | * please consult the newlib libc manual 10 | ****************************************************************************** 11 | * @attention 12 | * 13 | *

© Copyright (c) 2020 STMicroelectronics. 14 | * All rights reserved.

15 | * 16 | * This software component is licensed by ST under BSD 3-Clause license, 17 | * the "License"; You may not use this file except in compliance with the 18 | * License. You may obtain a copy of the License at: 19 | * opensource.org/licenses/BSD-3-Clause 20 | * 21 | ****************************************************************************** 22 | */ 23 | 24 | /* Includes */ 25 | #include 26 | #include 27 | 28 | /** 29 | * Pointer to the current high watermark of the heap usage 30 | */ 31 | static uint8_t *__sbrk_heap_end = NULL; 32 | 33 | /** 34 | * @brief _sbrk() allocates memory to the newlib heap and is used by malloc 35 | * and others from the C library 36 | * 37 | * @verbatim 38 | * ############################################################################ 39 | * # .data # .bss # newlib heap # MSP stack # 40 | * # # # # Reserved by _Min_Stack_Size # 41 | * ############################################################################ 42 | * ^-- RAM start ^-- _end _estack, RAM end --^ 43 | * @endverbatim 44 | * 45 | * This implementation starts allocating at the '_end' linker symbol 46 | * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack 47 | * The implementation considers '_estack' linker symbol to be RAM end 48 | * NOTE: If the MSP stack, at any point during execution, grows larger than the 49 | * reserved size, please increase the '_Min_Stack_Size'. 50 | * 51 | * @param incr Memory size 52 | * @return Pointer to allocated memory 53 | */ 54 | void *_sbrk(ptrdiff_t incr) 55 | { 56 | extern uint8_t _end; /* Symbol defined in the linker script */ 57 | extern uint8_t _estack; /* Symbol defined in the linker script */ 58 | extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ 59 | const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; 60 | const uint8_t *max_heap = (uint8_t *)stack_limit; 61 | uint8_t *prev_heap_end; 62 | 63 | /* Initialize heap end at first call */ 64 | if (NULL == __sbrk_heap_end) 65 | { 66 | __sbrk_heap_end = &_end; 67 | } 68 | 69 | /* Protect heap from growing into the reserved MSP stack */ 70 | if (__sbrk_heap_end + incr > max_heap) 71 | { 72 | errno = ENOMEM; 73 | return (void *)-1; 74 | } 75 | 76 | prev_heap_end = __sbrk_heap_end; 77 | __sbrk_heap_end += incr; 78 | 79 | return (void *)prev_heap_end; 80 | } 81 | -------------------------------------------------------------------------------- /Core/Src/system_stm32f4xx.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f4xx.c 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. 6 | * 7 | * This file provides two functions and one global variable to be called from 8 | * user application: 9 | * - SystemInit(): This function is called at startup just after reset and 10 | * before branch to main program. This call is made inside 11 | * the "startup_stm32f4xx.s" file. 12 | * 13 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 14 | * by the user application to setup the SysTick 15 | * timer or configure other parameters. 16 | * 17 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 18 | * be called whenever the core clock is changed 19 | * during program execution. 20 | * 21 | * 22 | ****************************************************************************** 23 | * @attention 24 | * 25 | *

© Copyright (c) 2017 STMicroelectronics. 26 | * All rights reserved.

27 | * 28 | * This software component is licensed by ST under BSD 3-Clause license, 29 | * the "License"; You may not use this file except in compliance with the 30 | * License. You may obtain a copy of the License at: 31 | * opensource.org/licenses/BSD-3-Clause 32 | * 33 | ****************************************************************************** 34 | */ 35 | 36 | /** @addtogroup CMSIS 37 | * @{ 38 | */ 39 | 40 | /** @addtogroup stm32f4xx_system 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup STM32F4xx_System_Private_Includes 45 | * @{ 46 | */ 47 | 48 | 49 | #include "stm32f4xx.h" 50 | 51 | #if !defined (HSE_VALUE) 52 | #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ 53 | #endif /* HSE_VALUE */ 54 | 55 | #if !defined (HSI_VALUE) 56 | #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ 57 | #endif /* HSI_VALUE */ 58 | 59 | /** 60 | * @} 61 | */ 62 | 63 | /** @addtogroup STM32F4xx_System_Private_TypesDefinitions 64 | * @{ 65 | */ 66 | 67 | /** 68 | * @} 69 | */ 70 | 71 | /** @addtogroup STM32F4xx_System_Private_Defines 72 | * @{ 73 | */ 74 | 75 | /************************* Miscellaneous Configuration ************************/ 76 | /*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */ 77 | #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ 78 | || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ 79 | || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) 80 | /* #define DATA_IN_ExtSRAM */ 81 | #endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\ 82 | STM32F412Zx || STM32F412Vx */ 83 | 84 | #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ 85 | || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) 86 | /* #define DATA_IN_ExtSDRAM */ 87 | #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\ 88 | STM32F479xx */ 89 | 90 | /* Note: Following vector table addresses must be defined in line with linker 91 | configuration. */ 92 | /*!< Uncomment the following line if you need to relocate the vector table 93 | anywhere in Flash or Sram, else the vector table is kept at the automatic 94 | remap of boot address selected */ 95 | /* #define USER_VECT_TAB_ADDRESS */ 96 | 97 | #if defined(USER_VECT_TAB_ADDRESS) 98 | /*!< Uncomment the following line if you need to relocate your vector Table 99 | in Sram else user remap will be done in Flash. */ 100 | /* #define VECT_TAB_SRAM */ 101 | #if defined(VECT_TAB_SRAM) 102 | #define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. 103 | This value must be a multiple of 0x200. */ 104 | #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. 105 | This value must be a multiple of 0x200. */ 106 | #else 107 | #define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. 108 | This value must be a multiple of 0x200. */ 109 | #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. 110 | This value must be a multiple of 0x200. */ 111 | #endif /* VECT_TAB_SRAM */ 112 | #endif /* USER_VECT_TAB_ADDRESS */ 113 | /******************************************************************************/ 114 | 115 | /** 116 | * @} 117 | */ 118 | 119 | /** @addtogroup STM32F4xx_System_Private_Macros 120 | * @{ 121 | */ 122 | 123 | /** 124 | * @} 125 | */ 126 | 127 | /** @addtogroup STM32F4xx_System_Private_Variables 128 | * @{ 129 | */ 130 | /* This variable is updated in three ways: 131 | 1) by calling CMSIS function SystemCoreClockUpdate() 132 | 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 133 | 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 134 | Note: If you use this function to configure the system clock; then there 135 | is no need to call the 2 first functions listed above, since SystemCoreClock 136 | variable is updated automatically. 137 | */ 138 | uint32_t SystemCoreClock = 16000000; 139 | const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 140 | const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; 141 | /** 142 | * @} 143 | */ 144 | 145 | /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes 146 | * @{ 147 | */ 148 | 149 | #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) 150 | static void SystemInit_ExtMemCtl(void); 151 | #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ 152 | 153 | /** 154 | * @} 155 | */ 156 | 157 | /** @addtogroup STM32F4xx_System_Private_Functions 158 | * @{ 159 | */ 160 | 161 | /** 162 | * @brief Setup the microcontroller system 163 | * Initialize the FPU setting, vector table location and External memory 164 | * configuration. 165 | * @param None 166 | * @retval None 167 | */ 168 | void SystemInit(void) 169 | { 170 | /* FPU settings ------------------------------------------------------------*/ 171 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 172 | SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ 173 | #endif 174 | 175 | #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) 176 | SystemInit_ExtMemCtl(); 177 | #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ 178 | 179 | /* Configure the Vector Table location -------------------------------------*/ 180 | #if defined(USER_VECT_TAB_ADDRESS) 181 | SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ 182 | #endif /* USER_VECT_TAB_ADDRESS */ 183 | } 184 | 185 | /** 186 | * @brief Update SystemCoreClock variable according to Clock Register Values. 187 | * The SystemCoreClock variable contains the core clock (HCLK), it can 188 | * be used by the user application to setup the SysTick timer or configure 189 | * other parameters. 190 | * 191 | * @note Each time the core clock (HCLK) changes, this function must be called 192 | * to update SystemCoreClock variable value. Otherwise, any configuration 193 | * based on this variable will be incorrect. 194 | * 195 | * @note - The system frequency computed by this function is not the real 196 | * frequency in the chip. It is calculated based on the predefined 197 | * constant and the selected clock source: 198 | * 199 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 200 | * 201 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 202 | * 203 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 204 | * or HSI_VALUE(*) multiplied/divided by the PLL factors. 205 | * 206 | * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value 207 | * 16 MHz) but the real value may vary depending on the variations 208 | * in voltage and temperature. 209 | * 210 | * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value 211 | * depends on the application requirements), user has to ensure that HSE_VALUE 212 | * is same as the real frequency of the crystal used. Otherwise, this function 213 | * may have wrong result. 214 | * 215 | * - The result of this function could be not correct when using fractional 216 | * value for HSE crystal. 217 | * 218 | * @param None 219 | * @retval None 220 | */ 221 | void SystemCoreClockUpdate(void) 222 | { 223 | uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; 224 | 225 | /* Get SYSCLK source -------------------------------------------------------*/ 226 | tmp = RCC->CFGR & RCC_CFGR_SWS; 227 | 228 | switch (tmp) 229 | { 230 | case 0x00: /* HSI used as system clock source */ 231 | SystemCoreClock = HSI_VALUE; 232 | break; 233 | case 0x04: /* HSE used as system clock source */ 234 | SystemCoreClock = HSE_VALUE; 235 | break; 236 | case 0x08: /* PLL used as system clock source */ 237 | 238 | /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N 239 | SYSCLK = PLL_VCO / PLL_P 240 | */ 241 | pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; 242 | pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; 243 | 244 | if (pllsource != 0) 245 | { 246 | /* HSE used as PLL clock source */ 247 | pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); 248 | } 249 | else 250 | { 251 | /* HSI used as PLL clock source */ 252 | pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); 253 | } 254 | 255 | pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; 256 | SystemCoreClock = pllvco/pllp; 257 | break; 258 | default: 259 | SystemCoreClock = HSI_VALUE; 260 | break; 261 | } 262 | /* Compute HCLK frequency --------------------------------------------------*/ 263 | /* Get HCLK prescaler */ 264 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 265 | /* HCLK frequency */ 266 | SystemCoreClock >>= tmp; 267 | } 268 | 269 | #if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM) 270 | #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ 271 | || defined(STM32F469xx) || defined(STM32F479xx) 272 | /** 273 | * @brief Setup the external memory controller. 274 | * Called in startup_stm32f4xx.s before jump to main. 275 | * This function configures the external memories (SRAM/SDRAM) 276 | * This SRAM/SDRAM will be used as program data memory (including heap and stack). 277 | * @param None 278 | * @retval None 279 | */ 280 | void SystemInit_ExtMemCtl(void) 281 | { 282 | __IO uint32_t tmp = 0x00; 283 | 284 | register uint32_t tmpreg = 0, timeout = 0xFFFF; 285 | register __IO uint32_t index; 286 | 287 | /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */ 288 | RCC->AHB1ENR |= 0x000001F8; 289 | 290 | /* Delay after an RCC peripheral clock enabling */ 291 | tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); 292 | 293 | /* Connect PDx pins to FMC Alternate function */ 294 | GPIOD->AFR[0] = 0x00CCC0CC; 295 | GPIOD->AFR[1] = 0xCCCCCCCC; 296 | /* Configure PDx pins in Alternate function mode */ 297 | GPIOD->MODER = 0xAAAA0A8A; 298 | /* Configure PDx pins speed to 100 MHz */ 299 | GPIOD->OSPEEDR = 0xFFFF0FCF; 300 | /* Configure PDx pins Output type to push-pull */ 301 | GPIOD->OTYPER = 0x00000000; 302 | /* No pull-up, pull-down for PDx pins */ 303 | GPIOD->PUPDR = 0x00000000; 304 | 305 | /* Connect PEx pins to FMC Alternate function */ 306 | GPIOE->AFR[0] = 0xC00CC0CC; 307 | GPIOE->AFR[1] = 0xCCCCCCCC; 308 | /* Configure PEx pins in Alternate function mode */ 309 | GPIOE->MODER = 0xAAAA828A; 310 | /* Configure PEx pins speed to 100 MHz */ 311 | GPIOE->OSPEEDR = 0xFFFFC3CF; 312 | /* Configure PEx pins Output type to push-pull */ 313 | GPIOE->OTYPER = 0x00000000; 314 | /* No pull-up, pull-down for PEx pins */ 315 | GPIOE->PUPDR = 0x00000000; 316 | 317 | /* Connect PFx pins to FMC Alternate function */ 318 | GPIOF->AFR[0] = 0xCCCCCCCC; 319 | GPIOF->AFR[1] = 0xCCCCCCCC; 320 | /* Configure PFx pins in Alternate function mode */ 321 | GPIOF->MODER = 0xAA800AAA; 322 | /* Configure PFx pins speed to 50 MHz */ 323 | GPIOF->OSPEEDR = 0xAA800AAA; 324 | /* Configure PFx pins Output type to push-pull */ 325 | GPIOF->OTYPER = 0x00000000; 326 | /* No pull-up, pull-down for PFx pins */ 327 | GPIOF->PUPDR = 0x00000000; 328 | 329 | /* Connect PGx pins to FMC Alternate function */ 330 | GPIOG->AFR[0] = 0xCCCCCCCC; 331 | GPIOG->AFR[1] = 0xCCCCCCCC; 332 | /* Configure PGx pins in Alternate function mode */ 333 | GPIOG->MODER = 0xAAAAAAAA; 334 | /* Configure PGx pins speed to 50 MHz */ 335 | GPIOG->OSPEEDR = 0xAAAAAAAA; 336 | /* Configure PGx pins Output type to push-pull */ 337 | GPIOG->OTYPER = 0x00000000; 338 | /* No pull-up, pull-down for PGx pins */ 339 | GPIOG->PUPDR = 0x00000000; 340 | 341 | /* Connect PHx pins to FMC Alternate function */ 342 | GPIOH->AFR[0] = 0x00C0CC00; 343 | GPIOH->AFR[1] = 0xCCCCCCCC; 344 | /* Configure PHx pins in Alternate function mode */ 345 | GPIOH->MODER = 0xAAAA08A0; 346 | /* Configure PHx pins speed to 50 MHz */ 347 | GPIOH->OSPEEDR = 0xAAAA08A0; 348 | /* Configure PHx pins Output type to push-pull */ 349 | GPIOH->OTYPER = 0x00000000; 350 | /* No pull-up, pull-down for PHx pins */ 351 | GPIOH->PUPDR = 0x00000000; 352 | 353 | /* Connect PIx pins to FMC Alternate function */ 354 | GPIOI->AFR[0] = 0xCCCCCCCC; 355 | GPIOI->AFR[1] = 0x00000CC0; 356 | /* Configure PIx pins in Alternate function mode */ 357 | GPIOI->MODER = 0x0028AAAA; 358 | /* Configure PIx pins speed to 50 MHz */ 359 | GPIOI->OSPEEDR = 0x0028AAAA; 360 | /* Configure PIx pins Output type to push-pull */ 361 | GPIOI->OTYPER = 0x00000000; 362 | /* No pull-up, pull-down for PIx pins */ 363 | GPIOI->PUPDR = 0x00000000; 364 | 365 | /*-- FMC Configuration -------------------------------------------------------*/ 366 | /* Enable the FMC interface clock */ 367 | RCC->AHB3ENR |= 0x00000001; 368 | /* Delay after an RCC peripheral clock enabling */ 369 | tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); 370 | 371 | FMC_Bank5_6->SDCR[0] = 0x000019E4; 372 | FMC_Bank5_6->SDTR[0] = 0x01115351; 373 | 374 | /* SDRAM initialization sequence */ 375 | /* Clock enable command */ 376 | FMC_Bank5_6->SDCMR = 0x00000011; 377 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 378 | while((tmpreg != 0) && (timeout-- > 0)) 379 | { 380 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 381 | } 382 | 383 | /* Delay */ 384 | for (index = 0; index<1000; index++); 385 | 386 | /* PALL command */ 387 | FMC_Bank5_6->SDCMR = 0x00000012; 388 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 389 | timeout = 0xFFFF; 390 | while((tmpreg != 0) && (timeout-- > 0)) 391 | { 392 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 393 | } 394 | 395 | /* Auto refresh command */ 396 | FMC_Bank5_6->SDCMR = 0x00000073; 397 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 398 | timeout = 0xFFFF; 399 | while((tmpreg != 0) && (timeout-- > 0)) 400 | { 401 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 402 | } 403 | 404 | /* MRD register program */ 405 | FMC_Bank5_6->SDCMR = 0x00046014; 406 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 407 | timeout = 0xFFFF; 408 | while((tmpreg != 0) && (timeout-- > 0)) 409 | { 410 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 411 | } 412 | 413 | /* Set refresh count */ 414 | tmpreg = FMC_Bank5_6->SDRTR; 415 | FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); 416 | 417 | /* Disable write protection */ 418 | tmpreg = FMC_Bank5_6->SDCR[0]; 419 | FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); 420 | 421 | #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) 422 | /* Configure and enable Bank1_SRAM2 */ 423 | FMC_Bank1->BTCR[2] = 0x00001011; 424 | FMC_Bank1->BTCR[3] = 0x00000201; 425 | FMC_Bank1E->BWTR[2] = 0x0fffffff; 426 | #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ 427 | #if defined(STM32F469xx) || defined(STM32F479xx) 428 | /* Configure and enable Bank1_SRAM2 */ 429 | FMC_Bank1->BTCR[2] = 0x00001091; 430 | FMC_Bank1->BTCR[3] = 0x00110212; 431 | FMC_Bank1E->BWTR[2] = 0x0fffffff; 432 | #endif /* STM32F469xx || STM32F479xx */ 433 | 434 | (void)(tmp); 435 | } 436 | #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ 437 | #elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) 438 | /** 439 | * @brief Setup the external memory controller. 440 | * Called in startup_stm32f4xx.s before jump to main. 441 | * This function configures the external memories (SRAM/SDRAM) 442 | * This SRAM/SDRAM will be used as program data memory (including heap and stack). 443 | * @param None 444 | * @retval None 445 | */ 446 | void SystemInit_ExtMemCtl(void) 447 | { 448 | __IO uint32_t tmp = 0x00; 449 | #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ 450 | || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) 451 | #if defined (DATA_IN_ExtSDRAM) 452 | register uint32_t tmpreg = 0, timeout = 0xFFFF; 453 | register __IO uint32_t index; 454 | 455 | #if defined(STM32F446xx) 456 | /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface 457 | clock */ 458 | RCC->AHB1ENR |= 0x0000007D; 459 | #else 460 | /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface 461 | clock */ 462 | RCC->AHB1ENR |= 0x000001F8; 463 | #endif /* STM32F446xx */ 464 | /* Delay after an RCC peripheral clock enabling */ 465 | tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); 466 | 467 | #if defined(STM32F446xx) 468 | /* Connect PAx pins to FMC Alternate function */ 469 | GPIOA->AFR[0] |= 0xC0000000; 470 | GPIOA->AFR[1] |= 0x00000000; 471 | /* Configure PDx pins in Alternate function mode */ 472 | GPIOA->MODER |= 0x00008000; 473 | /* Configure PDx pins speed to 50 MHz */ 474 | GPIOA->OSPEEDR |= 0x00008000; 475 | /* Configure PDx pins Output type to push-pull */ 476 | GPIOA->OTYPER |= 0x00000000; 477 | /* No pull-up, pull-down for PDx pins */ 478 | GPIOA->PUPDR |= 0x00000000; 479 | 480 | /* Connect PCx pins to FMC Alternate function */ 481 | GPIOC->AFR[0] |= 0x00CC0000; 482 | GPIOC->AFR[1] |= 0x00000000; 483 | /* Configure PDx pins in Alternate function mode */ 484 | GPIOC->MODER |= 0x00000A00; 485 | /* Configure PDx pins speed to 50 MHz */ 486 | GPIOC->OSPEEDR |= 0x00000A00; 487 | /* Configure PDx pins Output type to push-pull */ 488 | GPIOC->OTYPER |= 0x00000000; 489 | /* No pull-up, pull-down for PDx pins */ 490 | GPIOC->PUPDR |= 0x00000000; 491 | #endif /* STM32F446xx */ 492 | 493 | /* Connect PDx pins to FMC Alternate function */ 494 | GPIOD->AFR[0] = 0x000000CC; 495 | GPIOD->AFR[1] = 0xCC000CCC; 496 | /* Configure PDx pins in Alternate function mode */ 497 | GPIOD->MODER = 0xA02A000A; 498 | /* Configure PDx pins speed to 50 MHz */ 499 | GPIOD->OSPEEDR = 0xA02A000A; 500 | /* Configure PDx pins Output type to push-pull */ 501 | GPIOD->OTYPER = 0x00000000; 502 | /* No pull-up, pull-down for PDx pins */ 503 | GPIOD->PUPDR = 0x00000000; 504 | 505 | /* Connect PEx pins to FMC Alternate function */ 506 | GPIOE->AFR[0] = 0xC00000CC; 507 | GPIOE->AFR[1] = 0xCCCCCCCC; 508 | /* Configure PEx pins in Alternate function mode */ 509 | GPIOE->MODER = 0xAAAA800A; 510 | /* Configure PEx pins speed to 50 MHz */ 511 | GPIOE->OSPEEDR = 0xAAAA800A; 512 | /* Configure PEx pins Output type to push-pull */ 513 | GPIOE->OTYPER = 0x00000000; 514 | /* No pull-up, pull-down for PEx pins */ 515 | GPIOE->PUPDR = 0x00000000; 516 | 517 | /* Connect PFx pins to FMC Alternate function */ 518 | GPIOF->AFR[0] = 0xCCCCCCCC; 519 | GPIOF->AFR[1] = 0xCCCCCCCC; 520 | /* Configure PFx pins in Alternate function mode */ 521 | GPIOF->MODER = 0xAA800AAA; 522 | /* Configure PFx pins speed to 50 MHz */ 523 | GPIOF->OSPEEDR = 0xAA800AAA; 524 | /* Configure PFx pins Output type to push-pull */ 525 | GPIOF->OTYPER = 0x00000000; 526 | /* No pull-up, pull-down for PFx pins */ 527 | GPIOF->PUPDR = 0x00000000; 528 | 529 | /* Connect PGx pins to FMC Alternate function */ 530 | GPIOG->AFR[0] = 0xCCCCCCCC; 531 | GPIOG->AFR[1] = 0xCCCCCCCC; 532 | /* Configure PGx pins in Alternate function mode */ 533 | GPIOG->MODER = 0xAAAAAAAA; 534 | /* Configure PGx pins speed to 50 MHz */ 535 | GPIOG->OSPEEDR = 0xAAAAAAAA; 536 | /* Configure PGx pins Output type to push-pull */ 537 | GPIOG->OTYPER = 0x00000000; 538 | /* No pull-up, pull-down for PGx pins */ 539 | GPIOG->PUPDR = 0x00000000; 540 | 541 | #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ 542 | || defined(STM32F469xx) || defined(STM32F479xx) 543 | /* Connect PHx pins to FMC Alternate function */ 544 | GPIOH->AFR[0] = 0x00C0CC00; 545 | GPIOH->AFR[1] = 0xCCCCCCCC; 546 | /* Configure PHx pins in Alternate function mode */ 547 | GPIOH->MODER = 0xAAAA08A0; 548 | /* Configure PHx pins speed to 50 MHz */ 549 | GPIOH->OSPEEDR = 0xAAAA08A0; 550 | /* Configure PHx pins Output type to push-pull */ 551 | GPIOH->OTYPER = 0x00000000; 552 | /* No pull-up, pull-down for PHx pins */ 553 | GPIOH->PUPDR = 0x00000000; 554 | 555 | /* Connect PIx pins to FMC Alternate function */ 556 | GPIOI->AFR[0] = 0xCCCCCCCC; 557 | GPIOI->AFR[1] = 0x00000CC0; 558 | /* Configure PIx pins in Alternate function mode */ 559 | GPIOI->MODER = 0x0028AAAA; 560 | /* Configure PIx pins speed to 50 MHz */ 561 | GPIOI->OSPEEDR = 0x0028AAAA; 562 | /* Configure PIx pins Output type to push-pull */ 563 | GPIOI->OTYPER = 0x00000000; 564 | /* No pull-up, pull-down for PIx pins */ 565 | GPIOI->PUPDR = 0x00000000; 566 | #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ 567 | 568 | /*-- FMC Configuration -------------------------------------------------------*/ 569 | /* Enable the FMC interface clock */ 570 | RCC->AHB3ENR |= 0x00000001; 571 | /* Delay after an RCC peripheral clock enabling */ 572 | tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); 573 | 574 | /* Configure and enable SDRAM bank1 */ 575 | #if defined(STM32F446xx) 576 | FMC_Bank5_6->SDCR[0] = 0x00001954; 577 | #else 578 | FMC_Bank5_6->SDCR[0] = 0x000019E4; 579 | #endif /* STM32F446xx */ 580 | FMC_Bank5_6->SDTR[0] = 0x01115351; 581 | 582 | /* SDRAM initialization sequence */ 583 | /* Clock enable command */ 584 | FMC_Bank5_6->SDCMR = 0x00000011; 585 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 586 | while((tmpreg != 0) && (timeout-- > 0)) 587 | { 588 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 589 | } 590 | 591 | /* Delay */ 592 | for (index = 0; index<1000; index++); 593 | 594 | /* PALL command */ 595 | FMC_Bank5_6->SDCMR = 0x00000012; 596 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 597 | timeout = 0xFFFF; 598 | while((tmpreg != 0) && (timeout-- > 0)) 599 | { 600 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 601 | } 602 | 603 | /* Auto refresh command */ 604 | #if defined(STM32F446xx) 605 | FMC_Bank5_6->SDCMR = 0x000000F3; 606 | #else 607 | FMC_Bank5_6->SDCMR = 0x00000073; 608 | #endif /* STM32F446xx */ 609 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 610 | timeout = 0xFFFF; 611 | while((tmpreg != 0) && (timeout-- > 0)) 612 | { 613 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 614 | } 615 | 616 | /* MRD register program */ 617 | #if defined(STM32F446xx) 618 | FMC_Bank5_6->SDCMR = 0x00044014; 619 | #else 620 | FMC_Bank5_6->SDCMR = 0x00046014; 621 | #endif /* STM32F446xx */ 622 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 623 | timeout = 0xFFFF; 624 | while((tmpreg != 0) && (timeout-- > 0)) 625 | { 626 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 627 | } 628 | 629 | /* Set refresh count */ 630 | tmpreg = FMC_Bank5_6->SDRTR; 631 | #if defined(STM32F446xx) 632 | FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1)); 633 | #else 634 | FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); 635 | #endif /* STM32F446xx */ 636 | 637 | /* Disable write protection */ 638 | tmpreg = FMC_Bank5_6->SDCR[0]; 639 | FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); 640 | #endif /* DATA_IN_ExtSDRAM */ 641 | #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ 642 | 643 | #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ 644 | || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ 645 | || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) 646 | 647 | #if defined(DATA_IN_ExtSRAM) 648 | /*-- GPIOs Configuration -----------------------------------------------------*/ 649 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ 650 | RCC->AHB1ENR |= 0x00000078; 651 | /* Delay after an RCC peripheral clock enabling */ 652 | tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN); 653 | 654 | /* Connect PDx pins to FMC Alternate function */ 655 | GPIOD->AFR[0] = 0x00CCC0CC; 656 | GPIOD->AFR[1] = 0xCCCCCCCC; 657 | /* Configure PDx pins in Alternate function mode */ 658 | GPIOD->MODER = 0xAAAA0A8A; 659 | /* Configure PDx pins speed to 100 MHz */ 660 | GPIOD->OSPEEDR = 0xFFFF0FCF; 661 | /* Configure PDx pins Output type to push-pull */ 662 | GPIOD->OTYPER = 0x00000000; 663 | /* No pull-up, pull-down for PDx pins */ 664 | GPIOD->PUPDR = 0x00000000; 665 | 666 | /* Connect PEx pins to FMC Alternate function */ 667 | GPIOE->AFR[0] = 0xC00CC0CC; 668 | GPIOE->AFR[1] = 0xCCCCCCCC; 669 | /* Configure PEx pins in Alternate function mode */ 670 | GPIOE->MODER = 0xAAAA828A; 671 | /* Configure PEx pins speed to 100 MHz */ 672 | GPIOE->OSPEEDR = 0xFFFFC3CF; 673 | /* Configure PEx pins Output type to push-pull */ 674 | GPIOE->OTYPER = 0x00000000; 675 | /* No pull-up, pull-down for PEx pins */ 676 | GPIOE->PUPDR = 0x00000000; 677 | 678 | /* Connect PFx pins to FMC Alternate function */ 679 | GPIOF->AFR[0] = 0x00CCCCCC; 680 | GPIOF->AFR[1] = 0xCCCC0000; 681 | /* Configure PFx pins in Alternate function mode */ 682 | GPIOF->MODER = 0xAA000AAA; 683 | /* Configure PFx pins speed to 100 MHz */ 684 | GPIOF->OSPEEDR = 0xFF000FFF; 685 | /* Configure PFx pins Output type to push-pull */ 686 | GPIOF->OTYPER = 0x00000000; 687 | /* No pull-up, pull-down for PFx pins */ 688 | GPIOF->PUPDR = 0x00000000; 689 | 690 | /* Connect PGx pins to FMC Alternate function */ 691 | GPIOG->AFR[0] = 0x00CCCCCC; 692 | GPIOG->AFR[1] = 0x000000C0; 693 | /* Configure PGx pins in Alternate function mode */ 694 | GPIOG->MODER = 0x00085AAA; 695 | /* Configure PGx pins speed to 100 MHz */ 696 | GPIOG->OSPEEDR = 0x000CAFFF; 697 | /* Configure PGx pins Output type to push-pull */ 698 | GPIOG->OTYPER = 0x00000000; 699 | /* No pull-up, pull-down for PGx pins */ 700 | GPIOG->PUPDR = 0x00000000; 701 | 702 | /*-- FMC/FSMC Configuration --------------------------------------------------*/ 703 | /* Enable the FMC/FSMC interface clock */ 704 | RCC->AHB3ENR |= 0x00000001; 705 | 706 | #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) 707 | /* Delay after an RCC peripheral clock enabling */ 708 | tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); 709 | /* Configure and enable Bank1_SRAM2 */ 710 | FMC_Bank1->BTCR[2] = 0x00001011; 711 | FMC_Bank1->BTCR[3] = 0x00000201; 712 | FMC_Bank1E->BWTR[2] = 0x0fffffff; 713 | #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ 714 | #if defined(STM32F469xx) || defined(STM32F479xx) 715 | /* Delay after an RCC peripheral clock enabling */ 716 | tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); 717 | /* Configure and enable Bank1_SRAM2 */ 718 | FMC_Bank1->BTCR[2] = 0x00001091; 719 | FMC_Bank1->BTCR[3] = 0x00110212; 720 | FMC_Bank1E->BWTR[2] = 0x0fffffff; 721 | #endif /* STM32F469xx || STM32F479xx */ 722 | #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\ 723 | || defined(STM32F412Zx) || defined(STM32F412Vx) 724 | /* Delay after an RCC peripheral clock enabling */ 725 | tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN); 726 | /* Configure and enable Bank1_SRAM2 */ 727 | FSMC_Bank1->BTCR[2] = 0x00001011; 728 | FSMC_Bank1->BTCR[3] = 0x00000201; 729 | FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF; 730 | #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */ 731 | 732 | #endif /* DATA_IN_ExtSRAM */ 733 | #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ 734 | STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */ 735 | (void)(tmp); 736 | } 737 | #endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */ 738 | /** 739 | * @} 740 | */ 741 | 742 | /** 743 | * @} 744 | */ 745 | 746 | /** 747 | * @} 748 | */ 749 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 750 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Can Guveren 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to Use This Library 2 | 3 | This library supports 1,3,5,6,15,16 functions of modbus. 4 | 5 | **1.** Download file and include the source file in Core/Src/ModbusRTU_Master.c and Core/Inc/ModbusRTU_Master.h header file in your project. 6 | 7 | **2.** Set UART peripheral settings in your project. 8 | 9 | :exclamation: Attention. This project uses USART2 peripheral. If you want to different UART peripheral then you should change the value of UART_HandleTypeDef in the ModbusRTU_Master.c source file. 10 | 11 | ![image](https://user-images.githubusercontent.com/64977597/155136571-725a783a-b87b-41aa-a6a8-f7af2c698c48.png) 12 | 13 | 14 | 15 | **3.** Set number of register, number of coil and slave id in the slave device. 16 | 17 | ![image](https://user-images.githubusercontent.com/64977597/155137609-518863a6-ff9a-4240-b51a-944c7636bd23.png) 18 | 19 | 20 | **4.** You can use the library after making all the above settings. You can see the value of slave device register in the Modbus_Register[] array and you can see the value of slave device coil in the Modbus_Coil[] array. This arrays is in the ModbusRTU_Master.c source file. 21 | 22 | ![image](https://user-images.githubusercontent.com/64977597/155137841-c1aec211-3c1f-4c65-b783-ef37dc45d929.png) 23 | 24 | ## Running the Library 25 | 26 | - You can use **Modbus Slave** program to test the library. You can download the **[Modbus Slave](https://www.modbustools.com/download.html)** program from here. 27 | - Open the Modbus Slave program and connect to your device (Connection/Connect) 28 | - :exclamation:Pay attention to your serial settings. The serial settings of the modbus slave program and the settings of the uart peripheral must be the same. 29 | 30 | ![image](https://user-images.githubusercontent.com/64977597/155140512-c5953311-b0f8-4cab-b72b-25b12425e3e4.png) 31 | 32 | - After that, you should set slave definition. (Setup/Slave Definition) 33 | 34 | - After this step you can use library functions. 35 | 36 | You can find the **MODBUS CRC** function used in this project [here](https://github.com/LacobusVentura/MODBUS-CRC16). 37 | 38 | Modbus Slave Library [here](https://github.com/CanGuveren/STM32-ModbusRTU-Slave). 39 | --------------------------------------------------------------------------------