最近做个modbus网关,用到的MCU是stm32L152,这个项目是和别人合作,我做顶层的算法和从机协议,从机读回来的数据要存到外部flash中,而外部flash的索引地址要保存到内部的eeprom中,底层驱动合作方已经写好了,直接拿来使用。测试代码如下:
FLASH_Status writeEEPROMByte(uint32_t address, uint8_t data) {
FLASH_Status status = FLASH_COMPLETE;
address = address + EEPROM_START_ADDR;
DATA_EEPROM_Unlock(); //Unprotect the EEPROM to allow writing
while(FLASH_GetStatus()!=FLASH_COMPLETE);
status = DATA_EEPROM_ProgramByte(address, data);
DATA_EEPROM_Lock(); // Reprotect the EEPROM
return status;
}
uint8_t readEEPROMByte(uint32_t address) {
uint8_t tmp = 0;
address = address + EEPROM_START_ADDR;
tmp = *(__IO uint32_t*)address;
return tmp;
}
/*********************************************************************************
* Function Name : initAddrParameter
* Output : none
* Return : None
**********************************************************************************/
void initAddrParameter(void)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)
// if(readEEPROMByte(0x24) == 0x55)
{
writeEEPROMByte(0x24,0x55);
initParameter();
W25QXX_Erase_Sector(0);
}else
{
//¶ÁÊý¾ÝµØÖ·
write_Addr.wBlock_Addr = readEEPROMByte(0x00); // 0-255
write_Addr.wSector_Addr = readEEPROMByte(0x04);
write_Addr.wPage_Addr = readEEPROMByte(0x08);
write_Addr.wOffset_Addr = readEEPROMByte(0x0c);
write_Addr.wOver_take = readEEPROMByte(0x10);
read_Addr.rBlock_Addr = readEEPROMByte(0x14);
read_Addr.rSector_Addr = readEEPROMByte(0x18);
read_Addr.rPage_Addr = readEEPROMByte(0x1c);
read_Addr.rOffset_Addr = readEEPROMByte(0x20);
}
// initParameter();
// W25QXX_Erase_Sector(0);
//
}
void saveAddrParameter(void)
{
FLASH_Status status = FLASH_COMPLETE;
u8 tempaddr = 0;
__disable_irq() ;
//
writeEEPROMByte(0x00,write_Addr.wBlock_Addr); // 0-255
writeEEPROMByte(0x04,write_Addr.wSector_Addr);
writeEEPROMByte(0x08,write_Addr.wPage_Addr);
writeEEPROMByte(0x0c,write_Addr.wOffset_Addr);
writeEEPROMByte(0x10,write_Addr.wOver_take);
tempaddr = read_Addr.rBlock_Addr;
status= writeEEPROMByte(0x14,2);
tempaddr = read_Addr.rSector_Addr;
status= writeEEPROMByte(0x18,9);
tempaddr = read_Addr.rPage_Addr;
status= writeEEPROMByte(0x1c,6);
tempaddr = read_Addr.rOffset_Addr;
status= writeEEPROMByte(0x20,1);
__enable_irq() ;
}
读写测试OK
当把该程序加主程序中,从机读取完数据要保存时调用saveAddrParameter()函数出现 FLASH_ERROR_WRP 错误
调用改函数后 在往 flash 中写数据 就会发生错误。
经过一晚上的反复调试终于确定了错误。
在readDataFromFlash()中 调用了readWriteConpare这个参数
然后就出现了错误。
细心的朋友 ,我想已经发现了错误。
上层函数调用的时候传递进来的参数是NULL ,也就是说 PeerAddr是空
而我在这个函数中给空赋值,导致出错,也就是出现ASH_ERROR_WR 的病根,本身读写程序并没有错误。
给朋友们提个醒,传递指针的时候要格外小心,看清楚,找个错误很是费时间啊!!