STM8块编程的步骤为:
1、解锁FLASH权限
2、块编程
3、上锁FLASH权限
Note:如果你不是调用官方库函数对FLASH进行解锁,则要注意顺序,FLASH与EEPROM的解锁顺序是刚好相反的,解锁函数原型如下
/**
* @brief Unlocks the program or data EEPROM memory
* @param FLASH_MemType : Memory type to unlock
* This parameter can be a value of @ref FLASH_MemType_TypeDef
* @retval None
*/
void FLASH_Unlock(FLASH_MemType_TypeDef FLASH_MemType)
{
/* Check parameter */
assert_param(IS_MEMORY_TYPE_OK(FLASH_MemType));
/* Unlock program memory */
if (FLASH_MemType == FLASH_MEMTYPE_PROG)
{
FLASH->PUKR = FLASH_RASS_KEY1;
FLASH->PUKR = FLASH_RASS_KEY2;
}
/* Unlock data memory */
else
{
FLASH->DUKR = FLASH_RASS_KEY2; /* Warning: keys are reversed on data memory !!! */
FLASH->DUKR = FLASH_RASS_KEY1;
}
}
STM8块编程官方库函数原型如下:
/**
* @brief Programs a memory block
* @note This function should be called and executed from RAM.
* @param FLASH_MemType : The type of memory to program
* @param BlockNum : The block number
* @param FLASH_ProgMode : The programming mode.
* @param Buffer : Pointer to buffer containing source data.
* @retval None.
*/
IN_RAM(void FLASH_ProgramBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType,
FLASH_ProgramMode_TypeDef FLASH_ProgMode, uint8_t *Buffer))
{
uint16_t Count = 0;
uint32_t startaddress = 0;
/* Check parameters */
assert_param(IS_MEMORY_TYPE_OK(FLASH_MemType));
assert_param(IS_FLASH_PROGRAM_MODE_OK(FLASH_ProgMode));
if (FLASH_MemType == FLASH_MEMTYPE_PROG)
{
assert_param(IS_FLASH_PROG_BLOCK_NUMBER_OK(BlockNum));
startaddress = FLASH_PROG_START_PHYSICAL_ADDRESS;
}
else
{
assert_param(IS_FLASH_DATA_BLOCK_NUMBER_OK(BlockNum));
startaddress = FLASH_DATA_START_PHYSICAL_ADDRESS;
}
/* Point to the first block address */
startaddress = startaddress + ((uint32_t)BlockNum * FLASH_BLOCK_SIZE);
/* Selection of Standard or Fast programming mode */
if (FLASH_ProgMode == FLASH_PROGRAMMODE_STANDARD)
{
/* Standard programming mode */ /*No need in standard mode */
FLASH->CR2 |= FLASH_CR2_PRG;
FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NPRG);
}
else
{
/* Fast programming mode */
FLASH->CR2 |= FLASH_CR2_FPRG;
FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NFPRG);
}
/* Copy data bytes from RAM to FLASH memory */
for (Count = 0; Count < FLASH_BLOCK_SIZE; Count++)
{
#if defined (STM8S208) || defined(STM8S207) || defined(STM8S105) || defined (STM8AF62Ax) ||\
defined (STM8AF52Ax) || defined (STM8AF626x)
*((PointerAttr uint8_t*) (uint16_t)startaddress + Count) = ((uint8_t)(Buffer[Count]));
#elif defined (STM8S103) || defined (STM8S903)
*((PointerAttr uint8_t*) (uint16_t)startaddress + Count) = ((uint8_t)(Buffer[Count]));
#endif
}
}
注意事项:如果调用官方块编程的库函数,默认是关闭的状态,所以你需要把IN_RAM改为开启状态,因为IN_RAM由 #define RAM_EXECUTION (0) 控制,把(0)改为(1),然后重新编译即可。
回到正题!!!
如果你确保块编程的函数操作没有任何问题,逻辑都正确的情况下,程序跑到块编程执行烧写FLASH时,程序就卡死不动了,那就有可能是IAR优化等级过高导致的,博主实测优化等级开到HIGH高等级模式下,块编程操作失败,导致程序卡死。
如果你的程序空间不够,一定要开到最高优化等级,别担心,还有办法!!!
直接上代码
//写入一块数据
//选择不优化该函数,防止优化等级过高导致块编程失败卡死
#pragma optimize= none
__ramfunc void STMFLASH_WriteBlock(u16 block,u8 *block_buff)
{
uint8_t i;
u32 addr;
addr = block;
addr *=BLOCK_BYTES;
addr +=FLASH_PROG_START_PHYSICAL_ADDRESS;
/* Unlock program memory */
FLASH->PUKR = FLASH_RASS_KEY1;
FLASH->PUKR = FLASH_RASS_KEY2;
//Flash标准块编程:FLASH_NCR2_NPRG 快速块编程:FLASH_NCR2_NFPRG
FLASH->CR2 |= FLASH_CR2_PRG;
FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NPRG);
for(i=0; i<BLOCK_BYTES; i++)
{
*((PointerAttr uint8_t*)(u32)addr + i) = (u8)block_buff[i];
}
while( (FLASH->IAPSR & (FLASH_IAPSR_EOP | FLASH_IAPSR_WR_PG_DIS)) == 0);
/* Lock memory */
FLASH->IAPSR &= (uint8_t)FLASH_MEMTYPE_PROG;
}
参考链接:
iar选择性优化函数模块设置