Compare commits
1 Commits
main
...
modbus_tcp
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b49e0069e |
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -5,7 +5,3 @@
|
||||
path = labview_proj
|
||||
url = https://git.arktika.cyou/Andrey/labview_proj.git
|
||||
branch = master
|
||||
[submodule "core/STM32_Modbus"]
|
||||
path = core/STM32_Modbus
|
||||
url = https://git.arktika.cyou/set506/STM32_Modbus.git
|
||||
branch = release
|
||||
|
||||
BIN
Project Backups/schem [Autosaved].pdsprj
Normal file
BIN
Project Backups/schem [Autosaved].pdsprj
Normal file
Binary file not shown.
@ -1 +0,0 @@
|
||||
Subproject commit cba13802b11fd15013b96e8465b70415f969c946
|
||||
File diff suppressed because one or more lines are too long
@ -1,13 +0,0 @@
|
||||
#ifndef __PROJ_SETUP
|
||||
#define __PROJ_SETUP
|
||||
|
||||
//**********BEGIN defines***********
|
||||
//#define OldVer
|
||||
#define MAX_SENSE 32 // НЕ ДЕЛАТЬ МЕНЬШЕ 16
|
||||
|
||||
|
||||
|
||||
|
||||
//**********END defines***********
|
||||
|
||||
#endif
|
||||
@ -20,12 +20,10 @@
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "onewire.h"
|
||||
#include "PROJ_setup.h"
|
||||
|
||||
|
||||
|
||||
/* Data Structure ------------------------------------------------------------*/
|
||||
#define DS18B20_DEVICE_AMOUNT MAX_SENSE
|
||||
#define DS18B20_DEVICE_AMOUNT 30
|
||||
|
||||
/* Register ------------------------------------------------------------------*/
|
||||
#define DS18B20_CMD_CONVERT 0x44
|
||||
@ -77,7 +75,7 @@ typedef struct
|
||||
{
|
||||
uint8_t DevAddr[DS18B20_DEVICE_AMOUNT][8];
|
||||
} DS18B20_Drv_t;
|
||||
extern DS18B20_Drv_t DS;
|
||||
extern DS18B20_Drv_t DS;;
|
||||
extern OneWire_t OW;
|
||||
|
||||
/* External Function ---------------------------------------------------------*/
|
||||
|
||||
@ -1,12 +1,5 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
***************************************************************
|
||||
* 1 2 3 4 5 6 7 8 *
|
||||
* --- +++ *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
|
||||
******************************************************************************
|
||||
* @file : main.h
|
||||
* @brief : Header for main.c file.
|
||||
@ -35,29 +28,9 @@ extern "C" {
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "modbus_data.h"
|
||||
#include "PROJ_setup.h"
|
||||
#include "dallas_tools.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
typedef enum
|
||||
{
|
||||
FuncOK=0,
|
||||
FuncERROR=1
|
||||
|
||||
}FuncStat;
|
||||
|
||||
|
||||
typedef enum {
|
||||
CONFIG_DEVICE_ID = 0,
|
||||
CONFIG_BAUDRATE,
|
||||
CONFIG_CALIBRATION,
|
||||
CONFIG_SETTINGS
|
||||
} ConfigParams;
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
STATE_OPEN_VALVE = 0, // open
|
||||
STATE_CLOSE_VALVE= 1 // close
|
||||
@ -69,19 +42,17 @@ typedef struct
|
||||
uint16_t location;
|
||||
uint8_t t_open;
|
||||
float t_set;
|
||||
uint8_t t_close;
|
||||
uint8_t status_T_sense:1 ;
|
||||
uint8_t t_close;
|
||||
|
||||
|
||||
uint8_t status_T_sense:1 ;
|
||||
|
||||
ValveState state;
|
||||
uint16_t count;
|
||||
}TEMP_TypeDef;
|
||||
typedef struct {
|
||||
uint32_t init_tsens : 1; // Update Interrupt Flag (áèò 0) — ôëàã ïåðåïîëíåíèÿ/îáíîâëåíèÿ
|
||||
|
||||
// ... (äðóãèå áèòû ìîãóò áûòü çàðåçåðâèðîâàíû èëè èñïîëüçîâàòüñÿ â ðàñøèðåííûõ òàéìåðàõ)
|
||||
} Flags_TypeDef;
|
||||
|
||||
|
||||
|
||||
uint16_t count;
|
||||
|
||||
|
||||
|
||||
}TEMP;
|
||||
|
||||
|
||||
|
||||
@ -100,16 +71,10 @@ typedef struct {
|
||||
extern void handle_command(char* cmd);
|
||||
typedef void (*FunctionPointer)(void);
|
||||
|
||||
uint16_t handle_valves(TEMP_TypeDef* temp_sense[MAX_SENSE]);
|
||||
void init_setpoint_all_T_sense(TEMP_TypeDef* temp_sense[MAX_SENSE]);
|
||||
uint16_t handle_valves(TEMP* tmp_sense);
|
||||
void init_all_T_sense(void);
|
||||
void iwdg_refresh(void);
|
||||
void led_blink(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,uint8_t iter,uint16_t delay);
|
||||
FuncStat Field_modbus(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag);
|
||||
FuncStat packStruct(MB_DataStructureTypeDef* MB_DATA,int sizeARR);
|
||||
void Check_Tconnect(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag ,DALLAS_HandleTypeDef* hdallas, int a[50]);
|
||||
FuncStat value_control(void );
|
||||
|
||||
void reinit_t_sens(void);
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
@ -131,8 +96,6 @@ void Error_Handler(void);
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define Relay_dc5v_Pin GPIO_PIN_10
|
||||
#define Relay_dc5v_GPIO_Port GPIOA
|
||||
#define One_wire_Pin GPIO_PIN_15
|
||||
#define One_wire_GPIO_Port GPIOA
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#define __STM32F1xx_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//extern uint8_t devices_found ;
|
||||
extern uint8_t roms[MAX_DEVICES][8];
|
||||
extern char rx_buffer[64];
|
||||
extern TEMP_TypeDef temp_sense[30];
|
||||
extern TEMP temp_sense[30];
|
||||
extern uint8_t init;
|
||||
int test_var=0;
|
||||
//void handle_command(char* cmd)
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Configure GPIO */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -51,26 +50,15 @@ void MX_GPIO_Init(void)
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4
|
||||
|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|
||||
|GPIO_PIN_9|Relay_dc5v_Pin|One_wire_Pin, GPIO_PIN_RESET);
|
||||
|GPIO_PIN_9|GPIO_PIN_10|One_wire_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|
||||
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|
||||
|GPIO_PIN_15, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : PC13 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|GPIO_PIN_15, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin : PA0 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0;
|
||||
@ -80,10 +68,10 @@ void MX_GPIO_Init(void)
|
||||
|
||||
/*Configure GPIO pins : PA1 PA2 PA3 PA4
|
||||
PA5 PA6 PA7 PA8
|
||||
PA9 Relay_dc5v_Pin One_wire_Pin */
|
||||
PA9 PA10 PAPin */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4
|
||||
|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|
||||
|GPIO_PIN_9|Relay_dc5v_Pin|One_wire_Pin;
|
||||
|GPIO_PIN_9|GPIO_PIN_10|One_wire_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
|
||||
@ -27,23 +27,13 @@
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "dallas_tools.h"
|
||||
|
||||
#include "def.h"
|
||||
#include <stdio.h>
|
||||
#include "modbus.h"
|
||||
#include "eeprom_emul.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#include "rs_message.h"
|
||||
|
||||
|
||||
|
||||
@ -67,20 +57,18 @@ uint8_t ralay_5v_on_var=0;
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
float temperature;
|
||||
uint8_t roms[MAX_DEVICES][8];
|
||||
Flags_TypeDef flag;
|
||||
//extern uint8_t devices_found ;
|
||||
uint8_t _debug_init=0;
|
||||
TEMP_TypeDef temp_sense[30];
|
||||
float set_temp_old[30];
|
||||
char rx_buffer[64];
|
||||
uint8_t rx_index = 0;
|
||||
char command_ready = 0;
|
||||
uint8_t uart_byte = 0;
|
||||
uint8_t first_in=1;
|
||||
DALLAS_SensorHandleTypeDef sens[30];
|
||||
int init_sens=0;
|
||||
float temperature;
|
||||
extern uint8_t roms[MAX_DEVICES][8];
|
||||
//extern uint8_t devices_found ;
|
||||
uint8_t _debug_init=1;
|
||||
//TEMP temp_sense[30];
|
||||
float set_temp_old[30];
|
||||
char rx_buffer[64];
|
||||
uint8_t rx_index = 0;
|
||||
char command_ready = 0;
|
||||
uint8_t uart_byte = 0;
|
||||
uint8_t first_in=1;
|
||||
DALLAS_SensorHandleTypeDef sens[30];
|
||||
|
||||
|
||||
/* USER CODE END PM */
|
||||
@ -107,6 +95,7 @@ void SystemClock_Config(void);
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
@ -132,6 +121,7 @@ int main(void)
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
|
||||
MX_TIM1_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_TIM2_Init();
|
||||
@ -143,46 +133,34 @@ int main(void)
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
led_blink(GPIOC,13,rest_iter,reset_blink_delay);
|
||||
MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
|
||||
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
||||
|
||||
// Запуск приема Modbus
|
||||
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||
MODBUS_FirstInit();
|
||||
uint8_t uart_byte = 0;
|
||||
|
||||
Dallas_BusFirstInit(&htim1);
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
reinit_t_sens();
|
||||
RS_Receive_IT(&hmodbus1, &MODBUS_MSG);
|
||||
Dallas_BusFirstInit(&htim1);
|
||||
// èíèöèàëèçàöèÿ ïî ïîðÿäêó íàéäåííûõ äàò÷èêîâ
|
||||
// Èíèöèàëèçàöèÿ ïî èíäåêñó (ïîðÿäêîâîìó íîìåðó íàéäåííîãî äàò÷èêà)
|
||||
|
||||
for ( int i=0; i<hdallas.onewire->RomCnt;i++)
|
||||
{
|
||||
// Èíèöèàëèçàöèÿ ïî ROM-àäðåñó
|
||||
//sens[i].Init.init_func = &Dallas_SensorInitByROM;
|
||||
// sens[i].Init.InitParam.ROM = rom_address;
|
||||
sens[i].Init.InitParam.Ind = i;
|
||||
sens[i].Init.init_func = &Dallas_SensorInitByInd;
|
||||
sens[i].Init.Resolution = DALLAS_CONFIG_9_BITS;
|
||||
MB_DATA.HoldRegs.set_Temp[i] =sens[i].set_temp =20.;
|
||||
MB_DATA.HoldRegs.set_hyst[i]=sens[i].hyst =1;
|
||||
Dallas_AddNewSensors(&hdallas, &sens[i]);
|
||||
|
||||
MB_DATA.InRegs.num_Tsens=hdallas.onewire->RomCnt;
|
||||
}
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
Field_modbus(&MB_DATA,&flag);
|
||||
|
||||
if( hmodbus1.pMessagePtr->FuncCode&FC_ERR_VALUES_START)
|
||||
{
|
||||
static int pause_Alarm_led;
|
||||
while (1)
|
||||
{
|
||||
if (pause_Alarm_led>36000000)
|
||||
{
|
||||
GPIOC->ODR^=1<<13;
|
||||
pause_Alarm_led=0;
|
||||
|
||||
}
|
||||
pause_Alarm_led++;
|
||||
}
|
||||
}
|
||||
|
||||
Check_Tconnect(&MB_DATA,&flag,&hdallas, 0);
|
||||
value_control();
|
||||
handle_valves(temp_sense[]);
|
||||
|
||||
|
||||
|
||||
if (_debug_init||MB_DATA.Coils.init_param)
|
||||
{
|
||||
_debug_init=0;
|
||||
@ -212,8 +190,7 @@ int main(void)
|
||||
MB_DATA.InRegs.sens_Temp[i]=sens[i].temperature*10;
|
||||
|
||||
|
||||
/////////////////////////заменить на define ralay_5v_on_var GPIOA->ODR|=1<<10;
|
||||
|
||||
|
||||
ralay_5v_on_var=MB_DATA.Coils.coils[1].state_val_bit.state_val_05;
|
||||
if (ralay_5v_on_var)
|
||||
{
|
||||
@ -223,8 +200,32 @@ int main(void)
|
||||
{
|
||||
GPIOA->ODR&=~(1<<10);
|
||||
}
|
||||
//value_control();
|
||||
|
||||
|
||||
//// if (sens[i].temperature<sens[i].set_temp-sens[i].hyst)
|
||||
////
|
||||
//// {
|
||||
////
|
||||
//// MB_DATA.Coils.coils[0].all|=1<<i;
|
||||
////
|
||||
//// }
|
||||
////
|
||||
//// else
|
||||
////
|
||||
//// if (sens[i].temperature>sens[i].set_temp+sens[i].hyst)
|
||||
//// {
|
||||
////
|
||||
//// MB_DATA.Coils.coils[0].all&=~(1<<i);
|
||||
////
|
||||
//// }
|
||||
//// if(GPIOB11_valve)
|
||||
//// {
|
||||
//// GPIOB->ODR|=1<<11;
|
||||
//// }
|
||||
//// else
|
||||
//// {
|
||||
//// GPIOB->ODR&=~(1<<11);
|
||||
////
|
||||
//// }
|
||||
}
|
||||
|
||||
|
||||
@ -291,7 +292,7 @@ void SystemClock_Config(void)
|
||||
/* USER CODE BEGIN 4 */
|
||||
void iwdg_refresh(void)
|
||||
{
|
||||
IWDG->KR = 0xAAAA; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
IWDG->KR = 0xAAAA; // Ñáðîñèòü òàéìåð
|
||||
}
|
||||
void led_blink(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,uint8_t iter,uint16_t delay)
|
||||
{
|
||||
@ -301,186 +302,71 @@ void led_blink(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,uint8_t iter,uint16_t delay
|
||||
HAL_Delay(delay);
|
||||
}
|
||||
}
|
||||
//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
//{
|
||||
// if (huart->Instance == USART1)
|
||||
// {
|
||||
// if(first_in)
|
||||
// {
|
||||
// first_in=0;
|
||||
// rx_index = 0;
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// static uint8_t ch;
|
||||
// HAL_UART_Receive_IT(&huart1, &ch, 1);
|
||||
|
||||
void Check_Tconnect(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag ,DALLAS_HandleTypeDef* hdallas, int a[0])
|
||||
{
|
||||
for(int i=0;i<hdallas->onewire->RomCnt;i++)
|
||||
{
|
||||
if(sens[i].isLost)
|
||||
{
|
||||
//init_sens=1;
|
||||
}
|
||||
|
||||
}
|
||||
if (init_sens||flag->init_tsens)
|
||||
{
|
||||
init_sens=0;
|
||||
flag->init_tsens=0;
|
||||
//Dallas_BusFirstInit(&htim1);
|
||||
DS18B20_Search(&DS, &OW) ;
|
||||
reinit_t_sens();
|
||||
MB_DATA->InRegs.num_Tsens = hdallas->onewire->RomCnt;
|
||||
}
|
||||
}
|
||||
// if (ch == '\r' || ch == '\n')
|
||||
// {
|
||||
// rx_buffer[rx_index] = 0;
|
||||
// command_ready = 1;
|
||||
// rx_index = 0;
|
||||
// first_in=1;
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (rx_index < sizeof(rx_buffer) - 1)
|
||||
// {
|
||||
// rx_buffer[rx_index++] = ch;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
void reinit_t_sens(void)
|
||||
{
|
||||
for ( int i=0; i<hdallas.onewire->RomCnt;i++)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> ROM-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//sens[i].Init.init_func = &Dallas_SensorInitByROM;
|
||||
// sens[i].Init.InitParam.ROM = rom_address;
|
||||
sens[i].Init.InitParam.Ind = i;
|
||||
sens[i].Init.init_func = &Dallas_SensorInitByInd;
|
||||
sens[i].Init.Resolution = DALLAS_CONFIG_9_BITS;
|
||||
MB_DATA.HoldRegs.set_Temp[i] =sens[i].set_temp =20.;
|
||||
MB_DATA.HoldRegs.set_hyst[i]=sens[i].hyst =1;
|
||||
Dallas_AddNewSensors(&hdallas, &sens[i]);
|
||||
|
||||
}
|
||||
}
|
||||
FuncStat packStruct(MB_DataStructureTypeDef* MB_DATA,int sizeARR)
|
||||
{
|
||||
for(int i=0;i<sizeARR;i++)
|
||||
{
|
||||
for(int sens_num=0;sens_num<hdallas.onewire->RomCnt;sens_num++)
|
||||
{
|
||||
switch(sens_num)
|
||||
{
|
||||
case 0:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp1_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 1:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp2_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 2:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp3_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 3:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp4_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 4:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp5_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 5:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp6_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 6:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp7_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 7:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp8_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 8:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp9_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 9:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp10_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 10:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp11_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 11:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp12_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 12:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp13_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 13:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp14_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 14:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp15_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
case 15:
|
||||
MB_DATA->Coils.status_tSens[i].state_val_bit.Temp16_isConnected = sens[i*16+sens_num ].isConnected;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FuncOK;
|
||||
|
||||
}
|
||||
FuncStat Field_modbus(MB_DataStructureTypeDef* MB_DATA, Flags_TypeDef* flag)
|
||||
{
|
||||
|
||||
MB_DATA->InRegs.ID= *hdallas.ds_devices;
|
||||
flag->init_tsens=MB_DATA->Coils.init_Tsens;
|
||||
packStruct(MB_DATA,MAX_SENSE/16);
|
||||
|
||||
|
||||
return FuncOK;
|
||||
};
|
||||
|
||||
|
||||
FuncStat value_control(void )
|
||||
{
|
||||
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
if (sens[i].temperature<sens[i].set_temp-sens[i].hyst)
|
||||
|
||||
{
|
||||
|
||||
MB_DATA.Coils.coils[0].all|=1<<i;
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
if (sens[i].temperature>sens[i].set_temp+sens[i].hyst)
|
||||
{
|
||||
|
||||
MB_DATA.Coils.coils[0].all&=~(1<<i);
|
||||
|
||||
}
|
||||
if(GPIOB11_valve)
|
||||
{
|
||||
GPIOB->ODR|=1<<11;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIOB->ODR&=~(1<<11);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return FuncOK;
|
||||
}
|
||||
|
||||
//uint16_t handle_valves(TEMP* tmp_sense )
|
||||
//{
|
||||
//
|
||||
// if (temp_sense[0].state==STATE_OPEN_VALVE)
|
||||
// {
|
||||
// GPIOC->ODR|=1<<14;
|
||||
// }
|
||||
// else
|
||||
// if (temp_sense[0].state==STATE_CLOSE_VALVE)
|
||||
// {
|
||||
// GPIOC->ODR&=~(1<<14);
|
||||
// }
|
||||
//
|
||||
// return 1;
|
||||
//
|
||||
//}
|
||||
|
||||
uint16_t handle_valves(TEMP_TypeDef* temp_sense[MAX_SENSE] )
|
||||
{
|
||||
|
||||
if (temp_sense[0]->state==STATE_OPEN_VALVE)
|
||||
{
|
||||
GPIOC->ODR|=1<<14;
|
||||
}
|
||||
else
|
||||
if (temp_sense[0]->state==STATE_CLOSE_VALVE)
|
||||
{
|
||||
GPIOC->ODR&=~(1<<14);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
void init_setpoint_all_T_sense(TEMP_TypeDef* temp_sense[MAX_SENSE])
|
||||
{
|
||||
//ds_search_devices();
|
||||
for(int i=0;i<hdallas.onewire->RomCnt;i++)
|
||||
{
|
||||
temp_sense[i]->id[0]=roms[i][0]<<0|roms[i][1]<<8|roms[i][2]<<16|roms[i][3]<<24;
|
||||
temp_sense[i]->id[1]=roms[i][4]<<0|roms[i][5]<<8|roms[i][6]<<16|roms[i][7]<<24;
|
||||
temp_sense[i]->count =i+1;
|
||||
temp_sense[i]->location=1;
|
||||
temp_sense[i]->t_open=22;
|
||||
temp_sense[i]->t_close=18;
|
||||
temp_sense[i]->status_T_sense=1;
|
||||
}
|
||||
}
|
||||
//void init_all_T_sense(void)
|
||||
//{
|
||||
// //ds_search_devices();
|
||||
// for(int i=0;i<hdallas.onewire->RomCnt;i++)
|
||||
//{
|
||||
// temp_sense[i].id[0]=roms[i][0]<<0|roms[i][1]<<8|roms[i][2]<<16|roms[i][3]<<24;
|
||||
// temp_sense[i].id[1]=roms[i][4]<<0|roms[i][5]<<8|roms[i][6]<<16|roms[i][7]<<24;
|
||||
// temp_sense[i].count =i+1;
|
||||
// temp_sense[i].location=1;
|
||||
// temp_sense[i].t_open=22;
|
||||
// temp_sense[i].t_close=18;
|
||||
// temp_sense[i].status_T_sense=1;
|
||||
//}
|
||||
//}
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
@ -496,8 +382,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
/* USER CODE BEGIN Callback 0 */
|
||||
|
||||
/* USER CODE END Callback 0 */
|
||||
if (htim->Instance == TIM3)
|
||||
{
|
||||
if (htim->Instance == TIM3) {
|
||||
HAL_IncTick();
|
||||
}
|
||||
/* USER CODE BEGIN Callback 1 */
|
||||
@ -519,7 +404,8 @@ void Error_Handler(void)
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
#ifdef USE_FULL_ASSERT
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
|
||||
@ -53,7 +53,7 @@ volatile uint32_t *config_reg = (OW_Pin_Numb < 8) ? &(OW->DataPort->CRL) : &(OW-
|
||||
}
|
||||
HAL_GPIO_Init(OW->DataPort, &GPIO_InitStruct);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +98,7 @@ uint8_t OneWire_Pin_Read(OneWire_t* OW)
|
||||
#else
|
||||
#ifdef LL_Driver
|
||||
return ((OW->DataPort->IDR & OW->DataPin) != 0x00U) ? 1 : 0;
|
||||
#else
|
||||
#else6
|
||||
return HAL_GPIO_ReadPin(OW->DataPort, OW->DataPin);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -45,7 +45,7 @@ void MX_RTC_Init(void)
|
||||
*/
|
||||
hrtc.Instance = RTC;
|
||||
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
|
||||
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
|
||||
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_SECOND;
|
||||
if (HAL_RTC_Init(&hrtc) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
@ -57,23 +57,24 @@ void MX_RTC_Init(void)
|
||||
|
||||
/** Initialize RTC and set the Time and Date
|
||||
*/
|
||||
sTime.Hours = 0x0;
|
||||
sTime.Minutes = 0x0;
|
||||
sTime.Seconds = 0x0;
|
||||
|
||||
// sTime.Hours = 0x0;
|
||||
// sTime.Minutes = 0x0;
|
||||
// sTime.Seconds = 0x0;
|
||||
|
||||
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
|
||||
DateToUpdate.Month = RTC_MONTH_JANUARY;
|
||||
DateToUpdate.Date = 0x1;
|
||||
DateToUpdate.Year = 0x0;
|
||||
// // if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
|
||||
// {
|
||||
// Error_Handler();
|
||||
// }
|
||||
// DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
|
||||
// DateToUpdate.Month = RTC_MONTH_JANUARY;
|
||||
// DateToUpdate.Date = 0x1;
|
||||
// DateToUpdate.Year = 0x0;
|
||||
|
||||
if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
// if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
|
||||
// {
|
||||
// Error_Handler();
|
||||
// }
|
||||
/* USER CODE BEGIN RTC_Init 2 */
|
||||
|
||||
/* USER CODE END RTC_Init 2 */
|
||||
|
||||
@ -44,7 +44,7 @@ void MX_SPI1_Init(void)
|
||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
|
||||
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
|
||||
@ -46,15 +46,12 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
|
||||
uint32_t uwPrescalerValue = 0U;
|
||||
uint32_t pFLatency;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Enable TIM3 clock */
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
/* Get clock configuration */
|
||||
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||
|
||||
/* Get APB1 prescaler */
|
||||
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
|
||||
/* Compute TIM3 clock */
|
||||
@ -74,11 +71,12 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
htim3.Instance = TIM3;
|
||||
|
||||
/* Initialize TIMx peripheral as follow:
|
||||
* Period = [(TIM3CLK/1000) - 1]. to have a (1/1000) s time base.
|
||||
* Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
||||
* ClockDivision = 0
|
||||
* Counter direction = Up
|
||||
*/
|
||||
|
||||
+ Period = [(TIM3CLK/1000) - 1]. to have a (1/1000) s time base.
|
||||
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
||||
+ ClockDivision = 0
|
||||
+ Counter direction = Up
|
||||
*/
|
||||
htim3.Init.Period = (1000000U / 1000U) - 1U;
|
||||
htim3.Init.Prescaler = uwPrescalerValue;
|
||||
htim3.Init.ClockDivision = 0;
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#include "stm32f1xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "modbus.h"
|
||||
#include "rs_message.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@ -281,12 +281,11 @@ void TIM1_CC_IRQHandler(void)
|
||||
void TIM2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM2_IRQn 0 */
|
||||
RS_TIM_Handler(&hmodbus1);
|
||||
return;
|
||||
|
||||
/* USER CODE END TIM2_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim2);
|
||||
/* USER CODE BEGIN TIM2_IRQn 1 */
|
||||
//RS_TIM_Handler(&hmodbus1);
|
||||
RS_TIM_Handler(&hmodbus1);
|
||||
/* USER CODE END TIM2_IRQn 1 */
|
||||
}
|
||||
|
||||
@ -314,12 +313,11 @@ static uint8_t first_in=1;
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_IRQn 0 */
|
||||
RS_UART_Handler(&hmodbus1);
|
||||
return;
|
||||
|
||||
/* USER CODE END USART1_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart1);
|
||||
/* USER CODE BEGIN USART1_IRQn 1 */
|
||||
//RS_UART_Handler(&hmodbus1);
|
||||
RS_UART_Handler(&hmodbus1);
|
||||
|
||||
|
||||
/* USER CODE END USART1_IRQn 1 */
|
||||
|
||||
@ -83,7 +83,7 @@ void MX_TIM2_Init(void)
|
||||
|
||||
/* USER CODE END TIM2_Init 1 */
|
||||
htim2.Instance = TIM2;
|
||||
htim2.Init.Prescaler = 72-1;
|
||||
htim2.Init.Prescaler = 7199;
|
||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim2.Init.Period = 65535;
|
||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
|
||||
@ -36,7 +36,7 @@ void MX_USART1_UART_Init(void)
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
huart1.ReceptionType=HAL_UART_RECEPTION_TOIDLE;
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
#ifndef EEPROM_EMUL_H
|
||||
#define EEPROM_EMUL_H
|
||||
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
// Адреса для эмуляции EEPROM (последние страницы Flash)
|
||||
#define EEPROM_START_ADDRESS 0x0800F000 // Последний килобайт Flash
|
||||
#define EEPROM_PAGE_SIZE 1024 // Размер страницы STM32F103
|
||||
#define EEPROM_SIZE 1024 // Общий размер EEPROM
|
||||
|
||||
// Максимальное количество переменных
|
||||
#define EEPROM_MAX_VARIABLES 64
|
||||
|
||||
// Статусы операций
|
||||
typedef enum {
|
||||
EEPROM_OK = 0,
|
||||
EEPROM_ERROR = 1,
|
||||
EEPROM_INVALID = 2,
|
||||
EEPROM_FULL = 3
|
||||
} EEPROM_Status;
|
||||
|
||||
// Структура элемента данных
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint16_t address; // Адрес переменной (0-EEPROM_MAX_VARIABLES)
|
||||
uint16_t data; // Данные
|
||||
uint32_t timestamp; // Временная метка
|
||||
} EEPROM_Item;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Инициализация EEPROM
|
||||
EEPROM_Status EEPROM_Init(void);
|
||||
|
||||
// Чтение данных
|
||||
EEPROM_Status EEPROM_Read(uint16_t virt_address, uint16_t* data);
|
||||
|
||||
// Запись данных
|
||||
EEPROM_Status EEPROM_Write(uint16_t virt_address, uint16_t data);
|
||||
|
||||
// Массовая запись
|
||||
EEPROM_Status EEPROM_WriteMultiple(uint16_t virt_address, uint8_t* data, uint16_t size);
|
||||
|
||||
// Получение информации о EEPROM
|
||||
void EEPROM_GetInfo(uint32_t* used, uint32_t* total);
|
||||
|
||||
// Полное форматирование
|
||||
EEPROM_Status EEPROM_Format(void);
|
||||
|
||||
#endif
|
||||
@ -1,256 +0,0 @@
|
||||
#include "eeprom_emul.h"
|
||||
#include <string.h>
|
||||
|
||||
// Внутренние переменные
|
||||
static uint32_t eeprom_current_write_address = EEPROM_START_ADDRESS;
|
||||
static uint8_t eeprom_initialized = 0;
|
||||
|
||||
// Прототипы внутренних функций
|
||||
static EEPROM_Status EEPROM_FindLatestData(uint16_t virt_address, uint16_t* data);
|
||||
static EEPROM_Status EEPROM_WriteItem(EEPROM_Item* item);
|
||||
static EEPROM_Status EEPROM_ErasePage(uint32_t address);
|
||||
static uint32_t EEPROM_FindNextWriteAddress(void);
|
||||
static uint8_t EEPROM_IsPageErased(uint32_t address);
|
||||
static uint32_t EEPROM_CalculateCRC(EEPROM_Item* item);
|
||||
|
||||
// Инициализация EEPROM
|
||||
EEPROM_Status EEPROM_Init(void) {
|
||||
if (eeprom_initialized) {
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
// Находим следующий адрес для записи
|
||||
eeprom_current_write_address = EEPROM_FindNextWriteAddress();
|
||||
|
||||
// Если вся память заполнена, выполняем сборку мусора (форматирование)
|
||||
if (eeprom_current_write_address >= EEPROM_START_ADDRESS + EEPROM_SIZE) {
|
||||
EEPROM_Format();
|
||||
} else {
|
||||
eeprom_initialized = 1;
|
||||
}
|
||||
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
// Чтение данных по виртуальному адресу
|
||||
EEPROM_Status EEPROM_Read(uint16_t virt_address, uint16_t* data) {
|
||||
if (!eeprom_initialized) {
|
||||
return EEPROM_ERROR;
|
||||
}
|
||||
|
||||
if (virt_address >= EEPROM_MAX_VARIABLES || data == NULL) {
|
||||
return EEPROM_INVALID;
|
||||
}
|
||||
|
||||
return EEPROM_FindLatestData(virt_address, data);
|
||||
}
|
||||
|
||||
// Запись данных по виртуальному адресу
|
||||
EEPROM_Status EEPROM_Write(uint16_t virt_address, uint16_t data) {
|
||||
EEPROM_Item item;
|
||||
|
||||
if (!eeprom_initialized) {
|
||||
return EEPROM_ERROR;
|
||||
}
|
||||
|
||||
if (virt_address >= EEPROM_MAX_VARIABLES) {
|
||||
return EEPROM_INVALID;
|
||||
}
|
||||
|
||||
// Подготавливаем элемент данных
|
||||
item.address = virt_address;
|
||||
item.data = data;
|
||||
item.timestamp = HAL_GetTick(); // Используем системный таймер
|
||||
|
||||
// Записываем элемент
|
||||
return EEPROM_WriteItem(&item);
|
||||
}
|
||||
|
||||
// Поиск последних данных для виртуального адреса
|
||||
static EEPROM_Status EEPROM_FindLatestData(uint16_t virt_address, uint16_t* data) {
|
||||
uint32_t address = EEPROM_START_ADDRESS;
|
||||
EEPROM_Item current_item;
|
||||
uint32_t latest_timestamp = 0;
|
||||
uint16_t latest_data = 0;
|
||||
uint8_t data_found = 0;
|
||||
|
||||
// Сканируем всю область EEPROM
|
||||
while (address < EEPROM_START_ADDRESS + EEPROM_SIZE) {
|
||||
// Читаем элемент
|
||||
memcpy(¤t_item, (void*)address, sizeof(EEPROM_Item));
|
||||
|
||||
// Проверяем, является ли это валидными данными
|
||||
if (current_item.address == virt_address) {
|
||||
if (current_item.timestamp >= latest_timestamp) {
|
||||
latest_timestamp = current_item.timestamp;
|
||||
latest_data = current_item.data;
|
||||
data_found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
address += sizeof(EEPROM_Item);
|
||||
|
||||
// Проверяем конец страницы
|
||||
if ((address - EEPROM_START_ADDRESS) % EEPROM_PAGE_SIZE == 0) {
|
||||
address += (EEPROM_PAGE_SIZE - (sizeof(EEPROM_Item) * 2));
|
||||
}
|
||||
}
|
||||
|
||||
if (data_found) {
|
||||
*data = latest_data;
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
return EEPROM_INVALID;
|
||||
}
|
||||
|
||||
// Запись элемента в EEPROM
|
||||
static EEPROM_Status EEPROM_WriteItem(EEPROM_Item* item) {
|
||||
HAL_StatusTypeDef hal_status;
|
||||
|
||||
// Проверяем, нужно ли стирать страницу
|
||||
if ((eeprom_current_write_address - EEPROM_START_ADDRESS) % EEPROM_PAGE_SIZE == 0) {
|
||||
if (!EEPROM_IsPageErased(eeprom_current_write_address)) {
|
||||
if (EEPROM_ErasePage(eeprom_current_write_address) != EEPROM_OK) {
|
||||
return EEPROM_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Разблокируем Flash
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
// Записываем данные по словам (32 бита)
|
||||
uint32_t* data_ptr = (uint32_t*)item;
|
||||
|
||||
for (uint8_t i = 0; i < sizeof(EEPROM_Item) / 4; i++) {
|
||||
hal_status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
|
||||
eeprom_current_write_address + (i * 4),
|
||||
data_ptr[i]);
|
||||
|
||||
if (hal_status != HAL_OK) {
|
||||
HAL_FLASH_Lock();
|
||||
return EEPROM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Блокируем Flash
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
// Обновляем адрес для следующей записи
|
||||
eeprom_current_write_address += sizeof(EEPROM_Item);
|
||||
|
||||
// Проверяем переполнение
|
||||
if (eeprom_current_write_address >= EEPROM_START_ADDRESS + EEPROM_SIZE) {
|
||||
// Выполняем сборку мусора (в данном случае - форматирование)
|
||||
EEPROM_Format();
|
||||
}
|
||||
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
// Стирание страницы Flash
|
||||
static EEPROM_Status EEPROM_ErasePage(uint32_t address) {
|
||||
FLASH_EraseInitTypeDef erase;
|
||||
uint32_t page_error;
|
||||
|
||||
// Определяем номер страницы
|
||||
uint32_t page = (address - FLASH_BASE) / EEPROM_PAGE_SIZE;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
erase.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
erase.PageAddress = address;
|
||||
erase.NbPages = 1;
|
||||
|
||||
if (HAL_FLASHEx_Erase(&erase, &page_error) != HAL_OK) {
|
||||
HAL_FLASH_Lock();
|
||||
return EEPROM_ERROR;
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
// Поиск следующего адреса для записи
|
||||
static uint32_t EEPROM_FindNextWriteAddress(void) {
|
||||
uint32_t address = EEPROM_START_ADDRESS;
|
||||
EEPROM_Item item;
|
||||
|
||||
// Ищем первую свободную позицию
|
||||
while (address < EEPROM_START_ADDRESS + EEPROM_SIZE) {
|
||||
memcpy(&item, (void*)address, sizeof(EEPROM_Item));
|
||||
|
||||
// Если нашли пустой элемент (все FFFF), это свободная позиция
|
||||
if (item.address == 0xFFFF && item.data == 0xFFFF && item.timestamp == 0xFFFFFFFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
address += sizeof(EEPROM_Item);
|
||||
|
||||
// Проверяем границу страницы
|
||||
if ((address - EEPROM_START_ADDRESS) % EEPROM_PAGE_SIZE == 0) {
|
||||
address += (EEPROM_PAGE_SIZE - (sizeof(EEPROM_Item) * 2));
|
||||
}
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
// Проверка, стерта ли страница
|
||||
static uint8_t EEPROM_IsPageErased(uint32_t address) {
|
||||
uint32_t* check_addr = (uint32_t*)address;
|
||||
|
||||
// Проверяем первые несколько слов
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (check_addr[i] != 0xFFFFFFFF) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Полное форматирование EEPROM
|
||||
EEPROM_Status EEPROM_Format(void) {
|
||||
uint32_t address = EEPROM_START_ADDRESS;
|
||||
|
||||
// Стираем все страницы, используемые для EEPROM
|
||||
while (address < EEPROM_START_ADDRESS + EEPROM_SIZE) {
|
||||
if (EEPROM_ErasePage(address) != EEPROM_OK) {
|
||||
return EEPROM_ERROR;
|
||||
}
|
||||
address += EEPROM_PAGE_SIZE;
|
||||
}
|
||||
|
||||
eeprom_current_write_address = EEPROM_START_ADDRESS;
|
||||
eeprom_initialized = 1;
|
||||
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
// Получение информации об использовании EEPROM
|
||||
void EEPROM_GetInfo(uint32_t* used, uint32_t* total) {
|
||||
uint32_t address = EEPROM_START_ADDRESS;
|
||||
uint32_t used_bytes = 0;
|
||||
|
||||
if (used) {
|
||||
// Подсчитываем использованные байты
|
||||
while (address < EEPROM_START_ADDRESS + EEPROM_SIZE) {
|
||||
EEPROM_Item item;
|
||||
memcpy(&item, (void*)address, sizeof(EEPROM_Item));
|
||||
|
||||
if (item.address != 0xFFFF || item.data != 0xFFFF || item.timestamp != 0xFFFFFFFF) {
|
||||
used_bytes += sizeof(EEPROM_Item);
|
||||
}
|
||||
|
||||
address += sizeof(EEPROM_Item);
|
||||
}
|
||||
|
||||
*used = used_bytes;
|
||||
}
|
||||
|
||||
if (total) {
|
||||
*total = EEPROM_SIZE;
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
// File: STM32F101_102_103_105_107.dbgconf
|
||||
// Version: 1.0.0
|
||||
// Note: refer to STM32F101xx STM32F102xx STM32F103xx STM32F105xx STM32F107xx Reference manual (RM0008)
|
||||
// STM32F101xx STM32F102xx STM32F103xx STM32F105xx STM32F107xx datasheets
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h> Debug MCU configuration register (DBGMCU_CR)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.30> DBG_TIM11_STOP <i> TIM11 counter stopped when core is halted
|
||||
// <o.29> DBG_TIM10_STOP <i> TIM10 counter stopped when core is halted
|
||||
// <o.28> DBG_TIM9_STOP <i> TIM9 counter stopped when core is halted
|
||||
// <o.27> DBG_TIM14_STOP <i> TIM14 counter stopped when core is halted
|
||||
// <o.26> DBG_TIM13_STOP <i> TIM13 counter stopped when core is halted
|
||||
// <o.25> DBG_TIM12_STOP <i> TIM12 counter stopped when core is halted
|
||||
// <o.21> DBG_CAN2_STOP <i> Debug CAN2 stopped when core is halted
|
||||
// <o.20> DBG_TIM7_STOP <i> TIM7 counter stopped when core is halted
|
||||
// <o.19> DBG_TIM6_STOP <i> TIM6 counter stopped when core is halted
|
||||
// <o.18> DBG_TIM5_STOP <i> TIM5 counter stopped when core is halted
|
||||
// <o.17> DBG_TIM8_STOP <i> TIM8 counter stopped when core is halted
|
||||
// <o.16> DBG_I2C2_SMBUS_TIMEOUT <i> SMBUS timeout mode stopped when core is halted
|
||||
// <o.15> DBG_I2C1_SMBUS_TIMEOUT <i> SMBUS timeout mode stopped when core is halted
|
||||
// <o.14> DBG_CAN1_STOP <i> Debug CAN1 stopped when Core is halted
|
||||
// <o.13> DBG_TIM4_STOP <i> TIM4 counter stopped when core is halted
|
||||
// <o.12> DBG_TIM3_STOP <i> TIM3 counter stopped when core is halted
|
||||
// <o.11> DBG_TIM2_STOP <i> TIM2 counter stopped when core is halted
|
||||
// <o.10> DBG_TIM1_STOP <i> TIM1 counter stopped when core is halted
|
||||
// <o.9> DBG_WWDG_STOP <i> Debug window watchdog stopped when core is halted
|
||||
// <o.8> DBG_IWDG_STOP <i> Debug independent watchdog stopped when core is halted
|
||||
// <o.2> DBG_STANDBY <i> Debug standby mode
|
||||
// <o.1> DBG_STOP <i> Debug stop mode
|
||||
// <o.0> DBG_SLEEP <i> Debug sleep mode
|
||||
// </h>
|
||||
DbgMCU_CR = 0x00000007;
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
@ -1,47 +0,0 @@
|
||||
[BREAKPOINTS]
|
||||
ForceImpTypeAny = 0
|
||||
ShowInfoWin = 1
|
||||
EnableFlashBP = 2
|
||||
BPDuringExecution = 0
|
||||
[CFI]
|
||||
CFISize = 0x00
|
||||
CFIAddr = 0x00
|
||||
[CPU]
|
||||
MonModeVTableAddr = 0xFFFFFFFF
|
||||
MonModeDebug = 0
|
||||
MaxNumAPs = 0
|
||||
LowPowerHandlingMode = 0
|
||||
OverrideMemMap = 0
|
||||
AllowSimulation = 1
|
||||
ScriptFile=""
|
||||
[FLASH]
|
||||
RMWThreshold = 0x400
|
||||
Loaders=""
|
||||
EraseType = 0x00
|
||||
CacheExcludeSize = 0x00
|
||||
CacheExcludeAddr = 0x00
|
||||
MinNumBytesFlashDL = 0
|
||||
SkipProgOnCRCMatch = 1
|
||||
VerifyDownload = 1
|
||||
AllowCaching = 1
|
||||
EnableFlashDL = 2
|
||||
Override = 0
|
||||
Device="ARM7"
|
||||
[GENERAL]
|
||||
MaxNumTransfers = 0x00
|
||||
WorkRAMSize = 0x00
|
||||
WorkRAMAddr = 0x00
|
||||
RAMUsageLimit = 0x00
|
||||
[SWO]
|
||||
SWOLogFile=""
|
||||
[MEM]
|
||||
RdOverrideOrMask = 0x00
|
||||
RdOverrideAndMask = 0xFFFFFFFF
|
||||
RdOverrideAddr = 0xFFFFFFFF
|
||||
WrOverrideOrMask = 0x00
|
||||
WrOverrideAndMask = 0xFFFFFFFF
|
||||
WrOverrideAddr = 0xFFFFFFFF
|
||||
[RAM]
|
||||
VerifyDownload = 0x00
|
||||
[DYN_MEM_MAP]
|
||||
NumUserRegion = 0x00
|
||||
@ -26,7 +26,7 @@
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<TargetOption>
|
||||
<CLKADS>12000000</CLKADS>
|
||||
<CLKADS>8000000</CLKADS>
|
||||
<OPTTT>
|
||||
<gFlags>1</gFlags>
|
||||
<BeepAtEnd>1</BeepAtEnd>
|
||||
@ -117,16 +117,6 @@
|
||||
<pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
|
||||
</DebugOpt>
|
||||
<TargetDriverDllRegistry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>UL2CM3</Key>
|
||||
<Name>UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32F10x_128 -FL020000 -FS08000000 -FP0($$Device:STM32F103C8$Flash\STM32F10x_128.FLM)</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>ST-LINKIII-KEIL_SWO</Key>
|
||||
<Name>-U002400343233511639363634 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:STM32F103C8$Flash\STM32F10x_128.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>ARMRTXEVENTFLAGS</Key>
|
||||
@ -147,71 +137,118 @@
|
||||
<Key>DLGUARM</Key>
|
||||
<Name>(105=-1,-1,-1,-1,0)</Name>
|
||||
</SetRegEntry>
|
||||
</TargetDriverDllRegistry>
|
||||
<Breakpoint>
|
||||
<Bp>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>193</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>134249696</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>../Core/Src/main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\john103C6T6\../Core/Src/main.c\193</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>193</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>134249792</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>../Core/Src/main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\john103C6T6\../Core/Src/main.c\193</Expression>
|
||||
</Bp>
|
||||
</Breakpoint>
|
||||
<Key>UL2CM3</Key>
|
||||
<Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128 -FS08000000 -FL020000 -FP0($$Device:STM32F103C6$Flash\STM32F10x_128.FLM))</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>ST-LINKIII-KEIL_SWO</Key>
|
||||
<Name>-U37FF71064E57343625581443 -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(1BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL08000 -FP0($$Device:STM32F103C6$Flash\STM32F10x_128.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2</Name>
|
||||
</SetRegEntry>
|
||||
</TargetDriverDllRegistry>
|
||||
<Breakpoint/>
|
||||
<WatchWindow1>
|
||||
<Ww>
|
||||
<count>0</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>hiwdg</ItemText>
|
||||
<ItemText>sens,0x0A</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>1</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>DS18B20_DEVICE_AMOUNT</ItemText>
|
||||
<ItemText>hdallas</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>2</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>set_temp_old</ItemText>
|
||||
<ItemText>DS</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>3</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>sTime</ItemText>
|
||||
<ItemText>hmodbus1</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>4</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>sens[sens_num]</ItemText>
|
||||
<ItemText>hiwdg</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>5</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>sens</ItemText>
|
||||
<ItemText>OW</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>6</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>_debug_init</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>7</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>htim1,0x0A</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>8</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>DS18B20_DEVICE_AMOUNT</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>9</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>set_temp_old</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>10</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>hrtc.Instance,0x0A</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>11</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>\\john103C6T6\../Modbus/modbus.c\MB_DATA,0x0A</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>12</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>sTime</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>13</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>ralay_5v_on_var</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>14</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>MB_DATA.Coils.coils[1].state_val_bit.state_val_01,0x0A</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>15</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>MODBUS_MSG</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>16</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>RS_RES</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>17</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>rx_buffer</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>18</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>RS_msg</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>19</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>pMessagePtr</ItemText>
|
||||
</Ww>
|
||||
</WatchWindow1>
|
||||
<WatchWindow2>
|
||||
@ -220,20 +257,7 @@
|
||||
<WinNumber>2</WinNumber>
|
||||
<ItemText>resolution</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>1</count>
|
||||
<WinNumber>2</WinNumber>
|
||||
<ItemText>hmodbus1</ItemText>
|
||||
</Ww>
|
||||
</WatchWindow2>
|
||||
<MemoryWindow1>
|
||||
<Mm>
|
||||
<WinNumber>1</WinNumber>
|
||||
<SubType>0</SubType>
|
||||
<ItemText>0x08000000</ItemText>
|
||||
<AccSizeX>0</AccSizeX>
|
||||
</Mm>
|
||||
</MemoryWindow1>
|
||||
<Tracepoint>
|
||||
<THDelay>0</THDelay>
|
||||
</Tracepoint>
|
||||
@ -242,7 +266,7 @@
|
||||
<periodic>1</periodic>
|
||||
<aLwin>1</aLwin>
|
||||
<aCover>0</aCover>
|
||||
<aSer1>0</aSer1>
|
||||
<aSer1>1</aSer1>
|
||||
<aSer2>0</aSer2>
|
||||
<aPa>0</aPa>
|
||||
<viewmode>1</viewmode>
|
||||
@ -278,12 +302,8 @@
|
||||
<pMultCmdsp></pMultCmdsp>
|
||||
<SystemViewers>
|
||||
<Entry>
|
||||
<Name>System Viewer\GPIOB</Name>
|
||||
<WinId>35900</WinId>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Name>System Viewer\GPIOC</Name>
|
||||
<WinId>35905</WinId>
|
||||
<Name>System Viewer\USART1</Name>
|
||||
<WinId>35902</WinId>
|
||||
</Entry>
|
||||
</SystemViewers>
|
||||
<DebugDescription>
|
||||
@ -298,7 +318,7 @@
|
||||
|
||||
<Group>
|
||||
<GroupName>Application/MDK-ARM</GroupName>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
@ -329,6 +349,18 @@
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Core\Src\UART_TERM.c</PathWithFileName>
|
||||
<FilenameWithoutPath>UART_TERM.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>3</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Core\Src\dallas_tools.c</PathWithFileName>
|
||||
<FilenameWithoutPath>dallas_tools.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
@ -336,7 +368,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>3</FileNumber>
|
||||
<FileNumber>4</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -348,7 +380,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>4</FileNumber>
|
||||
<FileNumber>5</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -360,7 +392,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>5</FileNumber>
|
||||
<FileNumber>6</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -372,7 +404,43 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>6</FileNumber>
|
||||
<FileNumber>7</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Modbus\crc_algs.c</PathWithFileName>
|
||||
<FilenameWithoutPath>crc_algs.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>8</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Modbus\modbus.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>9</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Modbus\rs_message.c</PathWithFileName>
|
||||
<FilenameWithoutPath>rs_message.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>10</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -384,7 +452,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>7</FileNumber>
|
||||
<FileNumber>11</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -396,7 +464,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>8</FileNumber>
|
||||
<FileNumber>12</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -408,7 +476,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>9</FileNumber>
|
||||
<FileNumber>13</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -420,7 +488,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>10</FileNumber>
|
||||
<FileNumber>14</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -432,7 +500,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>11</FileNumber>
|
||||
<FileNumber>15</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -444,7 +512,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>12</FileNumber>
|
||||
<FileNumber>16</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -456,7 +524,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>13</FileNumber>
|
||||
<FileNumber>17</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -468,7 +536,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>14</FileNumber>
|
||||
<FileNumber>18</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -480,7 +548,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>15</FileNumber>
|
||||
<FileNumber>19</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -492,7 +560,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>16</FileNumber>
|
||||
<FileNumber>20</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -504,7 +572,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>17</FileNumber>
|
||||
<FileNumber>21</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -514,18 +582,6 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>18</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\EEPROM_Emul\src\EEPROM_Emul.c</PathWithFileName>
|
||||
<FilenameWithoutPath>EEPROM_Emul.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
@ -536,7 +592,7 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>19</FileNumber>
|
||||
<FileNumber>22</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -548,31 +604,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>20</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f1xx_hal_tim.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>21</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f1xx_hal_tim_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>22</FileNumber>
|
||||
<FileNumber>23</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -584,7 +616,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>23</FileNumber>
|
||||
<FileNumber>24</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -596,7 +628,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>24</FileNumber>
|
||||
<FileNumber>25</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -608,7 +640,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>25</FileNumber>
|
||||
<FileNumber>26</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -620,7 +652,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>26</FileNumber>
|
||||
<FileNumber>27</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -632,7 +664,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>27</FileNumber>
|
||||
<FileNumber>28</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -644,7 +676,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>28</FileNumber>
|
||||
<FileNumber>29</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -656,7 +688,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>29</FileNumber>
|
||||
<FileNumber>30</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -668,7 +700,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>30</FileNumber>
|
||||
<FileNumber>31</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -680,7 +712,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>31</FileNumber>
|
||||
<FileNumber>32</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -692,7 +724,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>32</FileNumber>
|
||||
<FileNumber>33</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -704,7 +736,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>33</FileNumber>
|
||||
<FileNumber>34</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -716,7 +748,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>34</FileNumber>
|
||||
<FileNumber>35</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -728,7 +760,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>35</FileNumber>
|
||||
<FileNumber>36</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -740,7 +772,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>36</FileNumber>
|
||||
<FileNumber>37</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -752,7 +784,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>37</FileNumber>
|
||||
<FileNumber>38</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -764,7 +796,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>38</FileNumber>
|
||||
<FileNumber>39</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -776,7 +808,31 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>39</FileNumber>
|
||||
<FileNumber>40</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f1xx_hal_tim.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f1xx_hal_tim_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>42</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -796,7 +852,7 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>4</GroupNumber>
|
||||
<FileNumber>40</FileNumber>
|
||||
<FileNumber>43</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -808,170 +864,6 @@
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>modbus</GroupName>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\__crc_algs.c</PathWithFileName>
|
||||
<FilenameWithoutPath>__crc_algs.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>42</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\__modbus_compat.c</PathWithFileName>
|
||||
<FilenameWithoutPath>__modbus_compat.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>43</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>44</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_coils.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_coils.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>45</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_core.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_core.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>46</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_devid.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_devid.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>47</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_diag.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_diag.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>48</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_holdregs.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_holdregs.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>49</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_inputregs.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_inputregs.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>50</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_master.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_master.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>51</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\modbus_slave.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_slave.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>52</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\core\STM32_Modbus\Src\rs_message.c</PathWithFileName>
|
||||
<FilenameWithoutPath>rs_message.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>53</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Modbus\modbus_data.c</PathWithFileName>
|
||||
<FilenameWithoutPath>modbus_data.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>::CMSIS</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
@ -980,14 +872,6 @@
|
||||
<RteFlg>1</RteFlg>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>::CMSIS Driver</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>1</RteFlg>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>::Compiler</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
|
||||
@ -15,16 +15,16 @@
|
||||
<uAC6>1</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
<Device>STM32F103C8</Device>
|
||||
<Device>STM32F103C6</Device>
|
||||
<Vendor>STMicroelectronics</Vendor>
|
||||
<PackID>Keil.STM32F1xx_DFP.2.4.0</PackID>
|
||||
<PackURL>http://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000,0x00005000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE</Cpu>
|
||||
<PackID>Keil.STM32F1xx_DFP.2.4.1</PackID>
|
||||
<PackURL>https://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000-0x200027FF) IROM(0x8000000-0x8007FFF) CLOCK(8000000) CPUTYPE("Cortex-M3") TZ</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile></StartupFile>
|
||||
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128 -FS08000000 -FL020000 -FP0($$Device:STM32F103C8$Flash\STM32F10x_128.FLM))</FlashDriverDll>
|
||||
<FlashDriverDll></FlashDriverDll>
|
||||
<DeviceId>0</DeviceId>
|
||||
<RegisterFile>$$Device:STM32F103C8$Device\Include\stm32f10x.h</RegisterFile>
|
||||
<RegisterFile></RegisterFile>
|
||||
<MemoryEnv></MemoryEnv>
|
||||
<Cmp></Cmp>
|
||||
<Asm></Asm>
|
||||
@ -34,7 +34,7 @@
|
||||
<SLE66CMisc></SLE66CMisc>
|
||||
<SLE66AMisc></SLE66AMisc>
|
||||
<SLE66LinkerMisc></SLE66LinkerMisc>
|
||||
<SFDFile>$$Device:STM32F103C8$SVD\STM32F103xx.svd</SFDFile>
|
||||
<SFDFile>$$Device:STM32F103C6$SVD\STM32F103xx.svd</SFDFile>
|
||||
<bCustSvd>0</bCustSvd>
|
||||
<UseEnv>0</UseEnv>
|
||||
<BinPath></BinPath>
|
||||
@ -82,7 +82,7 @@
|
||||
</BeforeMake>
|
||||
<AfterMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<RunUserProg2>1</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
@ -111,7 +111,7 @@
|
||||
</CommonProperty>
|
||||
<DllOption>
|
||||
<SimDllName>SARMCM3.DLL</SimDllName>
|
||||
<SimDllArguments> -REMAP</SimDllArguments>
|
||||
<SimDllArguments>-REMAP</SimDllArguments>
|
||||
<SimDlgDll>DCM.DLL</SimDlgDll>
|
||||
<SimDlgDllArguments>-pCM3</SimDlgDllArguments>
|
||||
<TargetDllName>SARMCM3.DLL</TargetDllName>
|
||||
@ -133,12 +133,12 @@
|
||||
<UseTargetDll>1</UseTargetDll>
|
||||
<UseExternalTool>0</UseExternalTool>
|
||||
<RunIndependent>0</RunIndependent>
|
||||
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
|
||||
<UpdateFlashBeforeDebugging>0</UpdateFlashBeforeDebugging>
|
||||
<Capability>1</Capability>
|
||||
<DriverSelection>4096</DriverSelection>
|
||||
<DriverSelection>4101</DriverSelection>
|
||||
</Flash1>
|
||||
<bUseTDR>1</bUseTDR>
|
||||
<Flash2>BIN\UL2CM3.DLL</Flash2>
|
||||
<Flash2>STLink\ST-LINKIII-KEIL_SWO.dll</Flash2>
|
||||
<Flash3>"" ()</Flash3>
|
||||
<Flash4></Flash4>
|
||||
<pFcarmOut></pFcarmOut>
|
||||
@ -196,7 +196,7 @@
|
||||
<uLtcg>0</uLtcg>
|
||||
<nSecure>0</nSecure>
|
||||
<RoSelD>3</RoSelD>
|
||||
<RwSelD>3</RwSelD>
|
||||
<RwSelD>4</RwSelD>
|
||||
<CodeSel>0</CodeSel>
|
||||
<OptFeed>0</OptFeed>
|
||||
<NoZi1>0</NoZi1>
|
||||
@ -248,12 +248,12 @@
|
||||
<IRAM>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x5000</Size>
|
||||
<Size>0x2800</Size>
|
||||
</IRAM>
|
||||
<IROM>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8000000</StartAddress>
|
||||
<Size>0x10000</Size>
|
||||
<Size>0x8000</Size>
|
||||
</IROM>
|
||||
<XRAM>
|
||||
<Type>0</Type>
|
||||
@ -278,12 +278,12 @@
|
||||
<OCR_RVCT4>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8000000</StartAddress>
|
||||
<Size>0x10000</Size>
|
||||
<Size>0x8000</Size>
|
||||
</OCR_RVCT4>
|
||||
<OCR_RVCT5>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
<StartAddress>0x8008000</StartAddress>
|
||||
<Size>0x2000</Size>
|
||||
</OCR_RVCT5>
|
||||
<OCR_RVCT6>
|
||||
<Type>0</Type>
|
||||
@ -303,7 +303,7 @@
|
||||
<OCR_RVCT9>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x5000</Size>
|
||||
<Size>0x2800</Size>
|
||||
</OCR_RVCT9>
|
||||
<OCR_RVCT10>
|
||||
<Type>0</Type>
|
||||
@ -341,7 +341,7 @@
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,STM32F103x6</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Modbus;..\EEPROM_Emul\lib;..\..\core\STM32_Modbus\Inc</IncludePath>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Modbus</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@ -395,6 +395,11 @@
|
||||
<Group>
|
||||
<GroupName>Application/User/Core</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>UART_TERM.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\Src\UART_TERM.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>dallas_tools.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@ -415,6 +420,21 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\Src\ow_port.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>crc_algs.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Modbus\crc_algs.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Modbus\modbus.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rs_message.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Modbus\rs_message.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>main.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@ -730,11 +750,6 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Core/Src/stm32f1xx_hal_timebase_tim.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>EEPROM_Emul.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\EEPROM_Emul\src\EEPROM_Emul.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
@ -745,16 +760,6 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f1xx_hal_tim.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f1xx_hal_tim_ex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f1xx_hal_adc.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@ -1197,6 +1202,16 @@
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f1xx_hal_tim.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f1xx_hal_tim_ex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f1xx_hal_uart.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@ -1214,82 +1229,9 @@
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>modbus</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>__crc_algs.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\__crc_algs.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>__modbus_compat.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\__modbus_compat.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_coils.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_coils.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_core.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_core.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_devid.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_devid.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_diag.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_diag.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_holdregs.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_holdregs.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_inputregs.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_inputregs.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_master.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_master.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_slave.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\modbus_slave.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rs_message.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\core\STM32_Modbus\Src\rs_message.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_data.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Modbus\modbus_data.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::CMSIS</GroupName>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::CMSIS Driver</GroupName>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::Compiler</GroupName>
|
||||
</Group>
|
||||
@ -1298,21 +1240,8 @@
|
||||
</Targets>
|
||||
|
||||
<RTE>
|
||||
<apis>
|
||||
<api Capiversion="2.3.0" Cclass="CMSIS Driver" Cgroup="Flash" exclusive="0">
|
||||
<package name="CMSIS" schemaVersion="1.7.7" url="http://www.keil.com/pack/" vendor="ARM" version="5.9.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="john103C6T6"/>
|
||||
</targetInfos>
|
||||
</api>
|
||||
</apis>
|
||||
<apis/>
|
||||
<components>
|
||||
<component Capiversion="2.3.0" Cclass="CMSIS Driver" Cgroup="Flash" Csub="Custom" Cvendor="ARM" Cversion="1.0.0" custom="1">
|
||||
<package name="CMSIS" schemaVersion="1.7.7" url="http://www.keil.com/pack/" vendor="ARM" version="5.9.0"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="john103C6T6"/>
|
||||
</targetInfos>
|
||||
</component>
|
||||
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.6.0" condition="ARMv6_7_8-M Device">
|
||||
<package name="CMSIS" schemaVersion="1.7.7" url="http://www.keil.com/pack/" vendor="ARM" version="5.9.0"/>
|
||||
<targetInfos>
|
||||
|
||||
@ -2,14 +2,14 @@
|
||||
; *** Scatter-Loading Description File generated by uVision ***
|
||||
; *************************************************************
|
||||
|
||||
LR_IROM1 0x08000000 0x00010000 { ; load region size_region
|
||||
ER_IROM1 0x08000000 0x00010000 { ; load address = execution address
|
||||
LR_IROM1 0x08000000 0x00008000 { ; load region size_region
|
||||
ER_IROM1 0x08000000 0x00008000 { ; load address = execution address
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
.ANY (+XO)
|
||||
}
|
||||
RW_IRAM1 0x20000000 0x00005000 { ; RW data
|
||||
RW_IRAM1 0x20000000 0x00002800 { ; RW data
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
}
|
||||
|
||||
116
john103C6T6/Modbus/crc_algs.c
Normal file
116
john103C6T6/Modbus/crc_algs.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include "crc_algs.h"
|
||||
|
||||
|
||||
uint32_t CRC_calc;
|
||||
uint32_t CRC_ref;
|
||||
|
||||
//uint16_t CRC_calc;
|
||||
//uint16_t CRC_ref;
|
||||
|
||||
|
||||
// left this global for debug
|
||||
uint8_t uchCRCHi = 0xFF;
|
||||
uint8_t uchCRCLo = 0xFF;
|
||||
unsigned uIndex;
|
||||
|
||||
|
||||
uint32_t crc32(uint8_t *data, uint32_t data_size)
|
||||
{
|
||||
static const unsigned int crc32_table[] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
unsigned int crc = 0xFFFFFFFF;
|
||||
while (data_size--)
|
||||
{
|
||||
crc = (crc >> 8) ^ crc32_table[(crc ^ *data) & 255];
|
||||
data++;
|
||||
}
|
||||
return crc^0xFFFFFFFF;
|
||||
}
|
||||
|
||||
|
||||
uint16_t crc16(uint8_t *data, uint32_t data_size)
|
||||
{
|
||||
/*Table of CRC values for high order byte*/
|
||||
static unsigned char auchCRCHi[]=
|
||||
{
|
||||
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,
|
||||
};
|
||||
/*Table of CRC values for low order byte*/
|
||||
static char auchCRCLo[] =
|
||||
{
|
||||
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,
|
||||
};
|
||||
uchCRCHi = 0xFF;
|
||||
uchCRCLo = 0xFF;
|
||||
/* CRC Generation Function */
|
||||
while( data_size--) /* pass through message buffer */
|
||||
{
|
||||
uIndex = uchCRCHi ^ *data++; /* calculate the CRC */
|
||||
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
|
||||
uchCRCLo = auchCRCLo[uIndex];
|
||||
}
|
||||
return uchCRCHi | uchCRCLo<<8;
|
||||
}
|
||||
9
john103C6T6/Modbus/crc_algs.h
Normal file
9
john103C6T6/Modbus/crc_algs.h
Normal file
@ -0,0 +1,9 @@
|
||||
#include "modbus_config.h"
|
||||
|
||||
// extern here to use in bootloader.c
|
||||
extern uint32_t CRC_calc;
|
||||
extern uint32_t CRC_ref;
|
||||
|
||||
|
||||
uint16_t crc16(uint8_t *data, uint32_t data_size);
|
||||
uint32_t crc32(uint8_t *data, uint32_t data_size);
|
||||
951
john103C6T6/Modbus/modbus.c
Normal file
951
john103C6T6/Modbus/modbus.c
Normal file
@ -0,0 +1,951 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus.c
|
||||
* @brief Модуль для реализации MODBUS.
|
||||
**************************************************************************
|
||||
* @details Файл содержит реализацию функций работы с Modbus, включая:
|
||||
* - доступ к coils и registers;
|
||||
* - обработку команд протокола;
|
||||
* - взаимодействие с RS (UART);
|
||||
* - инициализацию.
|
||||
*
|
||||
* @section Функции и макросы
|
||||
*
|
||||
* ### Доступ к coils:
|
||||
* - MB_Set_Coil_Local() — Установить coil по локальному адресу.
|
||||
* - MB_Reset_Coil_Local() — Сбросить coil по локальному адресу.
|
||||
* - MB_Toogle_Coil_Local() — Инвертировать coil по локальному адресу.
|
||||
* - MB_Read_Coil_Local() — Прочитать coil по локальному адресу.
|
||||
* - MB_Write_Coil_Global() — Установить/сбросить coil по глобальному адресу.
|
||||
* - MB_Read_Coil_Global() — Прочитать coil по глобальному адресу.
|
||||
*
|
||||
* ### Обработка команд Modbus:
|
||||
* - MB_DefineRegistersAddress() — Определить начальный адрес регистра.
|
||||
* - MB_DefineCoilsAddress() — Определить начальный адрес coils.
|
||||
* - MB_Check_Address_For_Arr() — Проверить, принадлежит ли адрес массиву.
|
||||
* - Основные команды Modbus:
|
||||
* - MB_Read_Coils()
|
||||
* - MB_Read_Hold_Regs()
|
||||
* - MB_Write_Single_Coil()
|
||||
* - MB_Write_Miltuple_Coils()
|
||||
* - MB_Write_Miltuple_Regs()
|
||||
*
|
||||
* ### Функции для работы с RS (UART):
|
||||
* - RS_Parse_Message() / RS_Collect_Message() — Парсинг и сборка сообщения.
|
||||
* - RS_Response() — Отправка ответа.
|
||||
* - RS_Define_Size_of_RX_Message() — Определение размера принимаемого сообщения.
|
||||
* - RS_Init() — Инициализация UART.
|
||||
*
|
||||
* ### Инициализация:
|
||||
* - MODBUS_FirstInit() — Инициализация модуля Modbus.
|
||||
*
|
||||
* @section Структура данных Modbus
|
||||
*
|
||||
* #### Holding/Input Registers:
|
||||
* - Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель.
|
||||
* Таким образом, сами регистры могут представлять собой как массив так и структуру.
|
||||
*
|
||||
* #### Coils:
|
||||
* - Coils — это биты, упакованные в 16-битные слова. Доступ к коилам осуществляется через указатель.
|
||||
* Таким образом, сами коилы могут представлять собой как массив так и структуру.
|
||||
*
|
||||
* @section Инструкция по подключению
|
||||
* Для корректной работы надо подключить обработчики RS_UART_Handler(), RS_TIM_Handler(),
|
||||
* в соответствубщие низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler. После HAL'овского обработчика
|
||||
*
|
||||
* Также необходимо в modbus_config.h настроить дефайны для нужной работы UART
|
||||
* После для запуска Modbus:
|
||||
* @verbatim
|
||||
//----------------Прием модбас----------------//
|
||||
#include "rs_message.h"
|
||||
MODBUS_FirstInit();
|
||||
RS_Receive_IT(&hmodbus1, &MODBUS_MSG);
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "rs_message.h"
|
||||
uint32_t dbg_temp, dbg_temp2, dbg_temp3; // for debug
|
||||
/* MODBUS HANDLES */
|
||||
extern UART_HandleTypeDef rs_huart;
|
||||
extern TIM_HandleTypeDef rs_htim;
|
||||
RS_HandleTypeDef hmodbus1;
|
||||
|
||||
/* DEFINE REGISTERS/COILS */
|
||||
MB_DeviceIdentificationTypeDef MB_INFO;
|
||||
MB_DataStructureTypeDef MB_DATA;
|
||||
RS_MsgTypeDef MODBUS_MSG;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//-----------------------------FOR USER------------------------------
|
||||
/**
|
||||
* @brief First set up of MODBUS.
|
||||
* @details Первый инит модбас. Заполняет структуры и инициализирует таймер и юарт для общения по модбас.
|
||||
* @note This called from main
|
||||
*/
|
||||
void MODBUS_FirstInit(void)
|
||||
{
|
||||
MB_DevoceInentificationInit();
|
||||
//-----------SETUP MODBUS-------------
|
||||
// set up modbus: MB_RX_Size_NotConst and Timeout enable
|
||||
hmodbus1.ID = MODBUS_DEVICE_ID;
|
||||
hmodbus1.sRS_Timeout = MODBUS_TIMEOUT;
|
||||
hmodbus1.sRS_Mode = SLAVE_ALWAYS_WAIT;
|
||||
hmodbus1.sRS_RX_Size_Mode = RS_RX_Size_NotConst;
|
||||
|
||||
// INIT
|
||||
hmodbus1.RS_STATUS = RS_Init(&hmodbus1, &rs_huart, &rs_htim, 0);
|
||||
|
||||
RS_EnableReceive();
|
||||
}
|
||||
/**
|
||||
* @brief Set or Reset Coil at its global address.
|
||||
* @param Addr - адрес коила.
|
||||
* @param WriteVal - Что записать в коил: 0 или 1.
|
||||
* @return ExceptionCode - Код исключения если коила по адресу не существует, и NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
||||
Вне зависимости от того как коилы размещены в памяти.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
MB_ExceptionTypeDef Exception = NO_ERRORS;
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
//------------WRITE COIL-------------
|
||||
Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1);
|
||||
if(Exception == NO_ERRORS)
|
||||
{
|
||||
switch(WriteVal)
|
||||
{
|
||||
case SET_COIL:
|
||||
*coils |= (1<<start_shift);
|
||||
break;
|
||||
|
||||
case RESET_COIL:
|
||||
*coils &= ~(1<<start_shift);
|
||||
break;
|
||||
|
||||
case TOOGLE_COIL:
|
||||
*coils ^= (1<<start_shift);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return Exception;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read Coil at its global address.
|
||||
* @param Addr - адрес коила.
|
||||
* @param Exception - Указатель на переменную для кода исключения, в случа неудачи при чтении.
|
||||
* @return uint16_t - Возвращает весь регистр с маской на запрошенном коиле.
|
||||
*
|
||||
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
||||
Вне зависимости от того как коилы размещены в памяти.
|
||||
*/
|
||||
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
MB_ExceptionTypeDef Exception_tmp;
|
||||
if(Exception == NULL) // if exception is not given to func fill it
|
||||
Exception = &Exception_tmp;
|
||||
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
//------------READ COIL--------------
|
||||
*Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0);
|
||||
if(*Exception == NO_ERRORS)
|
||||
{
|
||||
return ((*coils)&(1<<start_shift));
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
|
||||
/**
|
||||
* @brief Check is address valid for certain array.
|
||||
* @param Addr - начальный адресс.
|
||||
* @param Qnt - количество запрашиваемых элементов.
|
||||
* @param R_ARR_ADDR - начальный адресс массива R_ARR.
|
||||
* @param R_ARR_NUMB - количество элементов в массиве R_ARR.
|
||||
* @return ExceptionCode - ILLEGAL DATA ADRESS если адресс недействителен, и NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
|
||||
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
|
||||
* Если адресс Addr находится за пределами адрессов массива R_ARR - ILLEGAL_DATA_ADDRESSю.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
|
||||
{
|
||||
// if address from this array
|
||||
if(Addr >= R_ARR_ADDR)
|
||||
{
|
||||
// if quantity too big return error
|
||||
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
// if all ok - return no errors
|
||||
return NO_ERRORS;
|
||||
}
|
||||
// if address isnt from this array return error
|
||||
else
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for Input/Holding Registers
|
||||
* @param pRegs - указатель на указатель регистров.
|
||||
* @param Addr - адрес начального регистра.
|
||||
* @param Qnt - количество запрашиваемых регистров.
|
||||
* @param WriteFlag - флаг регистр нужны для чтения или записи.
|
||||
* @return ExceptionCode - Код исключения если есть, и NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра.
|
||||
* @note WriteFlag пока не используется.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType)
|
||||
{
|
||||
/* check quantity error */
|
||||
if (Qnt > 125)
|
||||
{
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
if(RegisterType == RegisterType_Holding)
|
||||
{
|
||||
// Default holding registers
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_ADDR, R_HOLDING_QNT) == NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr); // указатель на выбранный по Addr регистр
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else if(RegisterType == RegisterType_Input)
|
||||
{
|
||||
// Default input registers
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_INPUT_ADDR, R_INPUT_QNT) == NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr); // указатель на выбранный по Addr регистр
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ILLEGAL_FUNCTION;
|
||||
}
|
||||
// if found requeried array return no err
|
||||
return NO_ERRORS; // return no errors
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for coils
|
||||
* @param pCoils - указатель на указатель коилов.
|
||||
* @param Addr - адресс начального коила.
|
||||
* @param Qnt - количество запрашиваемых коилов.
|
||||
* @param start_shift - указатель на переменную содержащую сдвиг внутри регистра для начального коила.
|
||||
* @param WriteFlag - флаг коилы нужны для чтения или записи.
|
||||
* @return ExceptionCode - Код исключения если есть, и NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра запрашиваемых коилов.
|
||||
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag)
|
||||
{
|
||||
/* check quantity error */
|
||||
if (Qnt > 2000)
|
||||
{
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
// Default coils
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, C_CONTROL_ADDR, C_CONTROL_QNT) == NO_ERRORS)
|
||||
{
|
||||
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr); // указатель на выбранный по Addr массив коилов
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
|
||||
*start_shift = Addr % 16; // set shift to requested coil
|
||||
// if found requeried array return no err
|
||||
return NO_ERRORS; // return no errors
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Proccess command Read Coils (01 - 0x01).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Read Coils.
|
||||
*/
|
||||
uint8_t MB_Read_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 0);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------READING COIL------------
|
||||
// setup output message data size
|
||||
modbus_msg->ByteCnt = Divide_Up(modbus_msg->Qnt, 8);
|
||||
// create mask for coils
|
||||
uint16_t mask_for_coils = 0; // mask for coils that've been chosen
|
||||
uint16_t setted_coils = 0; // value of setted coils
|
||||
uint16_t temp_reg = 0; // temp register for saving coils that hasnt been chosen
|
||||
uint16_t coil_cnt = 0; // counter for processed coils
|
||||
|
||||
// cycle until all registers with requered coils would be processed
|
||||
int shift = start_shift; // set shift to first coil in first register
|
||||
int ind = 0; // index for coils registers and data
|
||||
for(; ind <= Divide_Up(start_shift + modbus_msg->Qnt, 16); ind++)
|
||||
{
|
||||
//----SET MASK FOR COILS REGISTER----
|
||||
mask_for_coils = 0;
|
||||
for(; shift < 0x10; shift++)
|
||||
{
|
||||
mask_for_coils |= 1<<(shift); // choose certain coil
|
||||
if(++coil_cnt >= modbus_msg->Qnt)
|
||||
break;
|
||||
}
|
||||
shift = 0; // set shift to zero for the next step
|
||||
|
||||
//-----------READ COILS--------------
|
||||
modbus_msg->DATA[ind] = (*(coils+ind)&mask_for_coils) >> start_shift;
|
||||
if(ind > 0)
|
||||
modbus_msg->DATA[ind-1] |= ((*(coils+ind)&mask_for_coils) << 16) >> start_shift;
|
||||
|
||||
}
|
||||
// т.к. DATA 16-битная, для 8-битной передачи, надо поменять местами верхний и нижний байты
|
||||
for(; ind >= 0; --ind)
|
||||
modbus_msg->DATA[ind] = ByteSwap16(modbus_msg->DATA[ind]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Read Holding Registers (03 - 0x03).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Read Holding Registers.
|
||||
*/
|
||||
uint8_t MB_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
//-----------READING REGS------------
|
||||
// setup output message data size
|
||||
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
|
||||
// read data
|
||||
int i;
|
||||
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
modbus_msg->DATA[i] = *(pHoldRegs++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Read Input Registers (04 - 0x04).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Read Input Registers.
|
||||
*/
|
||||
uint8_t MB_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
// get origin address for data
|
||||
uint16_t *pInRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pInRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Input); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
//-----------READING REGS------------
|
||||
// setup output message data size
|
||||
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
|
||||
// read data
|
||||
int i;
|
||||
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
if(*((int16_t *)pInRegs) > 0)
|
||||
modbus_msg->DATA[i] = (*pInRegs++);
|
||||
else
|
||||
modbus_msg->DATA[i] = (*pInRegs++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* @brief Proccess command Write Single Coils (05 - 0x05).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Single Coils.
|
||||
*/
|
||||
uint8_t MB_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if ((modbus_msg->Qnt != 0x0000) && (modbus_msg->Qnt != 0xFF00))
|
||||
{
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
return 0;
|
||||
}
|
||||
// define position of coil
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, 0, &start_shift, 1);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
//----------WRITTING COIL------------
|
||||
if(modbus_msg->Qnt == 0xFF00)
|
||||
*(coils) |= 1<<start_shift; // write flags corresponding to received data
|
||||
else
|
||||
*(coils) &= ~(1<<start_shift); // write flags corresponding to received data
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Write Single Register (06 - 0x06).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Single Register.
|
||||
*/
|
||||
uint8_t MB_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------WRITTING REG------------
|
||||
*(pHoldRegs) = modbus_msg->Qnt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Write Multiple Coils (15 - 0x0F).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Multiple Coils.
|
||||
*/
|
||||
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
|
||||
{ // if quantity too large OR if quantity and bytes count arent match
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
return 0;
|
||||
}
|
||||
// define position of coil
|
||||
uint16_t *coils; // pointer to coils
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 1);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//----------WRITTING COILS-----------
|
||||
// create mask for coils
|
||||
uint16_t mask_for_coils = 0; // mask for coils that've been chosen
|
||||
uint32_t setted_coils = 0; // value of setted coils
|
||||
uint16_t temp_reg = 0; // temp register for saving coils that hasnt been chosen
|
||||
uint16_t coil_cnt = 0; // counter for processed coils
|
||||
|
||||
// cycle until all registers with requered coils would be processed
|
||||
int shift = start_shift; // set shift to first coil in first register
|
||||
for(int ind = 0; ind <= Divide_Up(start_shift + modbus_msg->Qnt, 16); ind++)
|
||||
{
|
||||
//----SET MASK FOR COILS REGISTER----
|
||||
mask_for_coils = 0;
|
||||
for(; shift < 0x10; shift++)
|
||||
{
|
||||
mask_for_coils |= 1<<(shift); // choose certain coil
|
||||
if(++coil_cnt >= modbus_msg->Qnt)
|
||||
break;
|
||||
}
|
||||
shift = 0; // set shift to zero for the next step
|
||||
|
||||
|
||||
|
||||
//-----------WRITE COILS-------------
|
||||
// get current coils
|
||||
temp_reg = *(coils+ind);
|
||||
// set coils
|
||||
setted_coils = ByteSwap16(modbus_msg->DATA[ind]) << start_shift;
|
||||
if(ind > 0)
|
||||
{
|
||||
setted_coils |= ((ByteSwap16(modbus_msg->DATA[ind-1]) << start_shift) >> 16);
|
||||
}
|
||||
// write coils
|
||||
|
||||
*(coils+ind) = setted_coils & mask_for_coils;
|
||||
// restore untouched coils
|
||||
*(coils+ind) |= temp_reg&(~mask_for_coils);
|
||||
|
||||
|
||||
if(coil_cnt >= modbus_msg->Qnt) // if all coils written - break cycle
|
||||
break; // *kind of unnecessary
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Write Multiple Registers (16 - 0x10).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Multiple Registers.
|
||||
*/
|
||||
uint8_t MB_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if (modbus_msg->Qnt*2 != modbus_msg->ByteCnt)
|
||||
{ // if quantity and bytes count arent match
|
||||
modbus_msg->Except_Code = 3;
|
||||
return 0;
|
||||
}
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------WRITTING REGS-----------
|
||||
for (int i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
*(pHoldRegs++) = modbus_msg->DATA[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MB_WriteObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj)
|
||||
{
|
||||
mbdata[(*ind)++] = obj->length;
|
||||
for (int i = 0; i < obj->length; i++)
|
||||
{
|
||||
mbdata[(*ind)++] = obj->name[i];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Proccess command Read Device Identification (43/14 - 0x2B/0E).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Single Register.
|
||||
*/
|
||||
uint8_t MB_Read_Device_Identification(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
char *mbdata = (char *)modbus_msg->DATA;
|
||||
unsigned ind = 0;
|
||||
switch(modbus_msg->DevId.ReadDevId)
|
||||
{
|
||||
case MB_BASIC_IDENTIFICATION:
|
||||
mbdata[ind++] = 0x00;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.VendorName);
|
||||
mbdata[ind++] = 0x01;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ProductCode);
|
||||
mbdata[ind++] = 0x02;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.Revision);
|
||||
modbus_msg->DevId.NumbOfObj = 3;
|
||||
break;
|
||||
case MB_REGULAR_IDENTIFICATION:
|
||||
mbdata[ind++] = 0x03;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.VendorUrl);
|
||||
mbdata[ind++] = 0x04;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ProductName);
|
||||
mbdata[ind++] = 0x05;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ModelName);
|
||||
mbdata[ind++] = 0x06;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.UserApplicationName);
|
||||
modbus_msg->DevId.NumbOfObj = 4;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
modbus_msg->ByteCnt = ind;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Respond accord to received message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о результате ответа на комманду.
|
||||
* @details Обработка принятой комманды и ответ на неё.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
RS_StatusTypeDef MB_RES = 0;
|
||||
hmodbus->f.MessageHandled = 0;
|
||||
hmodbus->f.EchoResponse = 0;
|
||||
RS_Reset_TX_Flags(hmodbus); // reset flag for correct transmit
|
||||
|
||||
if(modbus_msg->Func_Code < ERR_VALUES_START)// if no errors after parsing
|
||||
{
|
||||
switch (modbus_msg->Func_Code)
|
||||
{
|
||||
// Read Coils
|
||||
case MB_R_COILS:
|
||||
hmodbus->f.MessageHandled = MB_Read_Coils(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
// Read Hodling Registers
|
||||
case MB_R_HOLD_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Read_Hold_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
case MB_R_IN_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Read_Input_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
|
||||
// Write Single Coils
|
||||
case MB_W_COIL:
|
||||
hmodbus->f.MessageHandled = MB_Write_Single_Coil(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_W_HOLD_REG:
|
||||
hmodbus->f.MessageHandled = MB_Write_Single_Reg(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
// Write Multiple Coils
|
||||
case MB_W_COILS:
|
||||
hmodbus->f.MessageHandled = MB_Write_Miltuple_Coils(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
// Write Multiple Registers
|
||||
case MB_W_HOLD_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Write_Miltuple_Regs(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_R_DEVICE_INFO:
|
||||
hmodbus->f.MessageHandled = MB_Read_Device_Identification(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
|
||||
/* unknown func code */
|
||||
default: modbus_msg->Except_Code = 0x01; /* set exception code: illegal function */
|
||||
}
|
||||
|
||||
if(hmodbus->f.MessageHandled == 0)
|
||||
{
|
||||
modbus_msg->Func_Code += ERR_VALUES_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// if we need response - check that transmit isnt busy
|
||||
if( RS_Is_TX_Busy(hmodbus) )
|
||||
RS_Abort(hmodbus, ABORT_TX); // if tx busy - set it free
|
||||
|
||||
// Transmit right there, or sets (fDeferredResponse) to transmit response in main code
|
||||
MB_RES = RS_Handle_Transmit_Start(hmodbus, modbus_msg);
|
||||
|
||||
hmodbus->RS_STATUS = MB_RES;
|
||||
return MB_RES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Collect message in buffer to transmit it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения буфера.
|
||||
* @details Заполнение буффера UART из структуры сообщения.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
|
||||
{
|
||||
int ind = 0; // ind for modbus-uart buffer
|
||||
|
||||
if(hmodbus->f.EchoResponse && hmodbus->f.MessageHandled) // if echo response need
|
||||
ind = hmodbus->RS_Message_Size;
|
||||
else
|
||||
{
|
||||
//------INFO ABOUT DATA/MESSAGE------
|
||||
//-----------[first bytes]-----------
|
||||
// set ID of message/user
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
||||
|
||||
// set dat or err response
|
||||
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
|
||||
|
||||
if (modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
|
||||
{
|
||||
// fill modbus header
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // devide identification header
|
||||
{
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.Conformity;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MoreFollows;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.NumbOfObj;
|
||||
|
||||
if (modbus_msg->ByteCnt > DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
|
||||
{
|
||||
return RS_COLLECT_MSG_ERR;
|
||||
}
|
||||
|
||||
|
||||
//---------------DATA----------------
|
||||
//-----------[data bytes]------------
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||
{ // set data
|
||||
modbus_uart_buff[ind++] = *tmp_data_addr;
|
||||
tmp_data_addr++;
|
||||
}
|
||||
|
||||
}
|
||||
else // modbus data header
|
||||
{
|
||||
// set size of received data
|
||||
if (modbus_msg->ByteCnt <= DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
|
||||
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
|
||||
else // otherwise return data_size err
|
||||
{
|
||||
return RS_COLLECT_MSG_ERR;
|
||||
}
|
||||
|
||||
//---------------DATA----------------
|
||||
//-----------[data bytes]------------
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||
{ // set data
|
||||
if (i%2 == 0) // HI byte
|
||||
modbus_uart_buff[ind++] = (*tmp_data_addr)>>8;
|
||||
else // LO byte
|
||||
{
|
||||
modbus_uart_buff[ind++] = *tmp_data_addr;
|
||||
tmp_data_addr++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else // if some error occur
|
||||
{ // send expection code
|
||||
modbus_uart_buff[ind++] = modbus_msg->Except_Code;
|
||||
}
|
||||
}
|
||||
//---------------CRC----------------
|
||||
//---------[last 16 bytes]----------
|
||||
// calc crc of received data
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
// write crc to message structure and modbus-uart buffer
|
||||
modbus_msg->MB_CRC = CRC_VALUE;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
||||
|
||||
hmodbus->RS_Message_Size = ind;
|
||||
|
||||
return RS_OK; // returns ok
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse message from buffer to process it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения структуры.
|
||||
* @details Заполнение структуры сообщения из буффера UART.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
|
||||
{
|
||||
uint32_t check_empty_buff;
|
||||
int ind = 0; // ind for modbus-uart buffer
|
||||
//-----INFO ABOUT DATA/MESSAGE-------
|
||||
//-----------[first bits]------------
|
||||
// get ID of message/user
|
||||
modbus_msg->MbAddr = modbus_uart_buff[ind++];
|
||||
if(modbus_msg->MbAddr != hmodbus->ID)
|
||||
return RS_SKIP;
|
||||
|
||||
// get func code
|
||||
modbus_msg->Func_Code = modbus_uart_buff[ind++];
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // if it device identification request
|
||||
{
|
||||
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
||||
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
||||
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
|
||||
modbus_msg->ByteCnt = 0;
|
||||
}
|
||||
else // if its classic modbus request
|
||||
{
|
||||
// get address from CMD
|
||||
modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->Addr |= modbus_uart_buff[ind++];
|
||||
|
||||
// get address from CMD
|
||||
modbus_msg->Qnt = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->Qnt |= modbus_uart_buff[ind++];
|
||||
}
|
||||
if(hmodbus->f.RX_Half == 0) // if all message received
|
||||
{
|
||||
//---------------DATA----------------
|
||||
// (optional)
|
||||
if (modbus_msg->ByteCnt != 0)
|
||||
{
|
||||
ind++; // increment ind for data_size byte
|
||||
//check that data size is correct
|
||||
if (modbus_msg->ByteCnt > DATA_SIZE*2)
|
||||
{
|
||||
modbus_msg->Func_Code += ERR_VALUES_START;
|
||||
return RS_PARSE_MSG_ERR;
|
||||
}
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // /2 because we transmit 8 bits, not 16 bits
|
||||
{ // set data
|
||||
if (i%2 == 0)
|
||||
*tmp_data_addr = ((uint16_t)modbus_uart_buff[ind++] << 8);
|
||||
else
|
||||
{
|
||||
*tmp_data_addr |= modbus_uart_buff[ind++];
|
||||
tmp_data_addr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------CRC----------------
|
||||
//----------[last 16 bits]----------
|
||||
// calc crc of received data
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
// get crc of received data
|
||||
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
|
||||
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
|
||||
// compare crc
|
||||
if (modbus_msg->MB_CRC != CRC_VALUE)
|
||||
{
|
||||
modbus_msg->Func_Code += ERR_VALUES_START;
|
||||
}
|
||||
// hmodbus->MB_RESPONSE = MB_CRC_ERR; // set func code - error about wrong crc
|
||||
|
||||
// check is buffer empty
|
||||
check_empty_buff = 0;
|
||||
for(int i=0; i<ind;i++)
|
||||
check_empty_buff += modbus_uart_buff[i];
|
||||
// if(check_empty_buff == 0)
|
||||
// hmodbus->MB_RESPONSE = MB_EMPTY_MSG; //
|
||||
}
|
||||
|
||||
return RS_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Define size of RX Message that need to be received.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param rx_data_size - указатель на переменную для записи кол-ва байт для принятия.
|
||||
* @return RS_RES - статус о корректности рассчета кол-ва байт для принятия.
|
||||
* @details Определение сколько байтов надо принять по протоколу.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hmodbus, uint32_t *rx_data_size)
|
||||
{
|
||||
RS_StatusTypeDef MB_RES = 0;
|
||||
|
||||
MB_RES = RS_Parse_Message(hmodbus, hmodbus->pMessagePtr, hmodbus->pBufferPtr);
|
||||
if(MB_RES == RS_SKIP) // if message not for us
|
||||
return MB_RES; // return
|
||||
|
||||
|
||||
if ((hmodbus->pMessagePtr->Func_Code & ~ERR_VALUES_START) < 0x0F)
|
||||
{
|
||||
hmodbus->pMessagePtr->ByteCnt = 0;
|
||||
*rx_data_size = 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
hmodbus->pMessagePtr->ByteCnt = hmodbus->pBufferPtr[RX_FIRST_PART_SIZE-1]; // get numb of data in command
|
||||
// +1 because that defines is size, not ind.
|
||||
*rx_data_size = hmodbus->pMessagePtr->ByteCnt + 2;
|
||||
}
|
||||
|
||||
|
||||
if(hmodbus->pMessagePtr->Func_Code == MB_R_DEVICE_INFO)
|
||||
{
|
||||
*rx_data_size = 0;
|
||||
}
|
||||
|
||||
hmodbus->RS_Message_Size = RX_FIRST_PART_SIZE + *rx_data_size; // size of whole message
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------FOR USER------------------------------
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
void MB_DevoceInentificationInit(void)
|
||||
{
|
||||
MB_INFO.VendorName.name = MODBUS_VENDOR_NAME;
|
||||
MB_INFO.ProductCode.name = MODBUS_PRODUCT_CODE;
|
||||
MB_INFO.Revision.name = MODBUS_REVISION;
|
||||
MB_INFO.VendorUrl.name = MODBUS_VENDOR_URL;
|
||||
MB_INFO.ProductName.name = MODBUS_PRODUCT_NAME;
|
||||
MB_INFO.ModelName.name = MODBUS_MODEL_NAME;
|
||||
MB_INFO.UserApplicationName.name = MODBUS_USER_APPLICATION_NAME;
|
||||
|
||||
|
||||
MB_INFO.VendorName.length = sizeof(MODBUS_VENDOR_NAME);
|
||||
MB_INFO.ProductCode.length = sizeof(MODBUS_PRODUCT_CODE);
|
||||
MB_INFO.Revision.length = sizeof(MODBUS_REVISION);
|
||||
MB_INFO.VendorUrl.length = sizeof(MODBUS_VENDOR_URL);
|
||||
MB_INFO.ProductName.length = sizeof(MODBUS_PRODUCT_NAME);
|
||||
MB_INFO.ModelName.length = sizeof(MODBUS_MODEL_NAME);
|
||||
MB_INFO.UserApplicationName.length = sizeof(MODBUS_USER_APPLICATION_NAME);
|
||||
}
|
||||
|
||||
|
||||
|
||||
376
john103C6T6/Modbus/modbus.h
Normal file
376
john103C6T6/Modbus/modbus.h
Normal file
@ -0,0 +1,376 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus.h
|
||||
* @brief Заголовочный файл модуля MODBUS.
|
||||
* @details Данный файл необходимо подключить в rs_message.h. После подключать
|
||||
* rs_message.h к основному проекту.
|
||||
*
|
||||
* @defgroup MODBUS
|
||||
* @brief Modbus stuff
|
||||
*
|
||||
*************************************************************************/
|
||||
#ifndef __MODBUS_H_
|
||||
#define __MODBUS_H_
|
||||
|
||||
#include "modbus_config.h"
|
||||
#include "modbus_data.h"
|
||||
//#include "settings.h" // for modbus settings
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_SETTINGS
|
||||
* @ingroup MODBUS
|
||||
* @brief Some defines for modbus
|
||||
@{
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////---SETTINGS---/////////////////////////////
|
||||
// USER SETTINGS FOR MODBUS IN interface_config.h
|
||||
//////////////////////////---SETTINGS---/////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////---USER MESSAGE DEFINES---//////////////////////
|
||||
//-------------DEFINES FOR STRUCTURE----------------
|
||||
/* defines for structure of modbus message */
|
||||
#define MbAddr_SIZE 1 ///< size of (MbAddr)
|
||||
#define Func_Code_SIZE 1 ///< size of (Func_Code)
|
||||
#define Addr_SIZE 2 ///< size of (Addr)
|
||||
#define Qnt_SIZE 2 ///< size of (Qnt)
|
||||
#define ByteCnt_SIZE 1 ///< size of (ByteCnt)
|
||||
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
|
||||
#define CRC_SIZE 2 ///< size of (MB_CRC) in bytes
|
||||
|
||||
/** @brief Size of whole message */
|
||||
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
|
||||
|
||||
/** @brief Size of first part of message that will be received
|
||||
first receive info part of message, than defines size of rest message*/
|
||||
#define RX_FIRST_PART_SIZE INFO_SIZE_MAX
|
||||
|
||||
/** @brief Size of buffer: max size of whole message */
|
||||
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
|
||||
|
||||
/** @brief Structure for modbus exception codes */
|
||||
typedef enum //MB_ExceptionTypeDef
|
||||
{
|
||||
// reading
|
||||
NO_ERRORS = 0x00, ///< no errors
|
||||
ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
||||
ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
||||
ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
||||
SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
||||
// ACKNOWLEDGE = 0x05, ///< idk
|
||||
// SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
||||
// MEMORY_PARITY_ERROR = 0x08, ///< idk
|
||||
}MB_ExceptionTypeDef;
|
||||
|
||||
#define ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
||||
/** @brief Structure for modbus func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
/* COMMANDS */
|
||||
// reading
|
||||
MB_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||
MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
||||
MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||
#else
|
||||
MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
||||
#endif
|
||||
|
||||
// writting
|
||||
MB_W_COIL = 0x05, ///< Запись битовой ячейки
|
||||
MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
||||
MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
||||
MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
||||
|
||||
MB_R_DEVICE_INFO = 0x2B, ///< Чтения информации об устройстве
|
||||
|
||||
/* ERRORS */
|
||||
// error reading
|
||||
MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||
MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||
MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||
MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||
|
||||
// error writting
|
||||
MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
||||
MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
||||
MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||
MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||
}MB_FunctonTypeDef;
|
||||
|
||||
/** @brief Structure for MEI func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MEI_DEVICE_IDENTIFICATION = 0x0E,
|
||||
}MB_MEITypeDef;
|
||||
|
||||
/** @brief Structure for MEI func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MB_BASIC_IDENTIFICATION = 0x01,
|
||||
MB_REGULAR_IDENTIFICATION = 0x02,
|
||||
|
||||
|
||||
/* ERRORS */
|
||||
MB_ERR_BASIC_IDENTIFICATION = MB_BASIC_IDENTIFICATION + ERR_VALUES_START,
|
||||
MB_ERR_REGULAR_IDENTIFICATION = MB_REGULAR_IDENTIFICATION + ERR_VALUES_START,
|
||||
}MB_ConformityTypeDef;
|
||||
|
||||
/** @brief Structure for decive identification message type */
|
||||
typedef struct
|
||||
{
|
||||
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identification Interface
|
||||
MB_ConformityTypeDef ReadDevId;
|
||||
MB_ConformityTypeDef Conformity;
|
||||
uint8_t MoreFollows; ///< in this library always a zero
|
||||
uint8_t NextObjId;
|
||||
uint8_t NumbOfObj;
|
||||
}MB_DevIdMsgTypeDef;
|
||||
|
||||
/** @brief Structure for modbus messsage */
|
||||
typedef struct // RS_MsgTypeDef
|
||||
{
|
||||
uint16_t Transaction_ID; ///< Modbus TCP Transaction_ID
|
||||
uint16_t Protocol_ID; ///<
|
||||
uint16_t Pack_length;
|
||||
|
||||
uint8_t MbAddr; ///< Modbus Slave Address
|
||||
MB_FunctonTypeDef Func_Code; ///< Modbus Function Code
|
||||
MB_DevIdMsgTypeDef DevId; ///< Read Device Identification Header struct
|
||||
uint16_t Addr; ///< Modbus Address of data
|
||||
uint16_t Qnt; ///< Quantity of modbus data
|
||||
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
|
||||
|
||||
uint16_t DATA[DATA_SIZE]; ///< Modbus Data
|
||||
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
|
||||
|
||||
uint16_t MB_CRC; ///< Modbus CRC
|
||||
}RS_MsgTypeDef;
|
||||
//--------------------------------------------------
|
||||
extern RS_MsgTypeDef MODBUS_MSG;
|
||||
/////////////////////---MODBUS USER SETTINGS---//////////////////////
|
||||
|
||||
/** MODBUS_SETTINGS
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||
/**
|
||||
* @addtogroup MODBUS_MESSAGE_DEFINES
|
||||
* @ingroup MODBUS
|
||||
* @brief Some defines for modbus
|
||||
@{
|
||||
*/
|
||||
/** @brief Structure for coils operation */
|
||||
typedef enum
|
||||
{
|
||||
SET_COIL,
|
||||
RESET_COIL,
|
||||
TOOGLE_COIL,
|
||||
}MB_CoilsOpTypeDef;
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Macros to set pointer to 16-bit array
|
||||
* @param _arr_ - массив регистров (16-бит).
|
||||
*/
|
||||
#define MB_Set_Arr16_Ptr(_arr_) ((uint16_t*)(&(_arr_)))
|
||||
/**
|
||||
* @brief Macros to set pointer to register
|
||||
* @param _parr_ - массив регистров.
|
||||
* @param _addr_ - Номер регистра (его индекс) от начала массива _arr_.
|
||||
*/
|
||||
#define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_))
|
||||
|
||||
/**
|
||||
* @brief Macros to set pointer to a certain register that contains certain coil
|
||||
* @param _parr_ - массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @note Используется вместе с @ref MB_Set_Coil_Mask
|
||||
@verbatim Пояснение выражений
|
||||
(_coil_/16) - get index (address shift) of register that contain certain coil
|
||||
Visual explanation: 30th coil in coils registers array
|
||||
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
||||
|register[0]----| |register[1]----|
|
||||
|skip this------| |get this-------|
|
||||
|shift to 14 bit|
|
||||
@endverbatim
|
||||
*/
|
||||
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
|
||||
/**
|
||||
* @brief Macros to set mask to a certain bit in coils register
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
|
||||
@verbatim Пояснение выражений
|
||||
(16*(_coil_/16) - how many coils we need to skip. e.g. (16*30/16) - skip 16 coils from first register
|
||||
_coil_-(16*(_coil_/16)) - shift to certain coil in certain register
|
||||
e.g. Coil(30) gets in register[1] (30/16 = 1) coil №14 (30 - (16*30/16) = 30 - 16 = 14)
|
||||
|
||||
Visual explanation: 30th coil in coils registers array
|
||||
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
||||
|register[0]----| |register[1]----|
|
||||
|skip this------| |get this-------|
|
||||
|shift to 14 bit|
|
||||
@endverbatim
|
||||
*/
|
||||
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
|
||||
|
||||
/**
|
||||
* @brief Read Coil at its local address.
|
||||
* @param _parr_ - массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @return uint16_t - Возвращает запрошенный коил на 0м бите.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Read_Coil_Local(_parr_, _coil_) (( *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) & MB_Set_Coil_Mask(_coil_) ) >> (_coil_))
|
||||
/**
|
||||
* @brief Set Coil at its local address.
|
||||
* @param _parr_ - указатель на массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Set_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) |= MB_Set_Coil_Mask(_coil_)
|
||||
/**
|
||||
* @brief Reset Coil at its local address.
|
||||
* @param _parr_ - указатель на массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Reset_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) &= ~(MB_Set_Coil_Mask(_coil_))
|
||||
/**
|
||||
* @brief Set Coil at its local address.
|
||||
* @param _parr_ - указатель на массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Toogle_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ^= MB_Set_Coil_Mask(_coil_)
|
||||
//--------------------------------------------------
|
||||
|
||||
|
||||
//------------------OTHER DEFINES-------------------
|
||||
#define RegisterType_Holding 0
|
||||
#define RegisterType_Input 1
|
||||
#define RegisterType_Discrete 2
|
||||
// create hadnles and settings for uart, tim, rs with _modbus_ name
|
||||
//--------------------------------------------------
|
||||
|
||||
#ifndef Divide_Up
|
||||
/**
|
||||
* @brief Calc dividing including remainder
|
||||
* @param _val_ - делимое.
|
||||
* @param _div_ - делитель.
|
||||
* @details Если результат деления без остатка: он возвращается как есть
|
||||
Если с остатком - округляется вверх
|
||||
*/
|
||||
//#define Divide_Up(_val_, _div_) (((_val_)%(_div_))? (_val_)/(_div_)+1 : (_val_)/_div_) /* через тернарный оператор */
|
||||
#define Divide_Up(_val_, _div_) ((_val_ - 1) / _div_) + 1 /* через мат выражение */
|
||||
#endif
|
||||
|
||||
#ifndef ByteSwap16
|
||||
/**
|
||||
* @brief Swap between Little Endian and Big Endian
|
||||
* @param v - Переменная для свапа.
|
||||
* @return v (new) - Свапнутая переменная.
|
||||
* @details Переключения между двумя типами хранения слова: HI-LO байты и LO-HI байты.
|
||||
*/
|
||||
#define ByteSwap16(v) (((v&0xFF00) >> (8)) | ((v&0x00FF) << (8)))
|
||||
#endif
|
||||
/** GENERAL_MODBUS_STUFF
|
||||
* @}
|
||||
*/
|
||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
/**
|
||||
* @addtogroup MODBUS_FUNCTIONS
|
||||
* @ingroup MODBUS
|
||||
* @brief Function for controling modbus communication
|
||||
*/
|
||||
|
||||
//----------------FUNCTIONS FOR USER----------------
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
|
||||
* @ingroup MODBUS_FUNCTIONS
|
||||
* @brief Function for user use
|
||||
@{
|
||||
*/
|
||||
/* First set up of MODBUS */
|
||||
void MODBUS_FirstInit(void);
|
||||
/* Set or Reset Coil at its global address */
|
||||
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal);
|
||||
/* Read Coil at its global address */
|
||||
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
||||
|
||||
/** MODBUS_DATA_ACCESS_FUNCTIONS
|
||||
* @}
|
||||
*/
|
||||
|
||||
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||
/**
|
||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
* @ingroup MODBUS_FUNCTIONS
|
||||
* @brief Function process commands
|
||||
@{
|
||||
*/
|
||||
/* Check is address valid for certain array */
|
||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB);
|
||||
/* Define Address Origin for Input/Holding Registers */
|
||||
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType);
|
||||
/* Define Address Origin for coils */
|
||||
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag);
|
||||
/* Proccess command Read Coils (01 - 0x01) */
|
||||
uint8_t MB_Read_Coils(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Read Holding Registers (03 - 0x03) */
|
||||
uint8_t MB_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Read Input Registers (04 - 0x04) */
|
||||
uint8_t MB_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Write Single Coils (05 - 0x05) */
|
||||
uint8_t MB_Write_Single_Coil(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Write Multiple Coils (15 - 0x0F) */
|
||||
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Write Multiple Register (16 - 0x10) */
|
||||
uint8_t MB_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
|
||||
/** MODBUS_DATA_ACCESS_FUNCTIONS
|
||||
* @}
|
||||
*/
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////---CALC DEFINES---//////////////////////////
|
||||
|
||||
|
||||
// TRACES DEFINES
|
||||
#ifndef Trace_MB_UART_Enter
|
||||
#define Trace_MB_UART_Enter()
|
||||
#endif //Trace_MB_UART_Enter
|
||||
|
||||
#ifndef Trace_MB_UART_Exit
|
||||
#define Trace_MB_UART_Exit()
|
||||
#endif //Trace_MB_UART_Exit
|
||||
|
||||
#ifndef Trace_MB_TIM_Enter
|
||||
#define Trace_MB_TIM_Enter()
|
||||
#endif //Trace_MB_TIM_Enter
|
||||
|
||||
#ifndef Trace_MB_TIM_Exit
|
||||
#define Trace_MB_TIM_Exit()
|
||||
#endif //Trace_MB_TIM_Exit
|
||||
|
||||
#endif //__MODBUS_H_
|
||||
@ -1,60 +1,33 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file modbus_config.h
|
||||
* @brief Конфигурационные параметры Modbus устройства
|
||||
******************************************************************************
|
||||
@addtogroup MODBUS_CONFIGS Modbus configs
|
||||
@ingroup MODBUS
|
||||
@brief Конфигурация библиотеки
|
||||
@{
|
||||
******************************************************************************
|
||||
* @details
|
||||
Файл содержит настройки для работы Modbus:
|
||||
- Подключение библиотек контроллера
|
||||
- ID устройства и таймауты
|
||||
- Строковые идентификаторы (Vendor, Product, Revision)
|
||||
- Настройки периферии (UART, TIMER)
|
||||
- Подключение модулей Modbus
|
||||
- Опциональные функции (переключение команд 0x03/0x04)
|
||||
******************************************************************************/
|
||||
**************************************************************************
|
||||
* @file interface_config.h
|
||||
* @brief Конфигурация для модбаса
|
||||
*************************************************************************/
|
||||
#ifndef _MODBUS_CONFIG_H_
|
||||
#define _MODBUS_CONFIG_H_
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
// Общие параметры
|
||||
#define MODBUS_DEVICE_ID 1 ///< Адрес устройства в сети Modbus
|
||||
#define MODBUS_TIMEOUT 5000 ///< Таймаут в тиках таймера
|
||||
// MODBUS PARAMS
|
||||
#define MODBUS_DEVICE_ID 1 ///< девайс текущего устройства
|
||||
#define MODBUS_TIMEOUT 2000 ///< максимальнйы тайтаут MB в тиках таймера
|
||||
|
||||
// Строковые идентификаторы устройства
|
||||
// STRING OBJECTS MODBUS
|
||||
#define MODBUS_VENDOR_NAME "NIO-12"
|
||||
#define MODBUS_PRODUCT_CODE ""
|
||||
#define MODBUS_REVISION ""
|
||||
#define MODBUS_REVISION "Ver. 1.0"
|
||||
#define MODBUS_VENDOR_URL ""
|
||||
#define MODBUS_PRODUCT_NAME ""
|
||||
#define MODBUS_MODEL_NAME ""
|
||||
#define MODBUS_MODEL_NAME "STM32F103"
|
||||
#define MODBUS_USER_APPLICATION_NAME ""
|
||||
|
||||
#define MODBUS_NUMB_OF_USEROBJECTS 0 ///< Количество пользовательских объектов
|
||||
#define MODBUS_USEROBJECT_0_NAME "" ///< Строка пользовательского идентификатора 0. По аналогии можно определить строки до <=128 USEROBJECT
|
||||
// PERIPH FUNCTIONS AND HANDLERS
|
||||
#define RS_UART_Init MX_USART1_UART_Init //инициализация uart
|
||||
#define RS_UART_DeInit HAL_UART_MspDeInit //деинициализация uart
|
||||
#define RS_TIM_Init MX_TIM2_Init //инициализация таймера
|
||||
#define RS_TIM_DeInit HAL_TIM_Base_MspDeInit//деинициализация таймера
|
||||
#define rs_huart huart1 //используемый uart
|
||||
#define rs_htim htim2 //используемый таймера
|
||||
|
||||
// Периферия (опционально)
|
||||
#define mb_huart huart1 ///< Удобный дефайн для модбасовского uart
|
||||
#define mb_htim htim2 ///< Удобный дефайн для модбасовского таймера
|
||||
//#define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485
|
||||
//#define RS_EnableTransmit() ///< Функция изменения направления передачи на ПЕРЕДАЧУ для RS-485
|
||||
|
||||
|
||||
// Модули modbus
|
||||
#define MODBUS_ENABLE_SLAVE ///< Включить обработку СЛЕЙВ режима
|
||||
//#define MODBUS_ENABLE_MASTER ///< Включить обработку МАСТЕР режима
|
||||
|
||||
#define MODBUS_ENABLE_COILS ///< Включить обработку коилов
|
||||
#define MODBUS_ENABLE_HOLDINGS ///< Включить обработку регистров хранения
|
||||
#define MODBUS_ENABLE_INPUTS ///< Включить обработку входных регистров
|
||||
#define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства
|
||||
#define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас
|
||||
|
||||
//#define MODBUS_PROTOCOL_TCP ///< Включить TCP-протокол, иначе - RTU
|
||||
|
||||
/**
|
||||
* @brief Поменять комманды 0x03 и 0x04 местами (для LabView терминалки от двигателей)
|
||||
@ -68,4 +41,4 @@
|
||||
|
||||
|
||||
|
||||
#endif //_MODBUS_CONFIG_H_
|
||||
#endif //_MODBUS_CONFIG_H_
|
||||
@ -1,141 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file modbus_data.c
|
||||
* @brief Функции доступа к данным Modbus
|
||||
******************************************************************************
|
||||
* @details
|
||||
Модуль реализует функции валидации адресов и доступа к данным:
|
||||
- Проверка корректности запрашиваемых адресов
|
||||
- Определение указателей на реальные данные в памяти
|
||||
- Поддержка пользовательских массивов регистров и coils
|
||||
|
||||
@section Валидация адресов:
|
||||
- MB_Check_Address_For_Arr() - проверка принадлежности адреса массиву
|
||||
- MB_DefineRegistersAddress() - получение указателя на регистры
|
||||
- MB_DefineCoilsAddress() - получение указателя на coils
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "modbus_core.h"
|
||||
#include "modbus_coils.h"
|
||||
#include "modbus_holdregs.h"
|
||||
#include "modbus_inputregs.h"
|
||||
#include "modbus_devid.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check is address valid for certain array.
|
||||
* @param Addr Начальный адресс.
|
||||
* @param Qnt Количество запрашиваемых элементов.
|
||||
* @param R_ARR_ADDR Начальный адресс массива R_ARR.
|
||||
* @param R_ARR_NUMB Количество элементов в массиве R_ARR.
|
||||
* @return ExceptionCode - ET_ILLEGAL_DATA_ADRESS если адресс недействителен, и ET_NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
|
||||
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
|
||||
* Если адресс Addr находится за пределами адрессов массива R_ARR - ET_ILLEGAL_DATA_ADDRESSю.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
|
||||
{
|
||||
// if address from this array
|
||||
if(Addr >= R_ARR_ADDR)
|
||||
{
|
||||
// if quantity too big return error
|
||||
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
|
||||
{
|
||||
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
// if all ok - return no errors
|
||||
return ET_NO_ERRORS;
|
||||
}
|
||||
// if address isnt from this array return error
|
||||
else
|
||||
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for Input/Holding Registers
|
||||
* @param pRegs Указатель на указатель регистров.
|
||||
* @param Addr Адрес начального регистра.
|
||||
* @param Qnt Количество запрашиваемых регистров.
|
||||
* @param WriteFlag Флаг регистр нужны для чтения или записи.
|
||||
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра.
|
||||
* @note WriteFlag пока не используется.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType)
|
||||
{
|
||||
/* check quantity error */
|
||||
if (Qnt > DATA_SIZE)
|
||||
{
|
||||
return ET_ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
if(RegisterType == RegisterType_Holding)
|
||||
{
|
||||
// Default holding registers
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_ADDR, R_HOLDING_QNT) == ET_NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr - R_HOLDING_ADDR); // указатель на выбранный по Addr регистр
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ET_ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else if(RegisterType == RegisterType_Input)
|
||||
{
|
||||
// Default input registers
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_INPUT_ADDR, R_INPUT_QNT) == ET_NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr - R_INPUT_ADDR); // указатель на выбранный по Addr регистр
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ET_ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ET_ILLEGAL_FUNCTION;
|
||||
}
|
||||
// if found requeried array return no err
|
||||
return ET_NO_ERRORS; // return no errors
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for coils
|
||||
* @param pCoils Указатель на указатель коилов.
|
||||
* @param Addr Адресс начального коила.
|
||||
* @param Qnt Количество запрашиваемых коилов.
|
||||
* @param start_shift Указатель на переменную содержащую сдвиг внутри регистра для начального коила.
|
||||
* @param WriteFlag Флаг коилы нужны для чтения или записи.
|
||||
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра запрашиваемых коилов.
|
||||
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag)
|
||||
{
|
||||
/* check quantity error */
|
||||
if (Qnt > 2000)
|
||||
{
|
||||
return ET_ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
// Default coils
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, C_CONTROL_ADDR, C_CONTROL_QNT) == ET_NO_ERRORS)
|
||||
{
|
||||
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr - C_CONTROL_ADDR); // указатель на выбранный по Addr массив коилов
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ET_ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
|
||||
*start_shift = Addr % 16; // set shift to requested coil
|
||||
// if found requeried array return no err
|
||||
return ET_NO_ERRORS; // return no errors
|
||||
}
|
||||
@ -11,32 +11,10 @@
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _MODBUS_DATA_H_
|
||||
#define _MODBUS_DATA_H_
|
||||
|
||||
|
||||
// DEFINES FOR INPUT REGISTERS ARRAYS
|
||||
#define R_INPUT_ADDR 0
|
||||
#define R_INPUT_QNT 2000
|
||||
|
||||
// DEFINES FOR HOLDING REGISTERS ARRAYS
|
||||
#define R_HOLDING_ADDR 0
|
||||
#define R_HOLDING_QNT 2000
|
||||
|
||||
// DEFINES FOR COIL ARRAYS
|
||||
#define C_CONTROL_ADDR 0
|
||||
#define C_CONTROL_QNT 1000
|
||||
|
||||
|
||||
|
||||
|
||||
#include "stdint.h"
|
||||
#include "ds18b20_driver.h"
|
||||
#include "PROJ_setup.h"
|
||||
|
||||
|
||||
//--------------DEFINES FOR REGISTERS---------------
|
||||
// DEFINES FOR ARRAYS
|
||||
/**
|
||||
@ -63,53 +41,40 @@
|
||||
/**
|
||||
* @brief Регистры хранения
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Определить размер структуры в регистрах модбас (16-бит слова)
|
||||
*/
|
||||
#define mb_sizeof(_struct_) (sizeof(_struct_)/sizeof(uint16_t))
|
||||
/**
|
||||
* @brief Определить количество резервных байт для выравнивания
|
||||
* @details Выравнивает так, чтобы количество регистров в _struct_ и reserved равнялось _align_.
|
||||
*
|
||||
*/
|
||||
#define mb_fill_rsv(_align_, _struct_) ((_align_ > mb_sizeof(_struct_)) ? (_align_ - mb_sizeof(_struct_)) : 0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef __PACKED_STRUCT//MB_DataInRegsTypeDef
|
||||
|
||||
#define MAX_SENSE 30
|
||||
|
||||
typedef struct //MB_DataInRegsTypeDef
|
||||
{
|
||||
uint16_t sens_Temp[MAX_SENSE];
|
||||
uint16_t UzptPLUS;
|
||||
uint16_t UzptMINUS;
|
||||
uint16_t UzptPLUS_MIN;
|
||||
|
||||
uint16_t sens_Temp[MAX_SENSE];
|
||||
|
||||
uint16_t reserve[mb_fill_rsv(1000, uint16_t[MAX_SENSE])];
|
||||
|
||||
DS18B20_Drv_t ID;
|
||||
uint16_t reserve1[mb_fill_rsv(200, DS18B20_Drv_t)];
|
||||
uint16_t num_Tsens;
|
||||
|
||||
|
||||
|
||||
}MB_DataInRegsTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Входные регистры
|
||||
*/
|
||||
typedef __PACKED_STRUCT //MB_DataInRegsTypeDef
|
||||
typedef struct //MB_DataInRegsTypeDef
|
||||
{
|
||||
uint16_t set_Temp[MAX_SENSE];
|
||||
uint16_t reserve[mb_fill_rsv(100, uint16_t[MAX_SENSE])];
|
||||
uint16_t set_Temp[MAX_SENSE];
|
||||
uint16_t set_hyst[MAX_SENSE];
|
||||
uint16_t reserve1[mb_fill_rsv(100, uint16_t[MAX_SENSE])];
|
||||
}MB_DataHoldRegsTypeDef;
|
||||
|
||||
|
||||
// DEFINES FOR INPUT REGISTERS ARRAYS
|
||||
#define R_INPUT_ADDR 0
|
||||
#define R_INPUT_QNT 40
|
||||
|
||||
// DEFINES FOR HOLDING REGISTERS ARRAYS
|
||||
#define R_HOLDING_ADDR 0
|
||||
#define R_HOLDING_QNT 40
|
||||
|
||||
|
||||
/** MODBUS_DATA_RERISTERS_DEFINES
|
||||
@ -145,9 +110,8 @@ typedef __PACKED_STRUCT //MB_DataInRegsTypeDef
|
||||
* @details Желательно с помощью reserved делать стркутуру кратной 16-битам
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
__PACKED_STRUCT
|
||||
{
|
||||
{
|
||||
struct __packed {
|
||||
unsigned state_val_01:1;
|
||||
unsigned state_val_02:1;
|
||||
unsigned state_val_03:1;
|
||||
@ -169,92 +133,19 @@ typedef union
|
||||
|
||||
|
||||
}word;
|
||||
typedef union
|
||||
{
|
||||
__PACKED_STRUCT
|
||||
{
|
||||
unsigned Temp1_relay_isOn :1;
|
||||
unsigned Temp2_relay_isOn :1;
|
||||
unsigned Temp3_relay_isOn :1;
|
||||
unsigned Temp4_relay_isOn :1;
|
||||
unsigned Temp5_relay_isOn :1;
|
||||
unsigned Temp6_relay_isOn :1;
|
||||
unsigned Temp7_relay_isOn :1;
|
||||
unsigned Temp8_relay_isOn :1;
|
||||
unsigned Temp9_relay_isOn :1;
|
||||
unsigned Temp10_relay_isOn :1;
|
||||
unsigned Temp11_relay_isOn :1;
|
||||
unsigned Temp12_relay_isOn :1;
|
||||
unsigned Temp13_relay_isOn :1;
|
||||
unsigned Temp14_relay_isOn :1;
|
||||
unsigned Temp15_relay_isOn :1;
|
||||
unsigned Temp16_relay_isOn :1;
|
||||
|
||||
|
||||
} state_val_bit;
|
||||
uint16_t all;
|
||||
|
||||
|
||||
}RELAY_Struct;
|
||||
|
||||
typedef union
|
||||
{
|
||||
__PACKED_STRUCT
|
||||
{
|
||||
unsigned Temp1_isConnected :1;
|
||||
unsigned Temp2_isConnected :1;
|
||||
unsigned Temp3_isConnected :1;
|
||||
unsigned Temp4_isConnected :1;
|
||||
unsigned Temp5_isConnected :1;
|
||||
unsigned Temp6_isConnected :1;
|
||||
unsigned Temp7_isConnected :1;
|
||||
unsigned Temp8_isConnected :1;
|
||||
unsigned Temp9_isConnected :1;
|
||||
unsigned Temp10_isConnected :1;
|
||||
unsigned Temp11_isConnected :1;
|
||||
unsigned Temp12_isConnected :1;
|
||||
unsigned Temp13_isConnected :1;
|
||||
unsigned Temp14_isConnected :1;
|
||||
unsigned Temp15_isConnected :1;
|
||||
unsigned Temp16_isConnected :1;
|
||||
|
||||
} state_val_bit;
|
||||
uint16_t all;
|
||||
|
||||
|
||||
}STATUS_TSENS;
|
||||
|
||||
|
||||
typedef __PACKED_STRUCT
|
||||
{
|
||||
int temp ;
|
||||
unsigned Temp_relay_on :1;
|
||||
unsigned Temp_relay_off :1;
|
||||
unsigned is_connect:1;
|
||||
|
||||
}Temp_sens;
|
||||
extern Temp_sens temp_sens ;
|
||||
|
||||
typedef __PACKED_STRUCT
|
||||
typedef struct //MB_DataCoilsTypeDef
|
||||
{
|
||||
|
||||
|
||||
|
||||
word coils[3]; //48
|
||||
uint16_t reserve1[mb_fill_rsv(128/16, word[3])];
|
||||
STATUS_TSENS status_tSens[MAX_SENSE/16]; //32
|
||||
uint16_t reserve2[mb_fill_rsv(128/16, STATUS_TSENS[MAX_SENSE/16])];
|
||||
RELAY_Struct relay_struct[MAX_SENSE/16*2];//16 2 реле на 1 датчик
|
||||
uint16_t reserve3[mb_fill_rsv(128/16, RELAY_Struct[MAX_SENSE/16*2])];
|
||||
|
||||
unsigned init_param:1; //384
|
||||
unsigned init_Tsens:1; //385
|
||||
unsigned Save_Param_to_Flash:1; //386
|
||||
unsigned reserved2:13;
|
||||
word coils[2];
|
||||
unsigned init_param:1;
|
||||
unsigned reserved:15;
|
||||
|
||||
}MB_DataCoilsTypeDef;
|
||||
|
||||
|
||||
// DEFINES FOR COIL ARRAYS
|
||||
#define C_CONTROL_ADDR 0
|
||||
#define C_CONTROL_QNT 100
|
||||
|
||||
/** MODBUS_DATA_COILS_DEFINES
|
||||
* @}
|
||||
@ -277,6 +168,33 @@ typedef struct // tester modbus data
|
||||
}MB_DataStructureTypeDef;
|
||||
extern MB_DataStructureTypeDef MB_DATA;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Структура для объекта Modbus
|
||||
* @ingroup MODBUS_DATA
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned length;
|
||||
char *name;
|
||||
}MB_DeviceObjectTypeDef;
|
||||
/**
|
||||
* @brief Структура для объектов Modbus
|
||||
* @ingroup MODBUS_DATA
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MB_DeviceObjectTypeDef VendorName;
|
||||
MB_DeviceObjectTypeDef ProductCode;
|
||||
MB_DeviceObjectTypeDef Revision;
|
||||
MB_DeviceObjectTypeDef VendorUrl;
|
||||
MB_DeviceObjectTypeDef ProductName;
|
||||
MB_DeviceObjectTypeDef ModelName;
|
||||
MB_DeviceObjectTypeDef UserApplicationName;
|
||||
}MB_DeviceIdentificationTypeDef;
|
||||
void MB_DevoceInentificationInit(void);
|
||||
|
||||
|
||||
#endif //_MODBUS_DATA_H_
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
555
john103C6T6/Modbus/rs_message.c
Normal file
555
john103C6T6/Modbus/rs_message.c
Normal file
@ -0,0 +1,555 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file rs_message.c
|
||||
* @brief Модуль для реализации протоколов по RS/UART.
|
||||
**************************************************************************\
|
||||
* @details
|
||||
* Данный модуль реализует основные функции для приема и передачи сообщений
|
||||
* по протоколу RS через UART в режиме прерываний. Реализована обработка
|
||||
* приема и передачи данных, управление состояниями RS, а также функции для
|
||||
* инициализации и управления периферией.
|
||||
*
|
||||
* Реализованы следующие функции:
|
||||
* - RS_Receive_IT() — запуск приема данных в прерывании по UART.
|
||||
* - RS_Transmit_IT() — запуск передачи данных в прерывании по UART.
|
||||
* - RS_Init() — инициализация структуры RS и привязка периферии.
|
||||
* - RS_ReInit_UART() — переинициализация UART и перезапуск приема данных.
|
||||
* - RS_Abort() — остановка работы RS/UART с очисткой флагов и структур.
|
||||
* - RS_Handle_Receive_Start() — обработка старта приема данных по RS.
|
||||
*
|
||||
* В модуле также определен буфер RS_Buffer[] для хранения принимаемых/передаваемых данных.
|
||||
*
|
||||
* @note
|
||||
* Для корректной работы модуля предполагается использование соответствующих
|
||||
* обработчиков прерываний UART и таймера (RS_UART_Handler(), RS_TIM_Handler()),
|
||||
* которые надо вызывать с обработчиках используемой периферии
|
||||
|
||||
@verbatim
|
||||
//-------------------Функции-------------------//
|
||||
Functions: users
|
||||
- RS_Parse_Message/RS_Collect_Message Заполнение структуры сообщения и буфера
|
||||
- RS_Response Ответ на сообщение
|
||||
- RS_Define_Size_of_RX_Message Определение размера принимаемых данных
|
||||
|
||||
Functions: general
|
||||
- RS_Receive_IT Ожидание комманды и ответ на неё
|
||||
- RS_Transmit_IT Отправление комманды и ожидание ответа
|
||||
- RS_Init Инициализация переферии и структуры для RS
|
||||
- RS_ReInit_UART Реинициализация UART для RS
|
||||
- RS_Abort Отмена приема/передачи по ЮАРТ
|
||||
- RS_Init Инициализация периферии и modbus handler
|
||||
|
||||
Functions: callback/handler
|
||||
- RS_Handle_Receive_Start Функция для запуска приема или остановки RS
|
||||
- RS_Handle_Transmit_Start Функция для запуска передачи или остановки RS
|
||||
|
||||
- RS_UART_RxCpltCallback Коллбек при окончании приема или передачи
|
||||
RS_UART_TxCpltCallback
|
||||
|
||||
- RS_UART_Handler Обработчик прерывания для UART
|
||||
- RS_TIM_Handler Обработчик прерывания для TIM
|
||||
|
||||
@endverbatim
|
||||
*************************************************************************/
|
||||
#include "rs_message.h"
|
||||
|
||||
uint8_t RS_Buffer[MSG_SIZE_MAX]; // uart buffer
|
||||
|
||||
extern void RS_UART_Init(void);
|
||||
extern void RS_UART_DeInit(UART_HandleTypeDef *huart);
|
||||
extern void RS_TIM_Init(void);
|
||||
extern void RS_TIM_DeInit(TIM_HandleTypeDef *htim);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
/**
|
||||
* @brief Start receive IT.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации приема.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
//-------------CHECK RS LINE----------------
|
||||
// check that receive isnt busy
|
||||
if( RS_Is_RX_Busy(hRS) ) // if tx busy - return busy status
|
||||
return RS_BUSY;
|
||||
|
||||
//-----------INITIALIZE RECEIVE-------------
|
||||
// if all OK: start receiving
|
||||
RS_EnableReceive();
|
||||
RS_Set_Busy(hRS); // set RS busy
|
||||
RS_Set_RX_Flags(hRS); // initialize flags for receive
|
||||
hRS->pMessagePtr = RS_msg; // set pointer to message structire for filling it from UARTHandler fucntions
|
||||
|
||||
// start receiving
|
||||
uart_res = HAL_UART_Receive_IT(hRS->huart, hRS->pBufferPtr, RX_FIRST_PART_SIZE); // receive until ByteCnt+1 byte,
|
||||
// then in Callback restart receive for rest bytes
|
||||
|
||||
// if receive isnt started - abort RS
|
||||
if(uart_res != HAL_OK)
|
||||
{
|
||||
RS_RES = RS_Abort(hRS, ABORT_RS);
|
||||
printf_rs_err("\n%d: Error RS: Failed to start RS receiving...", uwTick);
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_RES = RS_OK;
|
||||
printf_rs("\n%d: RS: Start Receiving...", uwTick);
|
||||
}
|
||||
|
||||
hRS->RS_STATUS = RS_RES;
|
||||
return RS_RES; // returns result of receive init
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start transmit IT.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации передачи.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
//-------------CHECK RS LINE----------------
|
||||
// check that transmit isnt busy
|
||||
if( RS_Is_TX_Busy(hRS) ) // if tx busy - return busy status
|
||||
return RS_BUSY;
|
||||
// check receive line
|
||||
|
||||
|
||||
//------------COLLECT MESSAGE---------------
|
||||
RS_RES = RS_Collect_Message(hRS, RS_msg, hRS->pBufferPtr);
|
||||
if (RS_RES != RS_OK) // if message isnt collect - stop RS and return error in RS_RES
|
||||
{// need collect message status, so doesnt write abort to RS_RES
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr); // restart receive
|
||||
}
|
||||
else // if collect successful
|
||||
{
|
||||
|
||||
//----------INITIALIZE TRANSMIT-------------
|
||||
RS_EnableTransmit();
|
||||
// for(int i = 0; i < hRS->sRS_Timeout; i++);
|
||||
|
||||
RS_Set_Busy(hRS); // set RS busy
|
||||
RS_Set_TX_Flags(hRS); // initialize flags for transmit IT
|
||||
hRS->pMessagePtr = RS_msg; // set pointer for filling given structure from UARTHandler fucntion
|
||||
|
||||
// if all OK: start transmitting
|
||||
uart_res = HAL_UART_Transmit_IT(hRS->huart, hRS->pBufferPtr, hRS->RS_Message_Size);
|
||||
// if transmit isnt started - abort RS
|
||||
if(uart_res != HAL_OK)
|
||||
{
|
||||
RS_RES = RS_Abort(hRS, ABORT_RS);
|
||||
printf_rs_err("\n%d: Error RS: Failed to start RS transmitting...", uwTick);
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_RES = RS_OK;
|
||||
printf_rs("\n%d: RS: Start Transmitting...", uwTick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hRS->RS_STATUS = RS_RES;
|
||||
return RS_RES; // returns result of transmit init
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize UART and handle RS stucture.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param suart - указатель на структуру с настройками UART.
|
||||
* @param stim - указатель на структуру с настройками таймера.
|
||||
* @param pRS_BufferPtr - указатель на буффер для приема-передачи по UART. Если он NULL, то поставиться библиотечный буфер.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации.
|
||||
* @note Инициализация перефирии и структуры для приема-передачи по RS.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr)
|
||||
{
|
||||
// check that hRS is defined
|
||||
if (hRS == NULL)
|
||||
return RS_ERR;
|
||||
// check that huart is defined
|
||||
if (huart == NULL)
|
||||
return RS_ERR;
|
||||
// init uart
|
||||
|
||||
// RS_UART_Init();
|
||||
hRS->huart = huart;
|
||||
|
||||
// RS_TIM_Init();
|
||||
hRS->htim = htim;
|
||||
|
||||
if (hRS->sRS_RX_Size_Mode == NULL)
|
||||
return RS_ERR;
|
||||
|
||||
// check that buffer is defined
|
||||
if (hRS->pBufferPtr == NULL)
|
||||
{
|
||||
hRS->pBufferPtr = RS_Buffer; // if no - set default
|
||||
}
|
||||
else
|
||||
hRS->pBufferPtr = pRS_BufferPtr; // if yes - set by user
|
||||
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ReInitialize UART and RS receive.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param suart - указатель на структуру с настройками UART.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации.
|
||||
* @note Реинициализация UART и приема по RS.
|
||||
*/
|
||||
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart)
|
||||
{
|
||||
HAL_StatusTypeDef RS_RES;
|
||||
hRS->f.ReInit_UART = 0;
|
||||
|
||||
// // check is settings are valid
|
||||
// if(Check_UART_Init_Struct(suart) != HAL_OK)
|
||||
// return HAL_ERROR;
|
||||
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
|
||||
RS_UART_DeInit(huart);
|
||||
|
||||
RS_UART_Init();
|
||||
|
||||
|
||||
RS_Receive_IT(hRS, hRS->pMessagePtr);
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Abort RS/UART.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param AbortMode - выбор, что надо отменить.
|
||||
- ABORT_TX: Отмена передачи по ЮАРТ, с очищением флагов TX,
|
||||
- ABORT_RX: Отмена приема по ЮАРТ, с очищением флагов RX,
|
||||
- ABORT_RX_TX: Отмена приема и передачи по ЮАРТ,
|
||||
- ABORT_RS: Отмена приема-передачи RS, с очищением всей структуры.
|
||||
* @return RS_RES - статус о состоянии RS после аборта.
|
||||
* @note Отмена работы UART в целом или отмена приема/передачи RS.
|
||||
Также очищается хендл hRS.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode)
|
||||
{
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
hRS->htim->Instance->CNT = 0;
|
||||
__HAL_TIM_CLEAR_IT(hRS->htim, TIM_IT_UPDATE);
|
||||
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
|
||||
|
||||
if((AbortMode&ABORT_RS) == 0x00)
|
||||
{
|
||||
if((AbortMode&ABORT_RX) == ABORT_RX)
|
||||
{
|
||||
uart_res = HAL_UART_AbortReceive(hRS->huart); // abort receive
|
||||
RS_Reset_RX_Flags(hRS);
|
||||
}
|
||||
|
||||
if((AbortMode&ABORT_TX) == ABORT_TX)
|
||||
{
|
||||
uart_res = HAL_UART_AbortTransmit(hRS->huart); // abort transmit
|
||||
RS_Reset_TX_Flags(hRS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uart_res = HAL_UART_Abort(hRS->huart);
|
||||
RS_Clear_All(hRS);
|
||||
}
|
||||
hRS->RS_STATUS = RS_ABORTED;
|
||||
return RS_ABORTED;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
/**
|
||||
* @brief Handle for starting receive.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации приема или окончания общения.
|
||||
* @note Определяет начинать прием команды/ответа или нет.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
|
||||
switch(hRS->sRS_Mode)
|
||||
{
|
||||
case SLAVE_ALWAYS_WAIT: // in slave mode with permanent waiting
|
||||
RS_RES = RS_Receive_IT(hRS, RS_msg); break; // start receiving again
|
||||
case SLAVE_TIMEOUT_WAIT: // in slave mode with timeout waiting (start receiving cmd by request)
|
||||
RS_Set_Free(hRS); RS_RES = RS_OK; break; // end RS communication (set RS unbusy)
|
||||
}
|
||||
|
||||
if(RS_RES != RS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
/**
|
||||
* @brief Handle for starting transmit.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации передачи.
|
||||
* @note Определяет отвечать ли на команду или нет.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
|
||||
switch(hRS->sRS_Mode)
|
||||
{
|
||||
case SLAVE_ALWAYS_WAIT: // in slave mode always response
|
||||
case SLAVE_TIMEOUT_WAIT: // transmit response
|
||||
RS_RES = RS_Transmit_IT(hRS, RS_msg); break;
|
||||
}
|
||||
if(RS_RES != RS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART RX Callback: define behaviour after receiving parts of message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @return RS_RES - статус о состоянии RS после обработки приема.
|
||||
* @note Контролирует прием сообщения: определяет размер принимаемой посылки и обрабатывает его.
|
||||
*/
|
||||
RS_StatusTypeDef RS_UART_RxCpltCallback(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
// if we had received bytes before ByteCnt
|
||||
if((hRS->sRS_RX_Size_Mode == RS_RX_Size_NotConst) && (hRS->f.RX_Half == 0)) // if data size isnt constant and its first half, and
|
||||
{ // First receive part of message, then define size of rest of message, and start receive it
|
||||
hRS->f.RX_Half = 1;
|
||||
//---------------FIND DATA SIZE-----------------
|
||||
uint32_t NuRS_of_Rest_Bytes = 0xFFFF;
|
||||
RS_RES = RS_Define_Size_of_RX_Message(hRS, &NuRS_of_Rest_Bytes);
|
||||
|
||||
|
||||
// if we need to skip this message - restart receive
|
||||
if(RS_RES == RS_SKIP || NuRS_of_Rest_Bytes == 0xFFFF)
|
||||
{
|
||||
RS_Abort(hRS, ABORT_RX);
|
||||
RS_RES = RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
// if there is no bytes to receive
|
||||
if(NuRS_of_Rest_Bytes == 0)
|
||||
{
|
||||
hRS->f.RX_Half = 0;
|
||||
|
||||
//---------PROCESS DATA & ENDING RECEIVING--------
|
||||
RS_Set_RX_End(hRS);
|
||||
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
|
||||
|
||||
// parse received data
|
||||
RS_RES = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr); // parse message
|
||||
|
||||
// RESPONSE
|
||||
RS_RES = RS_Response(hRS, hRS->pMessagePtr);
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
|
||||
//-------------START UART RECEIVE---------------
|
||||
uart_res = HAL_UART_Receive_IT(hRS->huart, (hRS->pBufferPtr + RX_FIRST_PART_SIZE), NuRS_of_Rest_Bytes);
|
||||
|
||||
if(uart_res != HAL_OK)
|
||||
{// need uart status, so doesnt write abort to RS_RES
|
||||
RS_RES = RS_Abort(hRS, ABORT_RS);
|
||||
}
|
||||
else
|
||||
RS_RES = RS_OK;
|
||||
}
|
||||
else // if we had received whole message
|
||||
{
|
||||
hRS->f.RX_Half = 0;
|
||||
|
||||
//---------PROCESS DATA & ENDING RECEIVING--------
|
||||
RS_Set_RX_End(hRS);
|
||||
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
|
||||
|
||||
// parse received data
|
||||
RS_RES = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr); // parse message
|
||||
|
||||
// RESPONSE
|
||||
RS_RES = RS_Response(hRS, hRS->pMessagePtr);
|
||||
}
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UART TX Callback: define behaviour after transmiting message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @return RS_RES - статус о состоянии RS после обработки приема.
|
||||
* @note Определяет поведение RS после передачи сообщения.
|
||||
*/
|
||||
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = RS_OK;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
//--------------ENDING TRANSMITTING-------------
|
||||
RS_Set_TX_End(hRS);
|
||||
RS_EnableReceive();
|
||||
// for(int i = 0; i < hRS->sRS_Timeout; i++);
|
||||
|
||||
//-----------START RECEIVING or END RS----------
|
||||
RS_RES = RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handler for UART.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @note Обрабатывает ошибки если есть и вызывает RS Коллбеки.
|
||||
* Добавить вызов этой функции в UARTx_IRQHandler() после HAL_UART_IRQHandler().
|
||||
*/
|
||||
void RS_UART_Handler(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
//-------------CALL RS CALLBACKS------------
|
||||
/* IF NO ERROR OCCURS */
|
||||
if(hRS->huart->ErrorCode == 0)
|
||||
{
|
||||
hRS->htim->Instance->CNT = 0; // reset cnt;
|
||||
/* Start timeout */
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
if((hRS->huart->RxXferCount+1 == hRS->huart->RxXferSize) && RS_Is_RX_Busy(hRS)) // if first byte is received and receive is active
|
||||
{
|
||||
hRS->htim->Instance->ARR = hRS->sRS_Timeout; // reset cnt;
|
||||
HAL_TIM_Base_Start_IT(hRS->htim);
|
||||
RS_Set_RX_Active_Flags(hRS);
|
||||
}
|
||||
|
||||
/* RX Callback */
|
||||
if (( hRS->huart->RxXferCount == 0U) && RS_Is_RX_Busy(hRS) && // if all bytes are received and receive is active
|
||||
hRS->huart->RxState != HAL_UART_STATE_BUSY_RX) // also check that receive "REALLY" isnt busy
|
||||
RS_UART_RxCpltCallback(hRS);
|
||||
|
||||
/* TX Callback */
|
||||
if (( hRS->huart->TxXferCount == 0U) && RS_Is_TX_Busy(hRS) && // if all bytes are transmited and transmit is active
|
||||
hRS->huart->gState != HAL_UART_STATE_BUSY_TX) // also check that receive "REALLY" isnt busy
|
||||
RS_UART_TxCpltCallback(hRS);
|
||||
}
|
||||
//----------------ERRORS HANDLER----------------
|
||||
else
|
||||
{
|
||||
if(hRS->f.RX_Busy)
|
||||
{
|
||||
|
||||
/* de-init uart transfer */
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
// later, maybe, will be added specific handlers for err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handler for TIM.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @note Попадание сюда = таймаут и перезапуск RS приема
|
||||
* Добавить вызов этой функции в TIMx_IRQHandler() после HAL_TIM_IRQHandler().
|
||||
*/
|
||||
void RS_TIM_Handler(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim);
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
|
||||
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
}
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//--------------WEAK PROTOTYPES FOR PROCESSING MESSAGE---------------
|
||||
/**
|
||||
* @brief Respond accord to received message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о результате ответа на комманду.
|
||||
* @note Обработка принятой комманды и ответ на неё.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Collect message in buffer to transmit it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения буфера.
|
||||
* @note Заполнение буффера UART из структуры сообщения.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse message from buffer to process it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения структуры.
|
||||
* @note Заполнение структуры сообщения из буффера UART.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Define size of RX Message that need to be received.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param rx_data_size - указатель на переменную для записи кол-ва байт для принятия.
|
||||
* @return RS_RES - статус о корректности рассчета кол-ва байт для принятия.
|
||||
* @note Определение сколько байтов надо принять по протоколу.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hRS, uint32_t *rx_data_size)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
//--------------WEAK PROTOTYPES FOR PROCESSING MESSAGE---------------
|
||||
//-------------------------------------------------------------------
|
||||
257
john103C6T6/Modbus/rs_message.h
Normal file
257
john103C6T6/Modbus/rs_message.h
Normal file
@ -0,0 +1,257 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file rs_message.h
|
||||
* @brief Заголовочный файл для модуля реализации протоколов по RS/UART.
|
||||
**************************************************************************
|
||||
* @defgroup RS_TOOLS
|
||||
* @brief Всякое для работы по UART/RS
|
||||
**************************************************************************
|
||||
@details
|
||||
**************************************************************************
|
||||
Для настройки RS/UART под нужный протокол, необходимо:
|
||||
- Определить структуру сообщения RS_MsgTypeDef и
|
||||
дефайны RX_FIRST_PART_SIZE и MSG_SIZE_MAX.
|
||||
- Подключить этот файл в раздел rs_message.h.
|
||||
- Определить функции для обработки сообщения: RS_Parse_Message(),
|
||||
RS_Collect_Message(), RS_Response(), RS_Define_Size_of_RX_Message()
|
||||
- Добавить UART/TIM Handler в Хендлер используемых UART/TIM.
|
||||
|
||||
Так же данный модуль использует счетчики
|
||||
**************************************************************************
|
||||
@verbatim
|
||||
Визуальное описание. Форматирование сохраняется как в коде.
|
||||
@endverbatim
|
||||
*************************************************************************/
|
||||
#ifndef __RS_LIB_H_
|
||||
#define __RS_LIB_H_
|
||||
|
||||
#include "modbus.h"
|
||||
|
||||
#include "crc_algs.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////---DEFINES---////////////////////////////
|
||||
/* Check that all defines required by RS are defined */
|
||||
#ifndef MSG_SIZE_MAX
|
||||
#error Define MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
|
||||
#endif
|
||||
|
||||
#ifndef RX_FIRST_PART_SIZE
|
||||
#error Define RX_FIRST_PART_SIZE (Size of first part of message). This is necessary to receive the first part of the message, from which determine the size of the remaining part of the message.
|
||||
#endif
|
||||
|
||||
|
||||
/* Clear message-uart buffer */
|
||||
#define RS_Clear_Buff(_buff_) for(int i=0; i<MSG_SIZE_MAX;i++) _buff_[i] = NULL
|
||||
|
||||
/* Set/Reset flags */
|
||||
#define RS_Set_Free(_hRS_) _hRS_->f.RS_Busy = 0
|
||||
#define RS_Set_Busy(_hRS_) _hRS_->f.RS_Busy = 1
|
||||
|
||||
#define RS_Set_RX_Flags(_hRS_) _hRS_->f.RX_Busy = 1; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
|
||||
#define RS_Set_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 1
|
||||
|
||||
|
||||
#define RS_Set_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 1; _hRS_->f.TX_Done = 0
|
||||
|
||||
#define RS_Reset_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 0
|
||||
#define RS_Reset_RX_Flags(_hRS_) RS_Reset_RX_Active_Flags(_hRS_); _hRS_->f.RX_Busy = 0; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
|
||||
#define RS_Reset_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 0; _hRS_->f.TX_Done = 0
|
||||
|
||||
#define RS_Set_RX_End_Flag(_hRS_) _hRS_->f.RX_Done = 1;
|
||||
#define RS_Set_TX_End_Flag(_hRS_) _hRS_->f.TX_Done = 1
|
||||
|
||||
#define RS_Set_RX_End(_hRS_) RS_Reset_RX_Flags(_hRS_); RS_Set_RX_End_Flag(_hRS_)
|
||||
#define RS_Set_TX_End(_hRS_) RS_Reset_TX_Flags(_hRS_); RS_Set_TX_End_Flag(_hRS_)
|
||||
|
||||
/* Clear all RS stuff */
|
||||
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->pBufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_);
|
||||
|
||||
//#define MB_Is_RX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_RX)
|
||||
//#define MB_Is_TX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_TX)
|
||||
#define RS_Is_RX_Busy(_hRS_) (_hRS_->f.RX_Busy == 1)
|
||||
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
|
||||
|
||||
|
||||
#ifndef RS_EnableReceive
|
||||
#define RS_EnableReceive()
|
||||
#endif
|
||||
#ifndef RS_EnableTransmit
|
||||
#define RS_EnableTransmit()
|
||||
#endif
|
||||
////////////////////////////---DEFINES---////////////////////////////
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
|
||||
//------------------ENUMERATIONS--------------------
|
||||
/** @brief Enums for respond CMD about RS status */
|
||||
typedef enum // RS_StatusTypeDef
|
||||
{
|
||||
/* IN-CODE STATUS (start from 0x01, and goes up)*/
|
||||
/*0x01*/ RS_OK = 0x01,
|
||||
/*0x02*/ RS_ERR,
|
||||
/*0x03*/ RS_ABORTED,
|
||||
/*0x04*/ RS_BUSY,
|
||||
/*0x05*/ RS_SKIP,
|
||||
|
||||
/*0x06*/ RS_COLLECT_MSG_ERR,
|
||||
/*0x07*/ RS_PARSE_MSG_ERR,
|
||||
|
||||
// reserved values
|
||||
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)
|
||||
}RS_StatusTypeDef;
|
||||
|
||||
|
||||
/** @brief Enums for RS Modes */
|
||||
typedef enum // RS_ModeTypeDef
|
||||
{
|
||||
SLAVE_ALWAYS_WAIT = 0x01, ///< Slave mode with infinity waiting
|
||||
SLAVE_TIMEOUT_WAIT = 0x02, ///< Slave mode with waiting with timeout
|
||||
// MASTER = 0x03, ///< Master mode
|
||||
}RS_ModeTypeDef;
|
||||
|
||||
/** @brief Enums for RS UART Modes */
|
||||
typedef enum // RS_ITModeTypeDef
|
||||
{
|
||||
BLCK_MODE = 0x00, ///< Blocking mode
|
||||
IT_MODE = 0x01, ///< Interrupt mode
|
||||
}RS_ITModeTypeDef;
|
||||
|
||||
/** @brief Enums for Abort modes */
|
||||
typedef enum // RS_AbortTypeDef
|
||||
{
|
||||
ABORT_TX = 0x01, ///< Abort transmit
|
||||
ABORT_RX = 0x02, ///< Abort receive
|
||||
ABORT_RX_TX = 0x03, ///< Abort receive and transmit
|
||||
ABORT_RS = 0x04, ///< Abort uart and reset RS structure
|
||||
}RS_AbortTypeDef;
|
||||
|
||||
/** @brief Enums for RX Size modes */
|
||||
typedef enum // RS_RXSizeTypeDef
|
||||
{
|
||||
RS_RX_Size_Const = 0x01, ///< size of receiving message is constant
|
||||
RS_RX_Size_NotConst = 0x02, ///< size of receiving message isnt constant
|
||||
}RS_RXSizeTypeDef;
|
||||
|
||||
|
||||
//-----------STRUCTURE FOR HANDLE RS------------
|
||||
/** @brief Struct for flags RS */
|
||||
typedef struct
|
||||
{
|
||||
unsigned RX_Half:1; ///< flag: 0 - receiving msg before ByteCnt, 0 - receiving msg after ByteCnt
|
||||
|
||||
unsigned RS_Busy:1; ///< flag: 1 - RS is busy, 0 - RS isnt busy
|
||||
unsigned RX_Ongoing:1; ///< flag: 1 - receiving data right now, 0 - waiting for receiving data
|
||||
|
||||
unsigned RX_Busy:1; ///< flag: 1 - receiving is active, 0 - receiving isnt active
|
||||
unsigned TX_Busy:1; ///< flag: 1 - transmiting is active, 0 - transmiting isnt active
|
||||
|
||||
unsigned RX_Done:1; ///< flag: 1 - receiving is done, 0 - receiving isnt done
|
||||
unsigned TX_Done:1; ///< flag: 1 - transmiting is done, 0 - transmiting isnt done
|
||||
|
||||
// setted by user
|
||||
unsigned MessageHandled:1; ///< flag: 1 - RS command is handled, 0 - RS command isnt handled yet
|
||||
unsigned EchoResponse:1; ///< flag: 1 - response with received msg, 0 - response with own msg
|
||||
unsigned DeferredResponse:1; ///< flag: 1 - response not in interrupt, 0 - response in interrupt
|
||||
unsigned ReInit_UART:1; ///< flag: 1 - need to reinitialize uart, 0 - nothing
|
||||
}RS_FlagsTypeDef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle for RS communication.
|
||||
* @note Prefixes: h - handle, s - settings, f - flag
|
||||
*/
|
||||
typedef struct // RS_HandleTypeDef
|
||||
{
|
||||
/* MESSAGE */
|
||||
uint8_t ID; ///< ID of RS "channel"
|
||||
RS_MsgTypeDef *pMessagePtr; ///< pointer to message struct
|
||||
uint8_t *pBufferPtr; ///< pointer to message buffer
|
||||
uint32_t RS_Message_Size; ///< size of whole message, not only data
|
||||
|
||||
/* HANDLERS and SETTINGS */
|
||||
UART_HandleTypeDef *huart; ///< handler for used uart
|
||||
TIM_HandleTypeDef *htim; ///< handler for used tim
|
||||
RS_ModeTypeDef sRS_Mode; ///< setting: slave or master @ref RS_ModeTypeDef
|
||||
RS_ITModeTypeDef sRS_IT_Mode; ///< setting: 1 - IT mode, 0 - Blocking mode
|
||||
uint16_t sRS_Timeout; ///< setting: timeout in ms
|
||||
RS_RXSizeTypeDef sRS_RX_Size_Mode; ///< setting: 1 - not const, 0 - const
|
||||
|
||||
/* FLAGS */
|
||||
RS_FlagsTypeDef f; ///< These flags for controling receive/transmit
|
||||
|
||||
/* RS STATUS */
|
||||
RS_StatusTypeDef RS_STATUS; ///< RS status
|
||||
}RS_HandleTypeDef;
|
||||
extern RS_HandleTypeDef hmodbus1;
|
||||
|
||||
|
||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////---FUNCTIONS---///////////////////////////
|
||||
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
|
||||
/*--------------------Defined by users purposes--------------------*/
|
||||
/* Respond accord to received message */
|
||||
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
|
||||
/* Collect message in buffer to transmit it */
|
||||
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
|
||||
|
||||
/* Parse message from buffer to process it */
|
||||
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
|
||||
|
||||
/* Define size of RX Message that need to be received */
|
||||
RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hRS, uint32_t *rx_data_size);
|
||||
|
||||
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
/*-----------------Should be called from main code-----------------*/
|
||||
/* Start receive IT */
|
||||
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
|
||||
/* Start transmit IT */
|
||||
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
|
||||
/* Initialize UART and handle RS stucture */
|
||||
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr);
|
||||
|
||||
/* ReInitialize UART and RS receive */
|
||||
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *suart);
|
||||
|
||||
/* Abort RS/UART */
|
||||
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
/* Handle for starting receive */
|
||||
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
/* Handle for starting transmit */
|
||||
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
/* UART RX Callback: define behaviour after receiving parts of message */
|
||||
RS_StatusTypeDef RS_UART_RxCpltCallback(RS_HandleTypeDef *hRS);
|
||||
/* UART TX Callback: define behaviour after transmiting message */
|
||||
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS);
|
||||
/* Handler for UART */
|
||||
void RS_UART_Handler(RS_HandleTypeDef *hRS);
|
||||
/* Handler for TIM */
|
||||
void RS_TIM_Handler(RS_HandleTypeDef *hRS);
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
///////////////////////////---FUNCTIONS---///////////////////////////
|
||||
|
||||
|
||||
#ifndef printf_rs_err
|
||||
#define printf_rs_err(...)
|
||||
#endif
|
||||
|
||||
#ifndef printf_rs
|
||||
#define printf_rs(...)
|
||||
#endif
|
||||
#endif // __RS_LIB_H_
|
||||
@ -33,53 +33,55 @@ Mcu.IPNb=11
|
||||
Mcu.Name=STM32F103C(4-6)Tx
|
||||
Mcu.Package=LQFP48
|
||||
Mcu.Pin0=PC13-TAMPER-RTC
|
||||
Mcu.Pin1=PD0-OSC_IN
|
||||
Mcu.Pin10=PA7
|
||||
Mcu.Pin11=PB0
|
||||
Mcu.Pin12=PB1
|
||||
Mcu.Pin13=PB2
|
||||
Mcu.Pin14=PB10
|
||||
Mcu.Pin15=PB11
|
||||
Mcu.Pin16=PB12
|
||||
Mcu.Pin17=PB13
|
||||
Mcu.Pin18=PB14
|
||||
Mcu.Pin19=PB15
|
||||
Mcu.Pin2=PD1-OSC_OUT
|
||||
Mcu.Pin20=PA8
|
||||
Mcu.Pin21=PA9
|
||||
Mcu.Pin22=PA10
|
||||
Mcu.Pin23=PA11
|
||||
Mcu.Pin24=PA12
|
||||
Mcu.Pin25=PA13
|
||||
Mcu.Pin26=PA14
|
||||
Mcu.Pin27=PA15
|
||||
Mcu.Pin28=PB3
|
||||
Mcu.Pin29=PB4
|
||||
Mcu.Pin3=PA0-WKUP
|
||||
Mcu.Pin30=PB5
|
||||
Mcu.Pin31=PB6
|
||||
Mcu.Pin32=PB7
|
||||
Mcu.Pin33=PB8
|
||||
Mcu.Pin34=PB9
|
||||
Mcu.Pin35=VP_ADC1_TempSens_Input
|
||||
Mcu.Pin36=VP_ADC1_Vref_Input
|
||||
Mcu.Pin37=VP_RTC_VS_RTC_Activate
|
||||
Mcu.Pin38=VP_RTC_VS_RTC_Calendar
|
||||
Mcu.Pin39=VP_SYS_VS_tim3
|
||||
Mcu.Pin4=PA1
|
||||
Mcu.Pin40=VP_TIM1_VS_ClockSourceINT
|
||||
Mcu.Pin41=VP_TIM2_VS_ClockSourceINT
|
||||
Mcu.Pin5=PA2
|
||||
Mcu.Pin6=PA3
|
||||
Mcu.Pin7=PA4
|
||||
Mcu.Pin8=PA5
|
||||
Mcu.Pin9=PA6
|
||||
Mcu.PinsNb=42
|
||||
Mcu.Pin1=PC14-OSC32_IN
|
||||
Mcu.Pin10=PA5
|
||||
Mcu.Pin11=PA6
|
||||
Mcu.Pin12=PA7
|
||||
Mcu.Pin13=PB0
|
||||
Mcu.Pin14=PB1
|
||||
Mcu.Pin15=PB2
|
||||
Mcu.Pin16=PB10
|
||||
Mcu.Pin17=PB11
|
||||
Mcu.Pin18=PB12
|
||||
Mcu.Pin19=PB13
|
||||
Mcu.Pin2=PC15-OSC32_OUT
|
||||
Mcu.Pin20=PB14
|
||||
Mcu.Pin21=PB15
|
||||
Mcu.Pin22=PA8
|
||||
Mcu.Pin23=PA9
|
||||
Mcu.Pin24=PA10
|
||||
Mcu.Pin25=PA11
|
||||
Mcu.Pin26=PA12
|
||||
Mcu.Pin27=PA13
|
||||
Mcu.Pin28=PA14
|
||||
Mcu.Pin29=PA15
|
||||
Mcu.Pin3=PD0-OSC_IN
|
||||
Mcu.Pin30=PB3
|
||||
Mcu.Pin31=PB4
|
||||
Mcu.Pin32=PB5
|
||||
Mcu.Pin33=PB6
|
||||
Mcu.Pin34=PB7
|
||||
Mcu.Pin35=PB8
|
||||
Mcu.Pin36=PB9
|
||||
Mcu.Pin37=VP_ADC1_TempSens_Input
|
||||
Mcu.Pin38=VP_ADC1_Vref_Input
|
||||
Mcu.Pin39=VP_RTC_VS_RTC_Activate
|
||||
Mcu.Pin4=PD1-OSC_OUT
|
||||
Mcu.Pin40=VP_RTC_VS_RTC_Calendar
|
||||
Mcu.Pin41=VP_SYS_VS_tim3
|
||||
Mcu.Pin42=VP_TIM1_VS_ClockSourceINT
|
||||
Mcu.Pin43=VP_TIM2_VS_ClockSourceINT
|
||||
Mcu.Pin5=PA0-WKUP
|
||||
Mcu.Pin6=PA1
|
||||
Mcu.Pin7=PA2
|
||||
Mcu.Pin8=PA3
|
||||
Mcu.Pin9=PA4
|
||||
Mcu.PinsNb=44
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F103C6Tx
|
||||
MxCube.Version=6.15.0
|
||||
MxDb.Version=DB.6.0.150
|
||||
MxCube.Version=6.12.0
|
||||
MxDb.Version=DB.6.0.120
|
||||
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.ForceEnableDMAVector=true
|
||||
@ -169,8 +171,12 @@ PB8.Mode=I2C
|
||||
PB8.Signal=I2C1_SCL
|
||||
PB9.Mode=I2C
|
||||
PB9.Signal=I2C1_SDA
|
||||
PC13-TAMPER-RTC.Locked=true
|
||||
PC13-TAMPER-RTC.Signal=GPIO_Output
|
||||
PC13-TAMPER-RTC.Mode=RTC OUT
|
||||
PC13-TAMPER-RTC.Signal=RTC_OUT
|
||||
PC14-OSC32_IN.Mode=LSE-External-Oscillator
|
||||
PC14-OSC32_IN.Signal=RCC_OSC32_IN
|
||||
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
|
||||
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
|
||||
PD0-OSC_IN.Mode=HSE-External-Oscillator
|
||||
PD0-OSC_IN.Signal=RCC_OSC_IN
|
||||
PD1-OSC_OUT.Mode=HSE-External-Oscillator
|
||||
@ -178,7 +184,6 @@ PD1-OSC_OUT.Signal=RCC_OSC_OUT
|
||||
PinOutPanel.RotationAngle=0
|
||||
ProjectManager.AskForMigrate=true
|
||||
ProjectManager.BackupPrevious=false
|
||||
ProjectManager.CompilerLinker=GCC
|
||||
ProjectManager.CompilerOptimize=6
|
||||
ProjectManager.ComputerToolchain=false
|
||||
ProjectManager.CoupleFile=true
|
||||
|
||||
Binary file not shown.
1
labview_john/labview_proj
Submodule
1
labview_john/labview_proj
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit fcba827e91c02c153b61966611c08c5265bf62be
|
||||
@ -1 +1 @@
|
||||
Subproject commit 640e360565bf87d9a26dc4ec240150d191716b57
|
||||
Subproject commit fcba827e91c02c153b61966611c08c5265bf62be
|
||||
Loading…
Reference in New Issue
Block a user