Modbus主机模板

#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;
        }
    }
}

 

posted on 2023-10-17 14:51  棕色的北极熊  阅读(42)  评论(0)    收藏  举报