/* -------------------------- (C) COPYRIGHT 2022 Fortiortech ShenZhen ---------------------------*/ /** * @copyright (C) COPYRIGHT 2022 Fortiortech Shenzhen * @file * @author Fortiortech Appliction Team * @since Create:2022-07-14 * @date Last modify:2022-07-14 * @note Last modify author is Leo.li * @brief */ /* Includes ------------------------------------------------------------------*/ #include #include ROM_TypeDef xdata FlashData; uint8 Flash_GetAddress(void); /** * @brief 读取固定地址值 * @date 2022-07-14 */ uint8 ReadFlashValue(uint16 ReadAddress) { uint16 TempAddress0 = ReadAddress; __IO uint8 tevalue = 0; //临时变量 tevalue = *(uint8 code *)TempAddress0; //读取回地址的值 return tevalue; } /** * @brief 擦除指定扇区 * @brief FlashAddress--Flash自擦除扇区内任意地址 * @return 0--Flash自擦除成功,1--Flash自擦除失败 * @date 2022-07-14 */ uint8 Flash_Sector_Erase(uint8 xdata * FlashAddress) { bool TempEA; uint16 TempFlashAddress; TempEA = EA; EA = 0; TempFlashAddress = (uint16)FlashAddress; if ((TempFlashAddress) < (0x7f00)) // 不擦除最后一个扇区 { FLA_CR = 0x03; //使能自擦除 FLA_KEY = 0x5a; FLA_KEY = 0x1f; //flash预编程解锁 _nop_(); *FlashAddress = 0xff; //写任意数据 FLA_CR = 0x08; //开始预编程,完成后Flash再次上锁 } EA = TempEA; if (ReadBit(FLA_CR, FLAERR)) { return 1; } else { return 0; } } /** * @brief 擦除指定扇区 * @brief FlashAddress--指定写入地址 * @brief FlashData--写入数值 * @return 0--Flash自擦除成功,1--Flash自擦除失败 * @date 2022-07-14 */ void Flash_Sector_Write(uint8 xdata * FlashAddress, uint8 Flash_Data) { bool TempEA = 0; uint16 TempFlashAddress; uint8 idata Flash_Data_t = Flash_Data; TempEA = EA; EA = 0; TempFlashAddress = (uint16)FlashAddress; if ((TempFlashAddress) < 0x7f00) // 不编程最后一个扇区 { FLA_CR = 0x01; // 使能Flash编程 FLA_KEY = 0x5a; FLA_KEY = 0x1f; // flash预编程解锁 _nop_(); *(uint8 xdata *)FlashAddress = Flash_Data_t; // 写编程数据 FLA_CR = 0x08; // 开始预编程,完成后Flash再次上锁 } EA = TempEA; } /** * @brief WriteAddress--指定写入地址 * @brief Length:写入数组长度 * @brief value--写入数组 * @date 2022-11-14 */ uint8 Flash_WriteValue(uint16 WriteAddress, uint8 Length, uint8 * str) { uint8 i; uint8 TempReadRomValue; uint16 FlashWriteAddr = WriteAddress; //读出有效数据 for (i = 0; i < Length; i++) { Flash_Sector_Write(FlashWriteAddr + i, str[i]); TempReadRomValue = *(uint8 code *)(FlashWriteAddr + i); if (TempReadRomValue != str[i]) { return 0; } } return 1; } /** * @brief 获取最后写入的地址,确认最新能写入的地址 * @brief unsigned short FlashAddress:目标FLASH首地址 * @brief uint8 Write_Length:写入数值长度 */ uint16 GetWrite_Black_Addr(unsigned short FlashAddress, uint8 Write_Length) { uint16 TempFlashAddress = 0; uint16 TempFirstAddress = 0; //用来保存保存首地址 uint8 tempFlashData = 0xFF; uint8 Length = 0; TempFlashAddress = FlashAddress; TempFirstAddress = FlashAddress; while ((Length != Write_Length) && (TempFlashAddress < (TempFirstAddress + Write_Length))) //限定读取地址为当前页 { tempFlashData = *(uint8 code *)(TempFlashAddress); //读取目标地址中数值是否为0 if (tempFlashData == 0) { Length ++; TempFlashAddress += 1; } else { TempFirstAddress += Write_Length; //首地址跳转Write_Length字节 if (TempFirstAddress > 0x7f00) { TempFirstAddress = 0x7f00; } TempFlashAddress = TempFirstAddress; Length = 0; } } return TempFirstAddress; } /** * @brief 读取Length字节数据, * @Input unsigned short BlockStartAddr:目标FLASH首地址 * @Input uint8 Length:数值长度 * @Input uint8 * str :读回数值写入数组 * @ruturn Flash数据 */ void ReadFromFlash(unsigned short BlockStartAddr, uint8 Length, uint8 * str) { uint8 i = 0; for (i = 0; i < Length; i++) { str[i] = *(uint8 code *)(BlockStartAddr + i); } } /** * @brief 扇区擦除 * @Input * @ruturn */ void Flash_Erase(void) { uint8 FlashEraseStatus = 0; FlashEraseStatus = Flash_Sector_Erase(START_WriteADDRESS); if (!FlashEraseStatus) { /*----- 获取写入首地址 -----*/ FlashData.WriteAddress = GetWrite_Black_Addr(START_WriteADDRESS, Write_Lenght); } else { FlashEraseStatus = Flash_Sector_Erase(START_WriteADDRESS); FlashData.WriteAddress = START_WriteADDRESS; //第一次擦写失败后第二次擦写,强行给地址 /*----- 第二次擦写再失败,默认为Flash损坏,不进行处理 -----*/ if (FlashEraseStatus) { ; } } FlashData.Flag_FlashErase = 0; } /** * @brief 保存按键 * @date 2022-11-14 */ void Save_KeyValue(void) { uint8 FlashWriteStatus = 0; //返回值 uint8 TempReadValue = 0; FlashData.WriteValue[0] = KS.KeyValuetotal; if (FlashData.ReadValue[0] != FlashData.WriteValue[0]) //确认写入前后数据不一致 { EA = 0; while (!FlashWriteStatus) //写入异常,换到下个地址写入 { FlashWriteStatus = Flash_WriteValue(FlashData.WriteAddress, Write_Lenght, FlashData.WriteValue); if (FlashWriteStatus) { Flash_Sector_Write(FlashData.WriteAddress + Verify_Bit, Verify_Ture); TempReadValue = *(uint8 code *)(FlashData.WriteAddress + Verify_Bit); /*----- 更新读取Flash首地址 -----*/ FlashData.ReadAddress = FlashData.WriteAddress - Write_Lenght; /*----- 读取数值到FlashData.ReadValue -----*/ ReadFromFlash(FlashData.ReadAddress, Write_Lenght, FlashData.ReadValue); if (TempReadValue == Verify_Ture) { goto exit; } else { FlashWriteStatus = 0; } } else { Flash_Sector_Write(FlashData.WriteAddress + Verify_Bit, Verify_Error); FlashData.WriteAddress = FlashData.WriteAddress + Write_Lenght; if (FlashData.WriteAddress > START_WriteADDRESS + 0x70) { FlashData.Flag_FlashErase = 1; //写到扇区最后字节,依然失败,直接进行数值清楚 goto exit; } } } exit: EA = 1; } }