IAP_6_内部Flash写

正点的代码,很好用哟。
库函数也把很多工作都做了,直接调用即可,具体操作读手册。

1、内部Flash写

  1. 解锁,FLASH_Unlock();

按顺序在FPEC键寄存器中写入0x45670123、0xCDEF89AB两个键值。

  1. 读要写的地址是否为0xFF,是则用FLASH_ProgramHalfWord写入数据,不是则页擦除FLASH_ErasePage后写入。

FLASH_ProgramHalfWord中已经包含Flash控制寄存器的PG置位和等待写入完成的操作。
大容量一页是2K字节,小容量一页是1K字节。

  1. 上锁,FLASH_Lock();

2、代码

2.1、一页的容量

#define STM32_FLASH_SIZE 128     //所选STM32的FLASH容量大小(单位为K)

//不同容量的扇区大小
#if STM32_FLASH_SIZE<256
    #define STM_SECTOR_SIZE 1024  //1K字节
#else 
    #define STM_SECTOR_SIZE 2048  //2K字节

2.2、不检查0xFF直接写入

//WriteAddr:起始地址; pBuffer:数据指针; NumToWrite:半字(16位)数  
void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   
{        
    u16 i;
    for(i=0;i<NumToWrite;i++){
        FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
        WriteAddr+=2;  //地址增加2.
    }  
} 

2.3、指定地址写入指定数量的数据,检查、切换页

u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];	//扇区缓存

//从指定地址开始写入指定长度的数据
//WriteAddr:起始地址(此地址必须为2的倍数!!)
//pBuffer:数据指针
//NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
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;					//非法地址
    			
    FLASH_Unlock();				//解锁	
    offaddr=WriteAddr-STM32_FLASH_BASE;		//实际偏移地址.	
    secpos=offaddr/STM_SECTOR_SIZE;		//扇区地址  0~127 for STM32F103RBT6;0-255 for 战舰 	
    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){			//需要擦除			
	    FLASH_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;		//写地址偏移	   		   	
	    NumToWrite-=secremain;		//字节(16位)数递减						
	    if(NumToWrite>(STM_SECTOR_SIZE/2))				
		secremain=STM_SECTOR_SIZE/2;	//下一个扇区还是写不完			
	    else 				
		secremain=NumToWrite;		//下一个扇区可以写完了		
	}	 	
    }		
    FLASH_Lock();				//上锁
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值