#ifndef MODBUS_MASTER_H #define MODBUS_MASTER_H #include "main.h" #ifdef MODBUS_MASTER_C #include "stm32f10x_usart.h" #include "crc.h" #define PrioritySize 3 #define MissionSize 10 #define Bps 115200 #define RecSize 100 #define SignalDelay 50 #define BroadcastID 0x00 #define CounterMax 20000 #define WaitDelay 200 #define ErrorMax 3 #define MissionNone 0x00 #define MissionReady 0x01 #define MissionStart 0x02 #define NoneCmd 0x00 #define ReadCmd 0x01 #define WriteCmd 0x02 typedef struct{ int* Pointer; int Last; uchar ReadOrWrite; uchar ID; ushort Addr; uchar Size; uchar Error; ushort Counter; } MODBUS_MasterCommandType; void MODBUS_MASTER_Deal0x03(void); void MODBUS_MASTER_Deal0x06(void); void MODBUS_MASTER_Deal0x10(void); void MODBUS_MASTER_DealRead (void); void MODBUS_MASTER_DealWrite(void); void MODBUS_MASTER_InsertMission(MODBUS_MasterCommandType mission, uchar priority); void MODBUS_MASTER_RemoveMission(MODBUS_MasterCommandType mission); void MODBUS_MASTER_GetNewMission(void); /*----------Queue----------*/ #define MODBUS_MASTER_QUEUE_ValueType MODBUS_MasterCommandType #define MODBUS_MASTER_QUEUE_MaxSize 10 typedef struct { MODBUS_MASTER_QUEUE_ValueType Value[MODBUS_MASTER_QUEUE_MaxSize]; ushort Head; ushort Tail; ushort Size; } MODBUS_MASTER_QUEUE_TypeDef; void MODBUS_MASTER_QUEUE_Push(MODBUS_MASTER_QUEUE_TypeDef* Que, MODBUS_MASTER_QUEUE_ValueType Data); void MODBUS_MASTER_QUEUE_Pop (MODBUS_MASTER_QUEUE_TypeDef* Que); ushort MODBUS_MASTER_QUEUE_NextIndex(ushort curIndex); /*----------End----------*/ #endif extern uchar MODBUS_MASTER_ActionFlag; void MODBUS_MASTER_Read (int* pointer); void MODBUS_MASTER_Write(int* pointer); void MODBUS_MASTER_Init (void); void MODBUS_MASTER_Action(void); #endif
#define MODBUS_MASTER_C #include "modbus_master.h" MODBUS_MASTER_QUEUE_TypeDef DirectMission; MODBUS_MASTER_QUEUE_TypeDef DutyMission[PrioritySize]; MODBUS_MasterCommandType* CurrentMission; uchar MODBUS_MASTER_ActionFlag; uchar MODBUS_MASTER_ErrorFlag; uchar RecByte[RecSize]; uchar Position; uchar StartFlag; ushort Counter; ushort DutyDelay[PrioritySize]; uchar MissionStatusFlag; void MODBUS_MASTER_Init(void) { GPIO_InitTypeDef GPIO_InitStructure ; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure ; //----------DATA Init---------- StartFlag = 0; Position = 0; Counter = 0; DutyDelay[0] = 100; DutyDelay[1] = 200; DutyDelay[2] = 500; MissionStatusFlag = MissionNone; //Mission MODBUS_MasterCommandType cmd; // cmd.Pointer =&SERVO_DataA.speed; // cmd.Last = SERVO_DataA.speed; // cmd.ReadOrWrite = WriteCmd; // cmd.ID = 0x01; // cmd.Addr = 0x0303; // cmd.Size = 1; // MODBUS_MASTER_InsertMission(cmd, 0); // // cmd.Pointer =&SERVO_DataA.position; // cmd.ReadOrWrite = ReadCmd; // cmd.ID = 0x01; // cmd.Addr = 0x1507; // cmd.Size = 2; // MODBUS_MASTER_InsertMission(cmd, 1); //----------GPIO Init---------- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, 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(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); //Limit GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; GPIO_Init(GPIOD, &GPIO_InitStructure); //----------USART Init---------- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, 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(USART3, &USART_InitStructure); //----------NVIC Init---------- NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //----------ENABLE---------- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); USART_Cmd(USART3, ENABLE); } uchar MODBUS_MASTER_CrcCheck(void) { uchar end = Position - 2; MyCRC_TypeDef crc; CRC_Clear(&crc); for(uchar i = 0; i < end; i ++) { CRC_Check(&crc, RecByte[i]); } if(RecByte[end] == crc.RegL && RecByte[end + 1] == crc.RegH) { return 0; } return 1; } void MODBUS_MASTER_SendData(uchar Data) { while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); USART_SendData(USART3, Data); } void MODBUS_MASTER_Deal0x03(void) { int rtn = 0; for(uchar i = 0; i < (*CurrentMission).Size; i ++) { uchar p = 3 + (i << 1); rtn<<= 16; rtn |= RecByte[p] << 8 | RecByte[p + 1]; } (*CurrentMission).Last = *(*CurrentMission).Pointer = rtn; (*CurrentMission).Error = 0; MissionStatusFlag = MissionNone; } void MODBUS_MASTER_Deal0x06(void) { (*CurrentMission).Last = *(*CurrentMission).Pointer; (*CurrentMission).Error = 0; MissionStatusFlag = MissionNone; } void MODBUS_MASTER_Deal0x10(void) { (*CurrentMission).Last = *(*CurrentMission).Pointer; (*CurrentMission).Error = 0; MissionStatusFlag = MissionNone; } void MODBUS_MASTER_Deal0x83(void) { (*CurrentMission).Error = ErrorMax; MissionStatusFlag = MissionNone; } void MODBUS_MASTER_DealRead(void) { uchar array[10]; array[0] = (*CurrentMission).ID; array[1] = 0x03; array[2] = (*CurrentMission).Addr >> 8; array[3] = (*CurrentMission).Addr; array[4] = 0x00; array[5] = (*CurrentMission).Size; MyCRC_TypeDef crc; CRC_Clear(&crc); for(uchar i = 0; i < 6; i ++) { MODBUS_MASTER_SendData(array[i]); CRC_Check(&crc, array[i]); } MODBUS_MASTER_SendData(crc.RegL); MODBUS_MASTER_SendData(crc.RegH); MissionStatusFlag = MissionStart; (*CurrentMission).Counter = 0; } void MODBUS_MASTER_DealWrite(void) { if((*CurrentMission).Last != *(*CurrentMission).Pointer) { uchar array[100]; array[0] = (*CurrentMission).ID; array[1] = 0x10; array[2] = (*CurrentMission).Addr >> 8; array[3] = (*CurrentMission).Addr; array[4] = 0x00; array[5] = (*CurrentMission).Size; array[6] = (*CurrentMission).Size << 1; int data = *(*CurrentMission).Pointer; for(uchar i = 0; i < (*CurrentMission).Size; i ++) { uchar p = 7 + (i << 1); array[p] = data >> 8; array[p+1] = data; data >>= 16; } MyCRC_TypeDef crc; CRC_Clear(&crc); uchar len = 7 + ((*CurrentMission).Size << 1); for(uchar i = 0; i < len; i ++) { MODBUS_MASTER_SendData(array[i]); CRC_Check(&crc, array[i]); } MODBUS_MASTER_SendData(crc.RegL); MODBUS_MASTER_SendData(crc.RegH); MissionStatusFlag = MissionStart; } else { MissionStatusFlag = MissionNone; } (*CurrentMission).Counter = 0; } void MODBUS_MASTER_Read(int* pointer) { MODBUS_MasterCommandType cmd; cmd.Pointer = pointer; cmd.ReadOrWrite = ReadCmd; MODBUS_MASTER_QUEUE_Push(&DirectMission, cmd); } void MODBUS_MASTER_Write(int* pointer) { MODBUS_MasterCommandType cmd; cmd.Pointer = pointer; cmd.Last =!*pointer; cmd.ReadOrWrite = WriteCmd; MODBUS_MASTER_QUEUE_Push(&DirectMission, cmd); } void MODBUS_MASTER_InsertMission(MODBUS_MasterCommandType mission, uchar priority) { MODBUS_MASTER_QUEUE_Push(&DutyMission[priority], mission); } void MODBUS_MASTER_RemoveMission(MODBUS_MasterCommandType mission) { for(uchar i = 0; i < PrioritySize; i ++) { uchar j = DutyMission[i].Size; while(j --) { uchar p = DutyMission[i].Head; if(DutyMission[i].Value[p].ID == mission.ID && DutyMission[i].Value[p].Addr == mission.Addr) { MODBUS_MASTER_QUEUE_Pop(&DutyMission[i]); return; } else { MODBUS_MASTER_QUEUE_Push(&DutyMission[i], DutyMission[i].Value[p]); MODBUS_MASTER_QUEUE_Pop (&DutyMission[i]); } } } } void MODBUS_MASTER_GetNewMission(void) { if(DirectMission.Size) { CurrentMission = &DirectMission.Value[DirectMission.Head]; MissionStatusFlag = MissionReady; MODBUS_MASTER_QUEUE_Pop(&DirectMission); return; } for(uchar i = 0; i < PrioritySize; i ++) { uchar j = DutyMission[i].Size; while(j--) { uchar p = DutyMission[i].Head; MODBUS_MASTER_QUEUE_Push(&DutyMission[i], DutyMission[i].Value[p]); MODBUS_MASTER_QUEUE_Pop (&DutyMission[i]); if(DutyMission[i].Value[p].Counter > DutyDelay[i]) { CurrentMission = &DutyMission[i].Value[p]; MissionStatusFlag = MissionReady; return; } } } } void MODBUS_MASTER_Action(void) { if(!MODBUS_MASTER_ActionFlag) { return; } MODBUS_MASTER_ActionFlag = 0; Counter ++; Counter = Min_ushort(Counter, CounterMax); if(Counter > SignalDelay && Position) { if(!MODBUS_MASTER_CrcCheck()) { switch(RecByte[1]) { case 0x03: { MODBUS_MASTER_Deal0x03(); }break; case 0x06: { MODBUS_MASTER_Deal0x06(); }break; case 0x10: { MODBUS_MASTER_Deal0x10(); }break; } StartFlag = 0; Position = 0; } } for(uchar i = 0; i < PrioritySize; i ++) { uchar j = DutyMission[i].Size; uchar k = DutyMission[i].Head; while(j--) { DutyMission[i].Value[k].Counter ++; DutyMission[i].Value[k].Counter = Min_ushort(DutyMission[i].Value[k].Counter, CounterMax); k = MODBUS_MASTER_QUEUE_NextIndex(k); } } if(MissionStatusFlag == MissionStart) { if((*CurrentMission).Counter > WaitDelay) { (*CurrentMission).Error ++; if((*CurrentMission).Error >= ErrorMax) { MODBUS_MASTER_GetNewMission(); } MissionStatusFlag = MissionReady; } } else { MODBUS_MASTER_GetNewMission(); } if(MissionStatusFlag != MissionReady) { return; } switch((*CurrentMission).ReadOrWrite) { case NoneCmd: { }break; case ReadCmd: { MODBUS_MASTER_DealRead(); }break; case WriteCmd: { MODBUS_MASTER_DealWrite(); }break; } } void USART3_IRQHandler(void) { if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { uchar rec = USART_ReceiveData(USART3); USART_ClearFlag(USART3, USART_IT_RXNE); if(Counter > SignalDelay) { StartFlag = 0; Position = 0; } Counter = 0; RecByte[Position ++] = rec; if(Position >= RecSize) { StartFlag = 0; Position = 0; } } } /*----------Queue----------*/ void MODBUS_MASTER_QUEUE_Push(MODBUS_MASTER_QUEUE_TypeDef* Que, MODBUS_MASTER_QUEUE_ValueType Data) { Que->Value[Que->Tail] = Data; Que->Tail = (Que->Tail + 1) % MODBUS_MASTER_QUEUE_MaxSize; Que->Size ++; } void MODBUS_MASTER_QUEUE_Pop(MODBUS_MASTER_QUEUE_TypeDef* Que) { Que->Head = (Que->Head + 1) % MODBUS_MASTER_QUEUE_MaxSize; Que->Size --; } ushort MODBUS_MASTER_QUEUE_NextIndex(ushort curIndex) { return (curIndex + 1) % MODBUS_MASTER_QUEUE_MaxSize; } /*----------End----------*/
标签:MODBUS,USART,主机,void,InitStructure,Modbus,MASTER,GPIO,模板 From: https://www.cnblogs.com/PolarBearINBrown/p/17769700.html