#ifndef MODBUS_MASTER_H
#define MODBUS_MASTER_H
#include "main.h"
#ifdef MODBUS_MASTER_C
#include "stm32f10x_usart.h"
#include "mode.h"
#include "device.h"
#include "fan.h"
#include "crc.h"
#define PriorityMaxSize 3
#define MissionMaxSize 10
#define Bps 9600
#define RecSize 100
#define SignalDelay 10
#define BroadcastID 0x00
#define CounterMax 20000
#define WaitDelay 80
#define ErrorMax 10
#define MissionNone 0x00
#define MissionReady 0x01
#define MissionStart 0x02
#define NoneCmd 0x00
#define Read3Cmd 0x01
#define Read4Cmd 0x02
#define WriteCmd 0x03
typedef struct{
short* Pointer;
int Last;
uchar ReadOrWrite;
uchar ID;
ushort Addr;
uchar* ErrorFlag;
ushort ErrorCounter;
ushort LastTrigger;
} MODBUS_MasterCommandType;
void MODBUS_MASTER_Deal0x03(void);
void MODBUS_MASTER_Deal0x04(void);
void MODBUS_MASTER_Deal0x06(void);
void MODBUS_MASTER_Deal0x10(void);
void MODBUS_MASTER_DealRead3(void);
void MODBUS_MASTER_DealRead4(void);
void MODBUS_MASTER_DealWrite(void);
void MODBUS_MASTER_InsertMission(MODBUS_MasterCommandType mission, uchar priority);
void MODBUS_MASTER_GetNewMission(void);
#endif
extern uchar MODBUS_MASTER_ActionFlag;
void MODBUS_MASTER_Init (void);
void MODBUS_MASTER_Action(void);
#endif
#define MODBUS_MASTER_C
#include "modbus_master.h"
MODBUS_MasterCommandType MODBUS_MASTER_MissionList[PriorityMaxSize][MissionMaxSize];
MODBUS_MasterCommandType* MODBUS_MASTER_CurrentMission;
uchar MODBUS_MASTER_MissionSize [PriorityMaxSize];
uchar MODBUS_MASTER_MissionIndex[PriorityMaxSize];
ushort MODBUS_MASTER_MissionDelay[PriorityMaxSize];
ushort MODBUS_MASTER_MissionCounter;
uchar MODBUS_MASTER_ActionFlag;
uchar MODBUS_MASTER_Read3Array[6] = {0x00, 0x03, 0x00, 0x00, 0x00, 0x01};
uchar MODBUS_MASTER_Read4Array[6] = {0x00, 0x04, 0x00, 0x00, 0x00, 0x01};
uchar MODBUS_MASTER_WriteArray[6] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00};
uchar MODBUS_MASTER_MissionStatus;
uchar MODBUS_MASTER_RecByte[RecSize];
uchar MODBUS_MASTER_Position;
ushort MODBUS_MASTER_Counter;
uchar testErrorFlag;
void MODBUS_MASTER_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure ;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure ;
//----------DATA Init----------
MODBUS_MASTER_Position = 0;
MODBUS_MASTER_Counter = 0;
for(uchar i = 0; i < PriorityMaxSize; i ++)
{
MODBUS_MASTER_MissionSize [i] = 0;
MODBUS_MASTER_MissionIndex[i] = 0;
}
MODBUS_MASTER_MissionDelay[0] = 100;
MODBUS_MASTER_MissionDelay[1] = 200;
MODBUS_MASTER_MissionDelay[2] = 1000;
MODBUS_MASTER_MissionStatus = MissionNone;
//Mission
MODBUS_MasterCommandType cmd;
cmd.Pointer =&MODE_Current_H2O_Density_Source;
cmd.ReadOrWrite = Read4Cmd;
cmd.ID = 0x02;
cmd.Addr = 0x0001;
cmd.ErrorFlag =&DEVICE_H2O_ErrorFlag;
MODBUS_MASTER_InsertMission(cmd, 2);
cmd.Pointer =&FAN_SpeedCmd;
cmd.Last = FAN_SpeedCmd;
cmd.ReadOrWrite = WriteCmd;
cmd.ID = 0x05;
cmd.Addr = 0x2001;
cmd.ErrorFlag =&DEVICE_FAN_ErrorFlag;
MODBUS_MASTER_InsertMission(cmd, 2);
//----------GPIO Init----------
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//RS485
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//----------USART Init----------
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
USART_InitStructure.USART_BaudRate = Bps;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART4, &USART_InitStructure);
//----------NVIC Init----------
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//----------ENABLE----------
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
USART_Cmd(UART4, ENABLE);
}
uchar MODBUS_MASTER_CrcCheck(void)
{
uchar end = MODBUS_MASTER_Position - 2;
MyCRC_TypeDef crc;
CRC_Clear(&crc);
for(uchar i = 0; i < end; i ++)
{
CRC_Check(&crc, MODBUS_MASTER_RecByte[i]);
}
if(MODBUS_MASTER_RecByte[end] == crc.RegL && MODBUS_MASTER_RecByte[end + 1] == crc.RegH)
{
return 0;
}
return 1;
}
void MODBUS_MASTER_SendData(uchar Data)
{
while(USART_GetFlagStatus(UART4, USART_FLAG_TC) != SET);
USART_SendData(UART4, Data);
}
void MODBUS_MASTER_Deal0x03(void)
{
short rtn = MODBUS_MASTER_RecByte[3] << 8 | MODBUS_MASTER_RecByte[4];
(*MODBUS_MASTER_CurrentMission).Last = *(*MODBUS_MASTER_CurrentMission).Pointer = rtn;
(*MODBUS_MASTER_CurrentMission).ErrorCounter = 0;
*(*MODBUS_MASTER_CurrentMission).ErrorFlag = 0;
MODBUS_MASTER_MissionStatus = MissionNone;
}
void MODBUS_MASTER_Deal0x04(void)
{
short rtn = MODBUS_MASTER_RecByte[3] << 8 | MODBUS_MASTER_RecByte[4];
(*MODBUS_MASTER_CurrentMission).Last = *(*MODBUS_MASTER_CurrentMission).Pointer = rtn;
(*MODBUS_MASTER_CurrentMission).ErrorCounter = 0;
*(*MODBUS_MASTER_CurrentMission).ErrorFlag = 0;
MODBUS_MASTER_MissionStatus = MissionNone;
}
void MODBUS_MASTER_Deal0x06(void)
{
(*MODBUS_MASTER_CurrentMission).Last = *(*MODBUS_MASTER_CurrentMission).Pointer;
(*MODBUS_MASTER_CurrentMission).ErrorCounter = 0;
*(*MODBUS_MASTER_CurrentMission).ErrorFlag = 0;
MODBUS_MASTER_MissionStatus = MissionNone;
}
void MODBUS_MASTER_Deal0x10(void)
{
(*MODBUS_MASTER_CurrentMission).Last = *(*MODBUS_MASTER_CurrentMission).Pointer;
(*MODBUS_MASTER_CurrentMission).ErrorCounter = 0;
*(*MODBUS_MASTER_CurrentMission).ErrorFlag = 0;
MODBUS_MASTER_MissionStatus = MissionNone;
}
void MODBUS_MASTER_Deal0x83(void)
{
(*MODBUS_MASTER_CurrentMission).ErrorCounter = ErrorMax;
*(*MODBUS_MASTER_CurrentMission).ErrorFlag = 1;
MODBUS_MASTER_MissionStatus = MissionNone;
}
void MODBUS_MASTER_DealRead3(void)
{
MODBUS_MASTER_Read3Array[0] = (*MODBUS_MASTER_CurrentMission).ID;
MODBUS_MASTER_Read3Array[2] = (*MODBUS_MASTER_CurrentMission).Addr >> 8;
MODBUS_MASTER_Read3Array[3] = (*MODBUS_MASTER_CurrentMission).Addr;
MyCRC_TypeDef crc;
CRC_Clear(&crc);
for(uchar i = 0; i < 6; i ++)
{
MODBUS_MASTER_SendData(MODBUS_MASTER_Read3Array[i]);
CRC_Check(&crc, MODBUS_MASTER_Read3Array[i]);
}
MODBUS_MASTER_SendData(crc.RegL);
MODBUS_MASTER_SendData(crc.RegH);
MODBUS_MASTER_MissionStatus = MissionStart;
}
void MODBUS_MASTER_DealRead4(void)
{
MODBUS_MASTER_Read4Array[0] = (*MODBUS_MASTER_CurrentMission).ID;
MODBUS_MASTER_Read4Array[2] = (*MODBUS_MASTER_CurrentMission).Addr >> 8;
MODBUS_MASTER_Read4Array[3] = (*MODBUS_MASTER_CurrentMission).Addr;
MyCRC_TypeDef crc;
CRC_Clear(&crc);
for(uchar i = 0; i < 6; i ++)
{
MODBUS_MASTER_SendData(MODBUS_MASTER_Read4Array[i]);
CRC_Check(&crc, MODBUS_MASTER_Read4Array[i]);
}
MODBUS_MASTER_SendData(crc.RegL);
MODBUS_MASTER_SendData(crc.RegH);
MODBUS_MASTER_MissionStatus = MissionStart;
}
void MODBUS_MASTER_DealWrite(void)
{
if((*MODBUS_MASTER_CurrentMission).Last != *(*MODBUS_MASTER_CurrentMission).Pointer)
{
MODBUS_MASTER_WriteArray[0] = (*MODBUS_MASTER_CurrentMission).ID;
MODBUS_MASTER_WriteArray[2] = (*MODBUS_MASTER_CurrentMission).Addr >> 8;
MODBUS_MASTER_WriteArray[3] = (*MODBUS_MASTER_CurrentMission).Addr;
MODBUS_MASTER_WriteArray[4] = *(*MODBUS_MASTER_CurrentMission).Pointer >> 8;
MODBUS_MASTER_WriteArray[5] = *(*MODBUS_MASTER_CurrentMission).Pointer;
MyCRC_TypeDef crc;
CRC_Clear(&crc);
for(uchar i = 0; i < 6; i ++)
{
MODBUS_MASTER_SendData(MODBUS_MASTER_WriteArray[i]);
CRC_Check(&crc, MODBUS_MASTER_WriteArray[i]);
}
MODBUS_MASTER_SendData(crc.RegL);
MODBUS_MASTER_SendData(crc.RegH);
MODBUS_MASTER_MissionStatus = MissionStart;
}
else
{
MODBUS_MASTER_MissionStatus = MissionNone;
}
}
void MODBUS_MASTER_InsertMission(MODBUS_MasterCommandType mission, uchar priority)
{
MODBUS_MASTER_MissionList[priority][MODBUS_MASTER_MissionSize[priority]] = mission;
MODBUS_MASTER_MissionSize[priority] ++;
}
void MODBUS_MASTER_GetNewMission(void)
{
for(uchar i = 0; i < PriorityMaxSize; i ++)
{
if(MODBUS_MASTER_MissionSize[i])
{
ushort lastTrigger = MODBUS_MASTER_MissionList[i][MODBUS_MASTER_MissionIndex[i]].LastTrigger;
if((MODBUS_MASTER_MissionCounter + CounterMax - lastTrigger) % CounterMax >= MODBUS_MASTER_MissionDelay[i])
{
MODBUS_MASTER_CurrentMission = &MODBUS_MASTER_MissionList[i][MODBUS_MASTER_MissionIndex[i]];
MODBUS_MASTER_MissionStatus = MissionReady;
MODBUS_MASTER_MissionIndex[i] ++;
MODBUS_MASTER_MissionIndex[i] %= MODBUS_MASTER_MissionSize[i];
(*MODBUS_MASTER_CurrentMission).LastTrigger = MODBUS_MASTER_MissionCounter;
break;
}
}
}
}
void MODBUS_MASTER_Action(void)
{
if(!MODBUS_MASTER_ActionFlag)
{
return;
}
MODBUS_MASTER_ActionFlag = 0;
MODBUS_MASTER_Counter ++;
MODBUS_MASTER_Counter = Min_ushort(MODBUS_MASTER_Counter, CounterMax);
MODBUS_MASTER_MissionCounter ++;
MODBUS_MASTER_MissionCounter %= CounterMax;
if(MODBUS_MASTER_Position > 6)
{
if(!MODBUS_MASTER_CrcCheck())
{
switch(MODBUS_MASTER_RecByte[1])
{
case 0x03:
{
MODBUS_MASTER_Deal0x03();
}break;
case 0x04:
{
MODBUS_MASTER_Deal0x04();
}break;
case 0x06:
{
MODBUS_MASTER_Deal0x06();
}break;
case 0x10:
{
MODBUS_MASTER_Deal0x10();
}break;
}
MODBUS_MASTER_Position = 0;
}
}
switch(MODBUS_MASTER_MissionStatus)
{
case MissionNone:
{
MODBUS_MASTER_GetNewMission();
}break;
case MissionStart:
{
ushort lastTrigger = (*MODBUS_MASTER_CurrentMission).LastTrigger;
if((MODBUS_MASTER_MissionCounter + CounterMax - lastTrigger) % CounterMax > WaitDelay)
{
(*MODBUS_MASTER_CurrentMission).ErrorCounter ++;
if((*MODBUS_MASTER_CurrentMission).ErrorCounter >= ErrorMax)
{
(*MODBUS_MASTER_CurrentMission).ErrorCounter = ErrorMax;
*(*MODBUS_MASTER_CurrentMission).ErrorFlag = 1;
}
MODBUS_MASTER_GetNewMission();
}
}break;
case MissionReady:
{
switch((*MODBUS_MASTER_CurrentMission).ReadOrWrite)
{
case NoneCmd:
{
}break;
case Read3Cmd:
{
MODBUS_MASTER_DealRead3();
}break;
case Read4Cmd:
{
MODBUS_MASTER_DealRead4();
}break;
case WriteCmd:
{
MODBUS_MASTER_DealWrite();
}break;
}
}break;
}
}
void UART4_IRQHandler(void)
{
if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
{
uchar rec = USART_ReceiveData(UART4);
USART_ClearFlag(UART4, USART_IT_RXNE);
if(MODBUS_MASTER_Counter > SignalDelay)
{
MODBUS_MASTER_Position = 0;
}
MODBUS_MASTER_Counter = 0;
MODBUS_MASTER_RecByte[MODBUS_MASTER_Position ++] = rec;
if(MODBUS_MASTER_Position >= RecSize)
{
MODBUS_MASTER_Position = 0;
}
}
}