|
- #include "stm32f4xx.h"
- #include "hardware.h"
- #include "ucos_ii.h"
- #include "os.h"
- #include "app_cfg.h"
- #include "sys_cfg.h"
- #include "string.h"
- #include "modbus.h"
-
- extern OS_EVENT* ModbusReceived; /*接收到modbus请求报文*/
-
-
-
-
- /*0x270F+1=K10000*/
- uint8_t ModbusCoil[1250]; /*10000/8=1250*/
- uint16_t ModbusReg[10000];
-
-
- void AddCrc16(uint8_t *data, uint16_t length);
- int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length);
- uint8_t ModbusReadCoil(uint16_t addres, uint16_t num);
- uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data);
- uint8_t ModbusReadReg(uint16_t addres, uint16_t num);
- uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data);
-
- /*USART接收空闲中断*/
- void USART1_IRQHandler(void)
- {
- OSIntEnter(); /*进入中断*/
-
- uint32_t temp;
- uint16_t rxLenRemain;
-
- if(USART_GetITStatus(USART1, USART_IT_IDLE) == SET)
- {
- /*在计算数据长度之前先关闭DMA接收通道,防止计算过程中DMA继续转运数据*/
- DMA_Cmd(DMA2_Stream2, DISABLE);
-
- /*清除IDLE中断标志位*/
- temp = USART1->SR;
- temp = USART1->DR;
- (void)temp;
-
- /*清除传输已经完成TCIF2、传输已经完成一半HTIF2标志位*/
- DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TCIF2 | DMA_FLAG_HTIF2);
-
- /*计算数据长度*/
- rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2);
- ModbusRxLen = MODBUS_RX_BUF_SIZE - rxLenRemain;
-
- if(ModbusRxLen != 0)
- {
- OSSemPost(ModbusReceived);
- }
-
- /*重新指定接收地址*/
- DMA_MemoryTargetConfig(DMA2_Stream2, (uint32_t)ModbusRxBuf, DMA_Memory_0);
- /*重启DMA*/
- DMA_SetCurrDataCounter(DMA2_Stream2, MODBUS_RX_BUF_SIZE);
- DMA_Cmd(DMA2_Stream2, ENABLE);
- }
-
- OSIntExit(); /*退出中断*/
- }
-
-
- /*modbus响应帧发送*/
- void ModbusSend(uint8_t *txBuf, uint16_t len)
- {
- /*先关闭DMA发送通道*/
- DMA_Cmd(DMA2_Stream7, DISABLE);
-
- /*等待DMA关闭*/
- while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);
-
- /*清除传输已经完成TCIF7、传输已经完成一半HTIF7、FIFO错误FEIF7标志位*/
- DMA_ClearFlag(DMA2_Stream7, DMA_FLAG_FEIF7 | DMA_FLAG_HTIF7 | DMA_FLAG_TCIF7);
-
- /*配置发送地址和长度*/
- DMA_MemoryTargetConfig(DMA2_Stream7, (uint32_t)txBuf, DMA_Memory_0);
- DMA_SetCurrDataCounter(DMA2_Stream7, len);
-
- /*启动 DMA 发送*/
- DMA_Cmd(DMA2_Stream7, ENABLE);
- }
-
-
- /*modbus协议帧解析任务*/
- void AppTaskModbusParse (void *p_arg)
- {
- INT8U err;
- MODBUS_FRAME frame;
- uint16_t rxLen;
- uint8_t rxBuf[256];
-
- while(1)
- {
- OSSemPend(ModbusReceived, 0, &err);
-
- rxLen = ModbusRxLen;
-
- memcpy(rxBuf, ModbusRxBuf, rxLen);
-
- frame.crc = ((uint16_t)(rxBuf[rxLen - 1])) | ((uint16_t)rxBuf[rxLen - 2] << 8);
- if(ChcekCrc16(frame.crc, rxBuf, rxLen) != 0)
- {
- /****************************crc错误处理******************************/
- }
-
-
- frame.slaveAddres = rxBuf[0];
- if(frame.slaveAddres != SLAVE_ADDRES)
- {
- /*****************************从机地址错误处理************************/
- }
-
-
- frame.func = rxBuf[1];
- frame.opeAddres = ((uint16_t)rxBuf[2] << 8) | ((uint16_t)rxBuf[3]);
- frame.opeNum = ((uint16_t)rxBuf[4] << 8) | ((uint16_t)rxBuf[5]);
-
-
-
- switch(frame.func)
- {
- case 0x01:/*读线圈*/
- ModbusReadCoil(frame.opeAddres, frame.opeNum);
-
- break;
-
- case 0x03:/*读寄存器*/
- ModbusReadReg(frame.opeAddres, frame.opeNum);
-
- break;
-
- case 0x0F:/*写多个线圈*/
- frame.wNum = rxBuf[6];
- memcpy(frame.wData, &rxBuf[7], frame.wNum);
-
- ModbusWriteCoil(frame.opeAddres, frame.opeNum, frame.wData);
-
-
- break;
-
- case 0x10:/*写多个寄存器*/
- frame.wNum = rxBuf[6];
- memcpy(frame.wData, &rxBuf[7], frame.wNum);
-
- ModbusWriteReg(frame.opeAddres, frame.opeNum, frame.wData);
-
- break;
-
- default:/*功能码错误*/
-
-
-
- break;
-
- }
- ModbusSend(ModbusTxBuf, ModbusTxLen);
- }
- }
-
- uint8_t ModbusReadCoil(uint16_t addres, uint16_t num)
- {
- uint16_t byteIndI;
- uint8_t bitIndI;
- uint16_t byteIndO;
- uint8_t bitIndO;
-
- uint8_t dataLen;
-
- uint8_t index;
- uint8_t readVal;
- uint8_t writeVal;
-
-
- if(addres > 0x270F || (addres + num) > 0x270F)
- {
- /********************地址超限处理*****************/
- }
-
-
- dataLen = (num + 7) / 8;
-
- memset(&ModbusTxBuf[3], 0, 253);/*清零发送数组*/
-
-
-
- for(uint16_t i = 0; i < num; i++)
- {
- byteIndO = i / 8;
- bitIndO = i % 8;
-
- byteIndI = (addres + i) / 8;
- bitIndI = (addres + i) % 8;
-
- readVal = ModbusCoil[byteIndI] & ((uint8_t)1 << bitIndI);
-
- if(readVal != 0)
- {
- index = 3 + byteIndO;
- writeVal = (uint8_t)1u << bitIndO;
-
- ModbusTxBuf[index] |= writeVal;
- }
- }
-
- ModbusTxBuf[0] = SLAVE_ADDRES;
- ModbusTxBuf[1] = 0x01;
- ModbusTxBuf[2] = dataLen;/*响应帧返回数据字节数*/
- AddCrc16(ModbusTxBuf, 3 + dataLen);
- ModbusTxLen = 5 + dataLen;
- }
-
- uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
- {
- uint16_t byteIndI;
- uint8_t bitIndI;
- uint16_t byteIndO;
- uint8_t bitIndO;
-
- uint8_t readVal;
- uint8_t writeVal;
-
-
- if(addres > 0x270F || (addres + num) > 0x270F)
- {
- /********************地址超限处理*****************/
- }
-
-
-
- for(uint16_t i = 0; i < num; i++)
- {
- byteIndI = (addres + i) / 8;
- bitIndI = (addres + i) % 8;
-
- byteIndO = i / 8;
- bitIndO = i % 8;
-
- readVal = data[byteIndO] | ((uint8_t)1 << bitIndO);
- writeVal = (uint8_t)1 << bitIndI;
-
-
- if(readVal != 0)
- {
- ModbusCoil[byteIndI] |= writeVal;
- }
- else
- {
- ModbusCoil[byteIndI] &= (~writeVal);
- }
-
- ModbusTxBuf[0] = SLAVE_ADDRES;
- ModbusTxBuf[1] = 0x0F;
- /*操作地址*/
- ModbusTxBuf[2] = (uint8_t)(addres >> 8);
- ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
- /*成功写入的数量*/
- ModbusTxBuf[4] = (uint8_t)(num >> 8);
- ModbusTxBuf[5] = (uint8_t)(num & 0x00FF);
- AddCrc16(ModbusTxBuf, 6);
- ModbusTxLen = 8;
- }
- }
-
- uint8_t ModbusReadReg(uint16_t addres, uint16_t num)
- {
- uint8_t index;
- uint8_t readValH;
- uint8_t readValL;
- uint8_t dataLen;
-
-
-
- if(addres > 0x270F || (addres + num) > 0x270F)
- {
- /********************地址错误处理*****************/
- }
-
-
- dataLen = num * 2;
- for(uint16_t i = 0; i < num; i++)
- {
- index = 3 + (i * 2);
- readValH = (uint8_t)(ModbusReg[addres + i] >> 8);
- readValL = (uint8_t)(ModbusReg[addres + i] & 0x00FF);
-
- ModbusTxBuf[index] = readValH;
- ModbusTxBuf[index + 1] = readValL;
- }
- ModbusTxBuf[0] = SLAVE_ADDRES;
- ModbusTxBuf[1] = 0x03;
- ModbusTxBuf[2] = dataLen;
- AddCrc16(ModbusTxBuf, 3 + dataLen);
- ModbusTxLen = 5 + dataLen;
- }
-
- uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data)
- {
- uint8_t index;
-
- uint8_t writeValH;
- uint8_t writeValL;
- uint16_t writeVal;
-
-
- if(addres > 0x270F || (addres + num) > 0x270F)
- {
- /********************地址错误处理*****************/
- }
-
-
- for(uint16_t i = 0; i < num; i++)
- {
- index = i * 2;
-
- writeValH = data[index];
- writeValL = data[index + 1];
-
- writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
- ModbusReg[addres + i] = writeVal;
- }
-
- ModbusTxBuf[0] = SLAVE_ADDRES;
- ModbusTxBuf[1] = 0x10;
- /*操作地址*/
- ModbusTxBuf[2] = (uint8_t)(addres >> 8);
- ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
- /*成功写入数量*/
- ModbusTxBuf[4] = (uint8_t)(num >> 8);
- ModbusTxBuf[5] = (uint8_t)(num & 0x00FF);
- AddCrc16(ModbusTxBuf, 6);
- ModbusTxLen = 8;
-
- }
-
- uint16_t Crc16(const uint8_t *data, uint16_t length);
-
- void AddCrc16(uint8_t *data, uint16_t length)
- {
- uint16_t crc16 = Crc16(data, length);
-
- /*低前高后*/
- data[length] = (uint8_t)(crc16 & 0x00FF);
- data[length + 1] = (uint8_t)(crc16 >> 8);
- }
-
- /*crc16校验*/
- uint16_t Crc16(const uint8_t *data, uint16_t length)
- {
- uint16_t crc;
- uint16_t byteInd;
- uint8_t bitInd;
-
- crc = 0xFFFFu;
- for (byteInd = 0u; byteInd < length; byteInd++)
- {
- crc ^= (uint16_t)data[byteInd];
- for (bitInd = 0u; bitInd < 8u; bitInd++)
- {
- if ((crc & 0x0001u) != 0u)
- {
- crc >>= 1;
- crc ^= 0xA001u;
- }
- else
- {
- crc >>= 1;
- }
- }
- }
- return crc;
- }
-
- /*crc16检查*/
- int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length)
- {
- uint16_t crc16 = Crc16(data, (length - 2));
-
- if(recCrc16 == crc16)
- {
- return 0;
- }
- else
- {
- return -1;
- }
- }
|