Пример #1
0
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)	
{
	u32 secpos;	   //扇区地址
	u16 secoff;	   //扇区内偏移地址(16位字计算)
	u16 secremain; //扇区内剩余地址(16位字计算)	   
 	u16 i;    
	u32 offaddr;   //去掉0X08000000后的地址
	if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*128)))return;//非法地址
	STMFLASH_Unlock();						//解锁
	offaddr=WriteAddr-STM32_FLASH_BASE;		//实际偏移地址offaddr=.5000 
	secpos=offaddr/1024;			        //扇区号
	secoff=(offaddr%1024)/2;		        //在扇区内的偏移(2个字节为基本单位.)
	secremain=512-secoff;		//扇区剩余空间大小   
	if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
	while(1) 
	{	
		STMFLASH_Read(secpos*1024+STM32_FLASH_BASE,STMFLASH_BUF,512);//读出整个扇区的内容
		for(i=0;i<secremain;i++)//校验数据
		{
			if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除  	  
		}
		if(i<secremain)//需要擦除
		{
			STMFLASH_ErasePage(secpos*1024+STM32_FLASH_BASE);//擦除这个扇区
			for(i=0;i<secremain;i++)//复制
			{
				STMFLASH_BUF[i+secoff]=pBuffer[i];	  
			}
			STMFLASH_Write_NoCheck(secpos*1024+STM32_FLASH_BASE,STMFLASH_BUF,512);//写入整个扇区  
		}else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间. 				   
		if(NumToWrite==secremain)break;//写入结束了
		else//写入未结束
		{
		   // printf("扇区加1\r\n");
			secpos++;				//扇区地址增1
			secoff=0;				//偏移位置为0 	 
		   	pBuffer+=secremain;  	//指针偏移
			WriteAddr+=secremain;	//写地址偏移	   
		   	NumToWrite-=secremain;	//字节(16位)数递减
			if(NumToWrite>512)
               secremain=512;//下一个扇区还是写不完
			else secremain=NumToWrite;//下一个扇区可以写完了
		}	 
	};	
	STMFLASH_Lock();//上锁
}
Пример #2
0
void STMFLASH_Write(u32 WriteAddr, u16 *pBuffer, u16 NumToWrite)	
{
	u32 secpos;		//扇区地址
	u16 secoff;		//扇区内偏移地址(16位字计算)
	u16 secremain;	//扇区内剩余地址(16位字计算)	   
 	u16 i;    
	u32 offaddr;	//去掉0X08000000后的地址
	if(WriteAddr < STM32_FLASH_BASE || (WriteAddr >= (STM32_FLASH_BASE + 1024 * STM32_FLASH_SIZE)))
		return;		//非法地址
	
	STMFLASH_Unlock();							//解锁
	offaddr = WriteAddr - STM32_FLASH_BASE;		//实际偏移地址.
	secpos = offaddr / STM_SECTOR_SIZE;			//扇区地址  0~127 for STM32F103RBT6
	secoff = (offaddr%STM_SECTOR_SIZE) / 2;		//在扇区内的偏移(2个字节为基本单位.)
	secremain = STM_SECTOR_SIZE / 2 - secoff;	//扇区剩余空间大小   
	if(NumToWrite <= secremain)
		secremain = NumToWrite;					//不大于该扇区范围
	
	while(1) 
	{	
		STMFLASH_Read(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE, STMFLASH_BUF, STM_SECTOR_SIZE / 2);	//读出整个扇区的内容
		for(i = 0; i < secremain; i++)			//校验数据
		{
			if(STMFLASH_BUF[secoff + i] != 0XFFFF)
				break;							//需要擦除  	  
		}
		
		if(i < secremain)						//需要擦除
		{
			STMFLASH_ErasePage(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE);	//擦除这个扇区
			for(i = 0; i < secremain; i++)		//复制
			{
				STMFLASH_BUF[i + secoff] = pBuffer[i];	  
			}
			STMFLASH_Write_NoCheck(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE, STMFLASH_BUF, STM_SECTOR_SIZE / 2);	//写入整个扇区  
		}
		else
		{
			STMFLASH_Write_NoCheck(WriteAddr, pBuffer, secremain);	//写已经擦除了的,直接写入扇区剩余区间. 				   
		}
		
		if(NumToWrite == secremain)
		{
			break;	//写入结束了
		}
		else		//写入未结束
		{
			secpos++;								//扇区地址增1
			secoff = 0;								//偏移位置为0 	 
		   	pBuffer += secremain;  					//指针偏移
			WriteAddr += secremain*2;				//写地址偏移(16位数据地址,需要*2)	   
		   	NumToWrite -= secremain;				//字节(16位)数递减
			if(NumToWrite >(STM_SECTOR_SIZE / 2))
				secremain = STM_SECTOR_SIZE / 2;	//下一个扇区还是写不完
			else
				secremain = NumToWrite;				//下一个扇区可以写完了
		}	 
	};
	
	STMFLASH_Lock();	//上锁
}