Add modbus module (currently not work)
This commit is contained in:
parent
4746b6269c
commit
cf049a6101
@ -66,6 +66,18 @@ typedef enum {
|
|||||||
START, STOP
|
START, STOP
|
||||||
} OptStates;
|
} OptStates;
|
||||||
extern OptStates opt_state;
|
extern OptStates opt_state;
|
||||||
|
extern uint16_t modbus_cnt;
|
||||||
|
|
||||||
|
#define DEVICE_CONTROL 0x01
|
||||||
|
#define DEVICE_CNT modbus_cnt
|
||||||
|
#define DEVICE_MIN_RECEIVE_PULSES 5
|
||||||
|
#define DEVICE_MAX_LOST_PULSES 20
|
||||||
|
#define DEVICE_MIN_PULSE_WIDTH 250
|
||||||
|
#define DEVICE_MAX_PULSE_WIDTH 750
|
||||||
|
|
||||||
|
typedef struct {} ModbusRegistersStruct;
|
||||||
|
extern ModbusRegistersStruct ModbusRegisters;
|
||||||
|
|
||||||
/* USER CODE END Private defines */
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
36
Core/Inc/modbus_crc.h
Normal file
36
Core/Inc/modbus_crc.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
|
||||||
|
* Copyright (c) 2006 Christian Walter <wolti@sil.at>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* File: $Id: mbcrc.h,v 1.5 2006/12/07 22:10:34 wolti Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MB_CRC_H
|
||||||
|
#define _MB_CRC_H
|
||||||
|
|
||||||
|
CRC_t usMBCRC16( UCHAR * pucFrame, USHORT usLen );
|
||||||
|
|
||||||
|
#endif
|
84
Core/Inc/modbus_lib.h
Normal file
84
Core/Inc/modbus_lib.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#define MODBUS_LIB_MAX_BUFFER 256
|
||||||
|
|
||||||
|
/* ----------------------- Defines ------------------------------------------*/
|
||||||
|
#define MB_ADDRESS_BROADCAST ( 0 ) /*! Modbus broadcast address. */
|
||||||
|
#define MB_ADDRESS_MIN ( 1 ) /*! Smallest possible slave address. */
|
||||||
|
#define MB_ADDRESS_MAX ( 247 ) /*! Biggest possible slave address. */
|
||||||
|
#define MB_FUNC_NONE ( 0 )
|
||||||
|
#define MB_FUNC_READ_COILS ( 1 )
|
||||||
|
#define MB_FUNC_READ_DISCRETE_INPUTS ( 2 )
|
||||||
|
#define MB_FUNC_WRITE_SINGLE_COIL ( 5 )
|
||||||
|
#define MB_FUNC_WRITE_MULTIPLE_COILS ( 15 )
|
||||||
|
#define MB_FUNC_READ_HOLDING_REGISTERS ( 3 )
|
||||||
|
#define MB_FUNC_READ_INPUT_REGISTER ( 4 )
|
||||||
|
#define MB_FUNC_WRITE_REGISTER ( 6 )
|
||||||
|
#define MB_FUNC_WRITE_MULTIPLE_REGISTERS ( 16 )
|
||||||
|
#define MB_FUNC_READWRITE_MULTIPLE_REGISTERS ( 23 )
|
||||||
|
#define MB_FUNC_DIAG_READ_EXCEPTION ( 7 )
|
||||||
|
#define MB_FUNC_DIAG_DIAGNOSTIC ( 8 )
|
||||||
|
#define MB_FUNC_DIAG_GET_COM_EVENT_CNT ( 11 )
|
||||||
|
#define MB_FUNC_DIAG_GET_COM_EVENT_LOG ( 12 )
|
||||||
|
#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 )
|
||||||
|
#define MB_FUNC_ERROR ( 128 )
|
||||||
|
|
||||||
|
/*----------------------- Response types ------------------------------*/
|
||||||
|
#define MBUS_RESPONSE_OK 0x00
|
||||||
|
#define MBUS_RESPONSE_NONE 0xFF
|
||||||
|
/* MBUS_RESPONSE_ILLEGAL_FUNCTION
|
||||||
|
The function code received in the query is not an allowable action
|
||||||
|
for the server. This may be because the function code is only
|
||||||
|
applicable to newerdevices, and was not implemented in the unit
|
||||||
|
selected. It could also indicate that the serveris in the wrong state to
|
||||||
|
process a request of this type, for example because it is
|
||||||
|
unconfigured and is being asked to return register values.
|
||||||
|
*/
|
||||||
|
#define MBUS_RESPONSE_ILLEGAL_FUNCTION 0x01
|
||||||
|
|
||||||
|
/* MBUS_RESPONSE_ILLEGAL_DATA_ADDRESS
|
||||||
|
The data address received in the query is not an allowable address
|
||||||
|
for the server. More specifically, the combination of reference number
|
||||||
|
and transfer length is invalid. For a controller with 100 registers,
|
||||||
|
the PDU addresses the first register as 0, and the last one as 99. If
|
||||||
|
a request is submitted with a starting register address of 96 and a
|
||||||
|
quantity of registers of 4, then this request will successfully
|
||||||
|
operate (address-wise at least) on registers 96, 97, 98, 99. If
|
||||||
|
a request is submitted with a starting register address of 96 and
|
||||||
|
a quantity of registers of 5, then this request will fail with
|
||||||
|
Exception Code 0x02 “Illegal Data Address” since it attempts to
|
||||||
|
operate on registers 96, 97, 98, 99 and 100, and there is no
|
||||||
|
register with address 100.
|
||||||
|
*/
|
||||||
|
#define MBUS_RESPONSE_ILLEGAL_DATA_ADDRESS 0x02
|
||||||
|
|
||||||
|
/* A value contained in the query data field is not an allowable value
|
||||||
|
for server. This indicates a fault in the structure of the remainder of
|
||||||
|
a complex request, such as that the implied length is
|
||||||
|
incorrect. It specifically does NOT mean that a data item submitted for
|
||||||
|
storage in a register has a value outside the expectation of the application
|
||||||
|
program, since the MODBUS protocol is unaware of the significance of
|
||||||
|
any particular val ue of any particular register.
|
||||||
|
*/
|
||||||
|
#define MBUS_RESPONSE_ILLEGAL_DATA_VALUE 0x03
|
||||||
|
/*
|
||||||
|
An unrecoverable error occurred while the server
|
||||||
|
was attempting to perform the requested action.
|
||||||
|
*/
|
||||||
|
#define MBUS_RESPONSE_SERVICE_DEVICE_FAILURE 0x04
|
||||||
|
|
||||||
|
|
||||||
|
#define MB_ADDRESS_HOLDING_REGISTER_OFFSET (40001)
|
||||||
|
|
||||||
|
typedef struct ModbusConfig_t{
|
||||||
|
uint16_t address;
|
||||||
|
} ModbusConfig_t;
|
||||||
|
|
||||||
|
extern uint8_t g_modbus_lib_received_telegram[MODBUS_LIB_MAX_BUFFER];
|
||||||
|
extern uint16_t g_modbus_lib_received_length;
|
||||||
|
|
||||||
|
extern int modbus_lib_init(ModbusConfig_t*);
|
||||||
|
extern void modbus_lib_append_data(uint8_t);
|
||||||
|
extern void modbus_lib_end_of_telegram(void);
|
||||||
|
extern uint16_t modbus_lib_send_error(int error_code);
|
||||||
|
extern int modbus_lib_transport_write(uint8_t* buffer, uint16_t length);
|
||||||
|
extern uint16_t modbus_lib_read_handler(uint16_t la);
|
||||||
|
extern uint16_t modbus_lib_write_handler(uint16_t la, uint16_t value);
|
10
Core/Inc/modbus_lib_types.h
Normal file
10
Core/Inc/modbus_lib_types.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _MODBUS_LIB_H_
|
||||||
|
#define _MODBUS_LIB_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* ----------------------- Defines ------------------------------------------*/
|
||||||
|
#define MODBUS_LIB_MIN_TELEGRAM_SIZE 4 /*!< Minimum size of a Modbus RTU frame. */
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _MODBUS_LIB_H_
|
21
Core/Inc/port.h
Normal file
21
Core/Inc/port.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef unsigned char BOOL;
|
||||||
|
|
||||||
|
typedef unsigned char UCHAR;
|
||||||
|
typedef char CHAR;
|
||||||
|
|
||||||
|
typedef unsigned int USHORT;
|
||||||
|
typedef int SHORT;
|
||||||
|
|
||||||
|
typedef unsigned long ULONG;
|
||||||
|
typedef long LONG;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint8_t low;
|
||||||
|
uint8_t high;
|
||||||
|
} bytes;
|
||||||
|
uint16_t value;
|
||||||
|
} CRC_t, MbDataField;
|
||||||
|
|
@ -41,12 +41,15 @@
|
|||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
TIM_HandleTypeDef htim2;
|
TIM_HandleTypeDef htim2;
|
||||||
|
TIM_HandleTypeDef htim3;
|
||||||
TIM_HandleTypeDef htim4;
|
TIM_HandleTypeDef htim4;
|
||||||
|
|
||||||
UART_HandleTypeDef huart1;
|
UART_HandleTypeDef huart1;
|
||||||
|
UART_HandleTypeDef huart2;
|
||||||
|
|
||||||
/* USER CODE BEGIN PV */
|
/* USER CODE BEGIN PV */
|
||||||
OptStates opt_state = STOP;
|
OptStates opt_state = STOP;
|
||||||
|
ModbusRegistersStruct ModbusRegisters;
|
||||||
/* USER CODE END PV */
|
/* USER CODE END PV */
|
||||||
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
@ -55,6 +58,8 @@ static void MX_GPIO_Init(void);
|
|||||||
static void MX_TIM4_Init(void);
|
static void MX_TIM4_Init(void);
|
||||||
static void MX_USART1_UART_Init(void);
|
static void MX_USART1_UART_Init(void);
|
||||||
static void MX_TIM2_Init(void);
|
static void MX_TIM2_Init(void);
|
||||||
|
static void MX_TIM3_Init(void);
|
||||||
|
static void MX_USART2_UART_Init(void);
|
||||||
/* USER CODE BEGIN PFP */
|
/* USER CODE BEGIN PFP */
|
||||||
|
|
||||||
/* USER CODE END PFP */
|
/* USER CODE END PFP */
|
||||||
@ -95,6 +100,8 @@ int main(void)
|
|||||||
MX_TIM4_Init();
|
MX_TIM4_Init();
|
||||||
MX_USART1_UART_Init();
|
MX_USART1_UART_Init();
|
||||||
MX_TIM2_Init();
|
MX_TIM2_Init();
|
||||||
|
MX_TIM3_Init();
|
||||||
|
MX_USART2_UART_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
HAL_TIM_Base_Start_IT(&htim2);
|
HAL_TIM_Base_Start_IT(&htim2);
|
||||||
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
|
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
|
||||||
@ -191,6 +198,7 @@ static void MX_TIM2_Init(void)
|
|||||||
htim2.Init.Prescaler = 72;
|
htim2.Init.Prescaler = 72;
|
||||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
htim2.Init.Period = 5000;
|
htim2.Init.Period = 5000;
|
||||||
|
|
||||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||||
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
|
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
|
||||||
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
|
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
|
||||||
@ -220,12 +228,63 @@ static void MX_TIM2_Init(void)
|
|||||||
{
|
{
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
|
||||||
|
sConfigIC.ICFilter = 0;
|
||||||
|
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
/* USER CODE BEGIN TIM2_Init 2 */
|
/* USER CODE BEGIN TIM2_Init 2 */
|
||||||
|
|
||||||
/* USER CODE END TIM2_Init 2 */
|
/* USER CODE END TIM2_Init 2 */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TIM3 Initialization Function
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void MX_TIM3_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN TIM3_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_Init 0 */
|
||||||
|
|
||||||
|
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||||
|
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||||
|
|
||||||
|
/* USER CODE BEGIN TIM3_Init 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_Init 1 */
|
||||||
|
htim3.Instance = TIM3;
|
||||||
|
htim3.Init.Prescaler = 0;
|
||||||
|
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
|
htim3.Init.Period = 65535;
|
||||||
|
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||||
|
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||||
|
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||||
|
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||||
|
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||||
|
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
/* USER CODE BEGIN TIM3_Init 2 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_Init 2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief TIM4 Initialization Function
|
* @brief TIM4 Initialization Function
|
||||||
* @param None
|
* @param None
|
||||||
@ -318,6 +377,39 @@ static void MX_USART1_UART_Init(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USART2 Initialization Function
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void MX_USART2_UART_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USART2_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USART2_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USART2_Init 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USART2_Init 1 */
|
||||||
|
huart2.Instance = USART2;
|
||||||
|
huart2.Init.BaudRate = 115200;
|
||||||
|
huart2.Init.WordLength = UART_WORDLENGTH_8B;
|
||||||
|
huart2.Init.StopBits = UART_STOPBITS_1;
|
||||||
|
huart2.Init.Parity = UART_PARITY_NONE;
|
||||||
|
huart2.Init.Mode = UART_MODE_TX_RX;
|
||||||
|
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||||
|
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||||
|
if (HAL_UART_Init(&huart2) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
/* USER CODE BEGIN USART2_Init 2 */
|
||||||
|
|
||||||
|
/* USER CODE END USART2_Init 2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief GPIO Initialization Function
|
* @brief GPIO Initialization Function
|
||||||
* @param None
|
* @param None
|
||||||
|
98
Core/Src/modbus_crc.c
Normal file
98
Core/Src/modbus_crc.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
|
||||||
|
* Copyright (c) 2006 Christian Walter <wolti@sil.at>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* File: $Id: mbcrc.c,v 1.7 2007/02/18 23:50:27 wolti Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ----------------------- Platform includes --------------------------------*/
|
||||||
|
#include "port.h"
|
||||||
|
|
||||||
|
static const UCHAR aucCRCHi[] = {
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
0x00, 0xC1, 0x81, 0x40
|
||||||
|
};
|
||||||
|
|
||||||
|
static const UCHAR aucCRCLo[] = {
|
||||||
|
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
|
||||||
|
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
|
||||||
|
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
|
||||||
|
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
|
||||||
|
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
||||||
|
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
|
||||||
|
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
|
||||||
|
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
|
||||||
|
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
|
||||||
|
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
||||||
|
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
|
||||||
|
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
|
||||||
|
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
|
||||||
|
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
|
||||||
|
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
||||||
|
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
|
||||||
|
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
|
||||||
|
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
|
||||||
|
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
|
||||||
|
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||||||
|
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
|
||||||
|
0x41, 0x81, 0x80, 0x40
|
||||||
|
};
|
||||||
|
|
||||||
|
CRC_t
|
||||||
|
usMBCRC16( UCHAR * pucFrame, USHORT usLen )
|
||||||
|
{
|
||||||
|
UCHAR ucCRCHi = 0xFF;
|
||||||
|
UCHAR ucCRCLo = 0xFF;
|
||||||
|
int iIndex;
|
||||||
|
|
||||||
|
while( usLen-- )
|
||||||
|
{
|
||||||
|
iIndex = ucCRCLo ^ *( pucFrame++ );
|
||||||
|
ucCRCLo = ( UCHAR )( ucCRCHi ^ aucCRCHi[iIndex] );
|
||||||
|
ucCRCHi = aucCRCLo[iIndex];
|
||||||
|
}
|
||||||
|
return ( CRC_t ){ .bytes.high = ucCRCHi, .bytes.low = ucCRCLo };
|
||||||
|
}
|
141
Core/Src/modbus_lib.c
Normal file
141
Core/Src/modbus_lib.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*******************************************************
|
||||||
|
*
|
||||||
|
* Implementation reference:
|
||||||
|
*
|
||||||
|
* http://www.mayor.de/lian98/doc.en/html/u_mbusser-rtu_struct.htm
|
||||||
|
* https://www.modbustools.com/modbus.html
|
||||||
|
*
|
||||||
|
* Example telegrams:
|
||||||
|
* Read holding registers: 010300000002c40b (read 2 registers starting from 40001)
|
||||||
|
* Read holding registers: 0103000000044409 (read 4 registers starting from 40001)
|
||||||
|
*
|
||||||
|
* Write single register: 01060000007bc9e9 (write "123" to register 40001)
|
||||||
|
*
|
||||||
|
* Write multiple registers: 01100000000204007b0237c300
|
||||||
|
*
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
#include "modbus_lib_types.h"
|
||||||
|
#include "modbus_lib.h"
|
||||||
|
#include "port.h"
|
||||||
|
#include "modbus_crc.h"
|
||||||
|
|
||||||
|
uint8_t g_modbus_lib_received_telegram[MODBUS_LIB_MAX_BUFFER];
|
||||||
|
uint16_t g_modbus_lib_received_length = 0;
|
||||||
|
uint8_t g_modbus_lib_exception_occurred = 0;
|
||||||
|
ModbusConfig_t* config;
|
||||||
|
|
||||||
|
int modbus_lib_init(ModbusConfig_t* cfg){
|
||||||
|
config = cfg;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modbus_lib_append_data(uint8_t byte){
|
||||||
|
if (g_modbus_lib_received_length < MODBUS_LIB_MAX_BUFFER){
|
||||||
|
g_modbus_lib_received_telegram[g_modbus_lib_received_length++] = byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void modbus_lib_end_of_telegram(){
|
||||||
|
(void) 0; // debugger: p/x *g_modbus_lib_received_telegram@g_modbus_lib_received_length
|
||||||
|
|
||||||
|
// Check length
|
||||||
|
if (g_modbus_lib_received_length < MODBUS_LIB_MIN_TELEGRAM_SIZE){
|
||||||
|
modbus_lib_send_error(MBUS_RESPONSE_NONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check CRC
|
||||||
|
CRC_t expected = usMBCRC16(g_modbus_lib_received_telegram, g_modbus_lib_received_length-2);
|
||||||
|
UCHAR got_low = g_modbus_lib_received_telegram[g_modbus_lib_received_length-2];
|
||||||
|
UCHAR got_high = g_modbus_lib_received_telegram[g_modbus_lib_received_length-1];
|
||||||
|
if ((expected.bytes.low != got_low) || (expected.bytes.high != got_high)){
|
||||||
|
modbus_lib_send_error(MBUS_RESPONSE_NONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check address
|
||||||
|
if (config->address != g_modbus_lib_received_telegram[0]){
|
||||||
|
modbus_lib_send_error(MBUS_RESPONSE_NONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Telegram is okay, call the relevant handler
|
||||||
|
// -------------------------------------------
|
||||||
|
uint8_t outgoing_telegram[MODBUS_LIB_MAX_BUFFER];
|
||||||
|
uint16_t oindex = 0;
|
||||||
|
|
||||||
|
outgoing_telegram[oindex++] = config->address;
|
||||||
|
|
||||||
|
volatile MbDataField start_addr, count, res, addr, value;
|
||||||
|
|
||||||
|
switch (g_modbus_lib_received_telegram[1]){
|
||||||
|
case MB_FUNC_READ_HOLDING_REGISTERS:
|
||||||
|
start_addr.bytes.high = g_modbus_lib_received_telegram[2];
|
||||||
|
start_addr.bytes.low = g_modbus_lib_received_telegram[3];
|
||||||
|
count.bytes.high = g_modbus_lib_received_telegram[4];
|
||||||
|
count.bytes.low = g_modbus_lib_received_telegram[5];
|
||||||
|
|
||||||
|
outgoing_telegram[oindex++] = g_modbus_lib_received_telegram[1]; // function code
|
||||||
|
outgoing_telegram[oindex++] = count.value * 2; // byte count
|
||||||
|
|
||||||
|
for (uint16_t i=0; i < count.value; i++){
|
||||||
|
res.value = modbus_lib_read_handler(start_addr.value + i + MB_ADDRESS_HOLDING_REGISTER_OFFSET);
|
||||||
|
if (g_modbus_lib_exception_occurred){
|
||||||
|
g_modbus_lib_exception_occurred = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
outgoing_telegram[oindex++] = res.bytes.high;
|
||||||
|
outgoing_telegram[oindex++] = res.bytes.low;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRC_t crc = usMBCRC16(outgoing_telegram, oindex);
|
||||||
|
outgoing_telegram[oindex++] = crc.bytes.low;
|
||||||
|
outgoing_telegram[oindex++] = crc.bytes.high;
|
||||||
|
|
||||||
|
modbus_lib_transport_write(outgoing_telegram, oindex);
|
||||||
|
break;
|
||||||
|
case MB_FUNC_WRITE_REGISTER:
|
||||||
|
addr.bytes.high = g_modbus_lib_received_telegram[2];
|
||||||
|
addr.bytes.low = g_modbus_lib_received_telegram[3];
|
||||||
|
value.bytes.high = g_modbus_lib_received_telegram[4];
|
||||||
|
value.bytes.low = g_modbus_lib_received_telegram[5];
|
||||||
|
|
||||||
|
if (modbus_lib_write_handler(addr.value + MB_ADDRESS_HOLDING_REGISTER_OFFSET, value.value) == 0){
|
||||||
|
// success
|
||||||
|
// normal response is the echo of received telegram
|
||||||
|
modbus_lib_transport_write(g_modbus_lib_received_telegram, g_modbus_lib_received_length);
|
||||||
|
} else {
|
||||||
|
// error
|
||||||
|
g_modbus_lib_exception_occurred = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// unimplemented
|
||||||
|
modbus_lib_send_error(MBUS_RESPONSE_SERVICE_DEVICE_FAILURE);
|
||||||
|
g_modbus_lib_exception_occurred = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_modbus_lib_received_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MB_EXCEPTION_LENGTH 5
|
||||||
|
|
||||||
|
uint16_t modbus_lib_send_error(int error_code){
|
||||||
|
if (error_code != MBUS_RESPONSE_NONE){
|
||||||
|
g_modbus_lib_exception_occurred = 1;
|
||||||
|
uint8_t res[MB_EXCEPTION_LENGTH] = {
|
||||||
|
config->address,
|
||||||
|
g_modbus_lib_received_telegram[1] | 0x80,
|
||||||
|
error_code
|
||||||
|
};
|
||||||
|
CRC_t crc = usMBCRC16(res, MB_EXCEPTION_LENGTH - 2);
|
||||||
|
res[MB_EXCEPTION_LENGTH - 2] = crc.bytes.low;
|
||||||
|
res[MB_EXCEPTION_LENGTH - 1] = crc.bytes.high;
|
||||||
|
|
||||||
|
modbus_lib_transport_write(res, MB_EXCEPTION_LENGTH);
|
||||||
|
}
|
||||||
|
g_modbus_lib_received_length = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
@ -101,13 +101,15 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
|
|||||||
|
|
||||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
/**TIM2 GPIO Configuration
|
/**TIM2 GPIO Configuration
|
||||||
PA0-WKUP ------> TIM2_CH1
|
PA15 ------> TIM2_CH1
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0;
|
GPIO_InitStruct.Pin = GPIO_PIN_15;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
__HAL_AFIO_REMAP_TIM2_PARTIAL_1();
|
||||||
|
|
||||||
/* TIM2 interrupt Init */
|
/* TIM2 interrupt Init */
|
||||||
HAL_NVIC_SetPriority(TIM2_IRQn, 14, 0);
|
HAL_NVIC_SetPriority(TIM2_IRQn, 14, 0);
|
||||||
HAL_NVIC_EnableIRQ(TIM2_IRQn);
|
HAL_NVIC_EnableIRQ(TIM2_IRQn);
|
||||||
@ -115,6 +117,17 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
|
|||||||
|
|
||||||
/* USER CODE END TIM2_MspInit 1 */
|
/* USER CODE END TIM2_MspInit 1 */
|
||||||
}
|
}
|
||||||
|
else if(htim_base->Instance==TIM3)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN TIM3_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspInit 0 */
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||||
|
/* USER CODE BEGIN TIM3_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspInit 1 */
|
||||||
|
}
|
||||||
else if(htim_base->Instance==TIM4)
|
else if(htim_base->Instance==TIM4)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN TIM4_MspInit 0 */
|
/* USER CODE BEGIN TIM4_MspInit 0 */
|
||||||
@ -170,9 +183,9 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
|
|||||||
__HAL_RCC_TIM2_CLK_DISABLE();
|
__HAL_RCC_TIM2_CLK_DISABLE();
|
||||||
|
|
||||||
/**TIM2 GPIO Configuration
|
/**TIM2 GPIO Configuration
|
||||||
PA0-WKUP ------> TIM2_CH1
|
PA15 ------> TIM2_CH1
|
||||||
*/
|
*/
|
||||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);
|
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);
|
||||||
|
|
||||||
/* TIM2 interrupt DeInit */
|
/* TIM2 interrupt DeInit */
|
||||||
HAL_NVIC_DisableIRQ(TIM2_IRQn);
|
HAL_NVIC_DisableIRQ(TIM2_IRQn);
|
||||||
@ -180,6 +193,17 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
|
|||||||
|
|
||||||
/* USER CODE END TIM2_MspDeInit 1 */
|
/* USER CODE END TIM2_MspDeInit 1 */
|
||||||
}
|
}
|
||||||
|
else if(htim_base->Instance==TIM3)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN TIM3_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspDeInit 0 */
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_TIM3_CLK_DISABLE();
|
||||||
|
/* USER CODE BEGIN TIM3_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspDeInit 1 */
|
||||||
|
}
|
||||||
else if(htim_base->Instance==TIM4)
|
else if(htim_base->Instance==TIM4)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN TIM4_MspDeInit 0 */
|
/* USER CODE BEGIN TIM4_MspDeInit 0 */
|
||||||
@ -230,6 +254,33 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
|
|||||||
|
|
||||||
/* USER CODE END USART1_MspInit 1 */
|
/* USER CODE END USART1_MspInit 1 */
|
||||||
}
|
}
|
||||||
|
else if(huart->Instance==USART2)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USART2_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USART2_MspInit 0 */
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
__HAL_RCC_USART2_CLK_ENABLE();
|
||||||
|
|
||||||
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
|
/**USART2 GPIO Configuration
|
||||||
|
PA2 ------> USART2_TX
|
||||||
|
PA3 ------> USART2_RX
|
||||||
|
*/
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USART2_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USART2_MspInit 1 */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,6 +310,24 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
|
|||||||
|
|
||||||
/* USER CODE END USART1_MspDeInit 1 */
|
/* USER CODE END USART1_MspDeInit 1 */
|
||||||
}
|
}
|
||||||
|
else if(huart->Instance==USART2)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USART2_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USART2_MspDeInit 0 */
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_USART2_CLK_DISABLE();
|
||||||
|
|
||||||
|
/**USART2 GPIO Configuration
|
||||||
|
PA2 ------> USART2_TX
|
||||||
|
PA3 ------> USART2_RX
|
||||||
|
*/
|
||||||
|
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USART2_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USART2_MspDeInit 1 */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,15 +213,29 @@ void TIM2_IRQHandler(void)
|
|||||||
_state_counter = 0;
|
_state_counter = 0;
|
||||||
LED_GPIO_Port->BSRR = LED_Pin;
|
LED_GPIO_Port->BSRR = LED_Pin;
|
||||||
}
|
}
|
||||||
|
// задний фронт, убывающий
|
||||||
|
if (sr & TIM_SR_CC2IF) {
|
||||||
|
uint32_t ccr = TIM2->CCR2;
|
||||||
|
if (ccr >= DEVICE_MIN_PULSE_WIDTH && ccr <= DEVICE_MAX_PULSE_WIDTH) {
|
||||||
|
// можно считать что это импульс
|
||||||
|
if (_state_counter > DEVICE_MIN_RECEIVE_PULSES) {
|
||||||
|
LED_GPIO_Port->BSRR = (uint32_t)LED_Pin << 16;
|
||||||
|
opt_state = START;
|
||||||
|
} else {
|
||||||
|
_state_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// // какое-то говно, а не импульс
|
||||||
|
// // ну я ничего не делаю
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// передний возрастающий фронт
|
||||||
|
// тут по сути надо обнулить CNT, и вроде все
|
||||||
if (sr & TIM_SR_CC1IF) {
|
if (sr & TIM_SR_CC1IF) {
|
||||||
TIM2->SR = TIM_SR_CC1IF;
|
TIM2->SR = TIM_SR_CC1IF;
|
||||||
TIM2->CNT = 0; // обнуляем счетчик таймера
|
TIM2->CNT = 0; // обнуляем счетчик таймера
|
||||||
if (_state_counter > 20) {
|
|
||||||
LED_GPIO_Port->BSRR = (uint32_t)LED_Pin << 16;
|
|
||||||
opt_state = START;
|
|
||||||
} else {
|
|
||||||
_state_counter++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* USER CODE END TIM2_IRQn 0 */
|
/* USER CODE END TIM2_IRQn 0 */
|
||||||
HAL_TIM_IRQHandler(&htim2);
|
HAL_TIM_IRQHandler(&htim2);
|
||||||
|
@ -7,25 +7,31 @@ Mcu.IP0=NVIC
|
|||||||
Mcu.IP1=RCC
|
Mcu.IP1=RCC
|
||||||
Mcu.IP2=SYS
|
Mcu.IP2=SYS
|
||||||
Mcu.IP3=TIM2
|
Mcu.IP3=TIM2
|
||||||
Mcu.IP4=TIM4
|
Mcu.IP4=TIM3
|
||||||
Mcu.IP5=USART1
|
Mcu.IP5=TIM4
|
||||||
Mcu.IPNb=6
|
Mcu.IP6=USART1
|
||||||
|
Mcu.IP7=USART2
|
||||||
|
Mcu.IPNb=8
|
||||||
Mcu.Name=STM32F103C(8-B)Tx
|
Mcu.Name=STM32F103C(8-B)Tx
|
||||||
Mcu.Package=LQFP48
|
Mcu.Package=LQFP48
|
||||||
Mcu.Pin0=PD0-OSC_IN
|
Mcu.Pin0=PD0-OSC_IN
|
||||||
Mcu.Pin1=PD1-OSC_OUT
|
Mcu.Pin1=PD1-OSC_OUT
|
||||||
Mcu.Pin10=VP_SYS_VS_Systick
|
Mcu.Pin10=PB5
|
||||||
Mcu.Pin11=VP_TIM2_VS_ClockSourceINT
|
Mcu.Pin11=PB6
|
||||||
Mcu.Pin12=VP_TIM4_VS_ClockSourceINT
|
Mcu.Pin12=VP_SYS_VS_Systick
|
||||||
Mcu.Pin2=PA0-WKUP
|
Mcu.Pin13=VP_TIM2_VS_ClockSourceINT
|
||||||
Mcu.Pin3=PB12
|
Mcu.Pin14=VP_TIM2_VS_indirect_ch1
|
||||||
Mcu.Pin4=PA9
|
Mcu.Pin15=VP_TIM3_VS_ClockSourceINT
|
||||||
Mcu.Pin5=PA10
|
Mcu.Pin16=VP_TIM4_VS_ClockSourceINT
|
||||||
Mcu.Pin6=PA13
|
Mcu.Pin2=PA2
|
||||||
Mcu.Pin7=PA14
|
Mcu.Pin3=PA3
|
||||||
Mcu.Pin8=PB5
|
Mcu.Pin4=PB12
|
||||||
Mcu.Pin9=PB6
|
Mcu.Pin5=PA9
|
||||||
Mcu.PinsNb=13
|
Mcu.Pin6=PA10
|
||||||
|
Mcu.Pin7=PA13
|
||||||
|
Mcu.Pin8=PA14
|
||||||
|
Mcu.Pin9=PA15
|
||||||
|
Mcu.PinsNb=17
|
||||||
Mcu.ThirdPartyNb=0
|
Mcu.ThirdPartyNb=0
|
||||||
Mcu.UserConstants=
|
Mcu.UserConstants=
|
||||||
Mcu.UserName=STM32F103C8Tx
|
Mcu.UserName=STM32F103C8Tx
|
||||||
@ -43,13 +49,17 @@ NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
|||||||
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true
|
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true
|
||||||
NVIC.TIM2_IRQn=true\:14\:0\:true\:false\:true\:true\:true
|
NVIC.TIM2_IRQn=true\:14\:0\:true\:false\:true\:true\:true
|
||||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
|
||||||
PA0-WKUP.Signal=S_TIM2_CH1_ETR
|
|
||||||
PA10.Mode=Asynchronous
|
PA10.Mode=Asynchronous
|
||||||
PA10.Signal=USART1_RX
|
PA10.Signal=USART1_RX
|
||||||
PA13.Mode=Serial_Wire
|
PA13.Mode=Serial_Wire
|
||||||
PA13.Signal=SYS_JTMS-SWDIO
|
PA13.Signal=SYS_JTMS-SWDIO
|
||||||
PA14.Mode=Serial_Wire
|
PA14.Mode=Serial_Wire
|
||||||
PA14.Signal=SYS_JTCK-SWCLK
|
PA14.Signal=SYS_JTCK-SWCLK
|
||||||
|
PA15.Signal=S_TIM2_CH1_ETR
|
||||||
|
PA2.Mode=Asynchronous
|
||||||
|
PA2.Signal=USART2_TX
|
||||||
|
PA3.Mode=Asynchronous
|
||||||
|
PA3.Signal=USART2_RX
|
||||||
PA9.Mode=Asynchronous
|
PA9.Mode=Asynchronous
|
||||||
PA9.Signal=USART1_TX
|
PA9.Signal=USART1_TX
|
||||||
PB12.GPIOParameters=GPIO_Label
|
PB12.GPIOParameters=GPIO_Label
|
||||||
@ -119,8 +129,9 @@ SH.S_TIM4_CH1.0=TIM4_CH1,PWM Generation1 CH1
|
|||||||
SH.S_TIM4_CH1.ConfNb=1
|
SH.S_TIM4_CH1.ConfNb=1
|
||||||
TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
|
TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
|
||||||
TIM2.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1
|
TIM2.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1
|
||||||
|
TIM2.Channel-Input_Capture2_from_TI1_63=TIM_CHANNEL_2
|
||||||
TIM2.ICFilter_CH1=1
|
TIM2.ICFilter_CH1=1
|
||||||
TIM2.IPParameters=Channel-Input_Capture1_from_TI1,ICFilter_CH1,Prescaler,Period,AutoReloadPreload
|
TIM2.IPParameters=Channel-Input_Capture1_from_TI1,ICFilter_CH1,Prescaler,Period,AutoReloadPreload,Channel-Input_Capture2_from_TI1_63
|
||||||
TIM2.Period=5000
|
TIM2.Period=5000
|
||||||
TIM2.Prescaler=72
|
TIM2.Prescaler=72
|
||||||
TIM4.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
TIM4.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||||
@ -130,10 +141,16 @@ TIM4.Prescaler=72
|
|||||||
TIM4.Pulse-PWM\ Generation1\ CH1=500
|
TIM4.Pulse-PWM\ Generation1\ CH1=500
|
||||||
USART1.IPParameters=VirtualMode
|
USART1.IPParameters=VirtualMode
|
||||||
USART1.VirtualMode=VM_ASYNC
|
USART1.VirtualMode=VM_ASYNC
|
||||||
|
USART2.IPParameters=VirtualMode
|
||||||
|
USART2.VirtualMode=VM_ASYNC
|
||||||
VP_SYS_VS_Systick.Mode=SysTick
|
VP_SYS_VS_Systick.Mode=SysTick
|
||||||
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
||||||
VP_TIM2_VS_ClockSourceINT.Mode=Internal
|
VP_TIM2_VS_ClockSourceINT.Mode=Internal
|
||||||
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
|
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
|
||||||
|
VP_TIM2_VS_indirect_ch1.Mode=Input_Capture2_from_TI1_63
|
||||||
|
VP_TIM2_VS_indirect_ch1.Signal=TIM2_VS_indirect_ch1
|
||||||
|
VP_TIM3_VS_ClockSourceINT.Mode=Internal
|
||||||
|
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
|
||||||
VP_TIM4_VS_ClockSourceINT.Mode=Internal
|
VP_TIM4_VS_ClockSourceINT.Mode=Internal
|
||||||
VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
|
VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
|
||||||
board=custom
|
board=custom
|
||||||
|
Loading…
x
Reference in New Issue
Block a user