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