
方法一
modbus.c
#include "modbus.h"
/* Debug */
//#define debugPrint
/* Initialize the entire structure */
MODBUS_DATA modbusData={0};
static void SendArray(uint8_t *p_Arr, uint16_t LEN)
{
RS485_ENABLE;
HAL_UART_Transmit_DMA(&huart1, p_Arr, LEN);
RS485_DISABLE;
}
/* Save -> Erase -> Write */
int ee_EraseAndWrite(uint32_t regNum,uint16_t regLen, const uint8_t *data)
{
uint8_t flashBuf[1024];
HAL_FLASH_Unlock();
/* Read out the original page and save it in buffer */
if(ee_read(0,1024,flashBuf) !=1)
{
return -1;
}
/* Modifies the data at the specified location in the buffer */
for(int i=0;i<regLen;i++)
{
flashBuf[2*(regNum+i)]=data[2*i];
flashBuf[2*(regNum+i)+1]=data[2*i+1];
}
/* Erase a page */
Flash_Erase(0x0801FC00,1); //0x0801FC00 is the first address of this page
/* Write the data in buffer into the entire page */
/* The actual address changed is the last page of the flash: 0+0x08000000+1024*127=0x0801FC00 */
if(ee_write(0,512,flashBuf) !=1)
{
return -2;
}
return 0;
}
/* Flash erases an entire page */
void Flash_Erase(uint32_t pageAddr,uint32_t nbPage)
{
FLASH_EraseInitTypeDef flash_eeprom;
uint32_t erase_addr;
/* 擦除一页 */
flash_eeprom.TypeErase = FLASH_TYPEERASE_PAGES; /* 选择页擦除 */
flash_eeprom.NbPages = nbPage; /* 要擦除的页数 */
flash_eeprom.PageAddress =pageAddr; /* 要擦除的起始地址 */
HAL_FLASHEx_Erase(&flash_eeprom, &erase_addr);
}
/* Debug */
void print_readOnePage(void)
{
uint8_t flashBuf[1024]={0};
//0+0x08000000+1024*127=0x0801FC00
if(ee_read(0,1024,flashBuf) !=1)
{
printf("ERROR:ee_read!\r\n");
}
for(int i=0;i<1024;i++)
{
printf("%02x",flashBuf[i]);
}
printf("\r\n");
}
int Modbus_Event()
{
uint16_t crc, calCRC;
if (modbusData.reFlag == 0)
{
return -1;
}
#ifdef debugPrint
for(int i=0;i< 8;i++)
{
printf("%02x",uart1RxBuf[i]);
}
printf("\r\n");
#endif
/* Remove the data received by the serial port */
memset(modbusData.rtuRxBuf,0,sizeof(modbusData.rtuRxBuf));
memcpy(modbusData.rtuRxBuf,uart1RxBuf,sizeof(modbusData.rtuRxBuf));
memset(uart1RxBuf,0,sizeof(uart1RxBuf));
#ifdef debugPrint
for(int i=0;i< 8;i++)
{
printf("%02x",modbusData.rtuRxBuf[i]);
}
printf("\r\n");
#endif
/* Start parsing data */
if(modbusData.rtuRxBuf[1]==0x03)
{
modbusData.recount=8;
}
if(modbusData.rtuRxBuf[1]==0x10)
{
modbusData.recount=modbusData.rtuRxBuf[6] + 9;
}
/* CRC check is performed on the received data */
calCRC = ModRTU_CRC(&modbusData.rtuRxBuf[0], modbusData.recount - 2);
crc = modbusData.rtuRxBuf[modbusData.recount - 2] * 256 + modbusData.rtuRxBuf[modbusData.recount - 1];
if (crc == calCRC)
{
if (modbusData.rtuRxBuf[0] == modbusData.Address)
{
switch (modbusData.rtuRxBuf[1])
{
case 3:
Modbus_Func3(); //0x03
break;
case 16:
Modbus_Func16(); //0x10
break;
default:
printf("No matching MODBUS function code exists\r\n");
break;
}
}
else
{
printf("ERROR:This ID number is not native!\r\n");
}
} else
{
printf("ERROR:CRC check error!\r\n");
}
modbusData.reFlag = 0;
modbusData.recount = 0;
return 0;
}
int Modbus_Func3()
{
uint16_t regAdd,regLen,calCRC,j;
uint8_t i;
uint8_t eeReadData[2];
regAdd = modbusData.rtuRxBuf[2] * 256 + modbusData.rtuRxBuf[3];
regLen = modbusData.rtuRxBuf[4] * 256 + modbusData.rtuRxBuf[5];
#ifdef debugPrint
printf("regAdd:%d\r\n",regAdd);
printf("regLen:%d\r\n",regLen);
#endif
i = 0;
modbusData.rtuTxBuf[i++] = modbusData.Address;
modbusData.rtuTxBuf[i++] = 0x03;
modbusData.rtuTxBuf[i++] = ((regLen * 2) % 256);
if(ee_read(regAdd,regLen*2,eeReadData) !=1)