打印
[STM32F1]

对于STM32的flash地址不是太明白

[复制链接]
446|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ousj|  楼主 | 2021-4-1 20:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我应该怎么擦出和编写呢?

使用特权

评论回复
沙发
pengf| | 2021-4-1 20:51 | 只看该作者
你有什么打算呢?或者你想知道什么?

使用特权

评论回复
板凳
ousj|  楼主 | 2021-4-1 20:53 | 只看该作者
我能从0x8002000开始擦出吗?

使用特权

评论回复
地板
supernan| | 2021-4-1 20:55 | 只看该作者
写多少?

使用特权

评论回复
5
ousj|  楼主 | 2021-4-1 20:57 | 只看该作者
大概2000个。

使用特权

评论回复
6
xxrs| | 2021-4-1 21:00 | 只看该作者
应该是有捷径的,2000个咋弄

使用特权

评论回复
7
zhanghqi| | 2021-4-1 21:03 | 只看该作者
可以擦除,但必须以块为单位,不同型号块的大小不同,需要查资料。

使用特权

评论回复
8
yinxiangh| | 2021-4-1 21:04 | 只看该作者
ST官方不是有参考程序吗

使用特权

评论回复
9
liuzaiy| | 2021-4-1 21:06 | 只看该作者

/**************************************************************************************
* FunctionName   : FLSEraseFlash()
* Description    : Flash擦除
* EntryParameter : sAddr - 起始地址,eAddr - 结束地址,pageSize - 页大小
* ReturnValue    : None
**************************************************************************************/
void FLSEraseFlash(u32 sAddr, u32 eAddr, u32 pageSize)
{
    u8 i, maxPag;
    volatile FLASH_Status fshStu = FLASH_COMPLETE;
   
    maxPag = (eAddr - sAddr) / pageSize;                                        // 页数
    FLASH_Unlock();                                                             // 解锁的闪存程序擦除控制器
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
   
    for (i=0; ((i
    {
        fshStu = FLASH_ErasePage(sAddr + (pageSize * i));                       // 擦除FLASH页
    }
   
    FLASH_Lock();                                                               // 锁Flash
}
复制代码
/**************************************************************************************
* FunctionName   : FLSWriteFlash()
* Description    : 写Flash
* EntryParameter : wrtAddr - 写地址,pDat - 数据,len - 数据长度
* ReturnValue    : 成功返回0,否则返回1
**************************************************************************************/
u8 FLSWriteFlash(u32 wrtAddr, u8 *pDat, u32 len)
{
    u8  times = 0;
    u16 i;
    u32 wrtDat = 0, reaDat = 0;                                                 // 读写缓冲
    u32 addr = wrtAddr;
   
    FLASH_Unlock();                                                             // 解锁的闪存程序擦除控制器
    for (i=0; i
    {
        wrtDat = (pDat[i+0]<<0) + (pDat[i+1]<<8) + (pDat[i+2]<<16) + (pDat[i+3]<<24);                           
        
        do
        {
            times++;
            FLASH_ProgramWord(addr, wrtDat);                                    // 写Flash
            reaDat = FLSReadDword(addr);                                        // 读Flash
            
        } while ((reaDat != wrtDat) && (times < 5));
        
        if (times == 0)                                                         // 读写错误
        {
            FLASH_Lock();                                                       // 锁Flash
            return 1;
        }
        
        times = 0;
        addr += 4;                                                              // 偏移地址
    }
   
    FLASH_Lock();                                                               // 锁Flash
    return 0;
}

使用特权

评论回复
10
pangb| | 2021-4-1 21:08 | 只看该作者

uint16_t Flash_Write_Without_check(uint32_t iAddress, uint8_t *buf, uint16_t iNumByteToWrite) {
    uint16_t i;
    volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
    i = 0;
   
//    FLASH_UnlockBank1();
    while((i < iNumByteToWrite) && (FLASHStatus == FLASH_COMPLETE))
    {
      FLASHStatus = FLASH_ProgramHalfWord(iAddress, *(uint16_t*)buf);
      i = i+2;
      iAddress = iAddress + 2;
      buf = buf + 2;
    }
   
    return iNumByteToWrite;
}
/**
  * @brief  Programs a half word at a specified Option Byte Data address.
  * @NOTE   This function can be used for all STM32F10x devices.
  * @param  Address: specifies the address to be programmed.
  * @param  buf: specifies the data to be programmed.
  * @param  iNbrToWrite: the number to write into flash
  * @retval if success return the number to write, -1 if error
  *  
  */
int Flash_Write(uint32_t iAddress, uint8_t *buf, uint32_t iNbrToWrite) {
                /* Unlock the Flash Bank1 Program Erase controller */
        uint32_t secpos;
        uint32_t iNumByteToWrite = iNbrToWrite;
uint16_t secoff;
uint16_t secremain;  
  uint16_t i = 0;   
        uint8_t tmp[FLASH_PAGE_SIZE];
        
        FLASH_UnlockBank1();
secpos=iAddress & (~(FLASH_PAGE_SIZE -1 )) ;//扇区地址
secoff=iAddress & (FLASH_PAGE_SIZE -1);     //在扇区内的偏移
secremain=FLASH_PAGE_SIZE-secoff;           //扇区剩余空间大小
        volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
        
        if(iNumByteToWrite<=secremain) secremain = iNumByteToWrite;//不大于4096个字节
        
        while( 1 ) {
            Flash_Read(secpos, tmp, FLASH_PAGE_SIZE);   //读出整个扇区
            for(i=0;i<secremain;i++) {       //校验数据
       if(tmp[secoff+i]!=0XFF)break;       //需要擦除
   }
            if(i<secremain) {  //需要擦除
                FLASHStatus = FLASH_ErasePage(secpos); //擦除这个扇区
                if(FLASHStatus != FLASH_COMPLETE)
                  return -1;
                for(i=0;i<secremain;i++) {   //复制
                        tmp[i+secoff]=buf;   
                }
                Flash_Write_Without_check(secpos ,tmp ,FLASH_PAGE_SIZE);//写入整个扇区  
            } else {
                Flash_Write_Without_check(iAddress,buf,secremain);//写已经擦除了的,直接写入扇区剩余区间.
            }
            
            if(iNumByteToWrite==secremain) //写入结束了
                break;
            else {
                secpos += FLASH_PAGE_SIZE;
                secoff = 0;//偏移位置为0
                buf += secremain;  //指针偏移
                iAddress += secremain;//写地址偏移   
                iNumByteToWrite -= secremain;  //字节数递减
                if(iNumByteToWrite>FLASH_PAGE_SIZE) secremain=FLASH_PAGE_SIZE;//下一个扇区还是写不完
                else secremain = iNumByteToWrite;  //下一个扇区可以写完了
            }
            
         }
        
        FLASH_LockBank1();
        return iNbrToWrite;
}






/**
  * @brief  Programs a half word at a specified Option Byte Data address.
  * @note   This function can be used for all STM32F10x devices.
  * @param  Address: specifies the address to be programmed.
  * @param  buf: specifies the data to be programmed.
  * @param  iNbrToWrite: the number to read from flash
  * @retval if success return the number to write, without error
  *  
  */
int Flash_Read(uint32_t iAddress, uint8_t *buf, int32_t iNbrToRead) {
        int i = 0;
        while(i < iNbrToRead ) {
           *(buf + i) = *(__IO uint8_t*) iAddress++;
           i++;
        }
        return i;
}


-------------------DataFlash.h----------------------------------
#ifndef   __DATAFLASH_H__
#define   __DATAFLASH_H__


#include "stm32f10x.h"
#include "stm32f10x_flash.h"




#if defined (STM32F10X_HD) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) || defined (STM32F10X_XL)
  #define FLASH_PAGE_SIZE    ((uint16_t)0x800)
  
#else
  #define FLASH_PAGE_SIZE    ((uint16_t)0x400)
#endif




int Flash_Read(uint32_t iAddress, uint8_t *buf, int32_t iNbrToRead) ;
int Flash_Write(uint32_t iAddress, uint8_t *buf, uint32_t iNbrToWrite);


#endif

使用特权

评论回复
11
chenjunt| | 2021-4-1 21:10 | 只看该作者
《stm32flash编程手册》 去看看这个。

使用特权

评论回复
12
llljh| | 2021-4-1 21:12 | 只看该作者
有现成的例程啊

使用特权

评论回复
13
renyaq| | 2021-4-1 21:14 | 只看该作者

应该先读读课本

使用特权

评论回复
14
xxrs| | 2021-4-1 21:15 | 只看该作者
我也一直闹不明白

使用特权

评论回复
15
ousj|  楼主 | 2021-4-1 21:17 | 只看该作者
其实还是不大明白,我再琢磨琢磨吧,多谢了哈

使用特权

评论回复
16
磨砂| | 2021-5-1 11:03 | 只看该作者
需要看看数据手册

使用特权

评论回复
17
晓伍| | 2021-5-1 11:06 | 只看该作者
有需要的特定地址吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

712

主题

7557

帖子

1

粉丝