STM32 通过Modbus协议更改内部Flash(模仿EEPROM)的运行参数

方法一

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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值