历史上的今天
返回首页

历史上的今天

今天是:2024年12月09日(星期一)

正在发生

2020年12月09日 | STM32F7xx —— 内部flash

2020-12-09 来源:eefocus

这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。


// STM32F767IGT6: 1M flash

// STM32F767ZIT6: 2M flash

#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */

#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */

#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */

#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */

#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */

#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */

#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */

#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */

#ifdef STM32F767ZIT6

#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */

#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */

#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */

#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */

#endif

// 获取要擦除扇区编号

static uint32_t flash_sector_number(uint32_t address)

{

  uint32_t sector = 0;

 

  if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))

  {

    sector = FLASH_SECTOR_0;

  }

  else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))

  {

    sector = FLASH_SECTOR_1;

  }

  else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))

  {

    sector = FLASH_SECTOR_2;

  }

  else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))

  {

    sector = FLASH_SECTOR_3;

  }

  else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))

  {

    sector = FLASH_SECTOR_4;

  }

  else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))

  {

    sector = FLASH_SECTOR_5;

  }

  else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))

  {

    sector = FLASH_SECTOR_6;

  }

#ifdef STM32F767ZIT6

  else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))

  {

    sector = FLASH_SECTOR_7;

  }

  else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))

  {

    sector = FLASH_SECTOR_8;

  }

  else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))

  {

    sector = FLASH_SECTOR_9;

  }

  else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))

  {

    sector = FLASH_SECTOR_10;

  }

  else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))

  {

    sector = FLASH_SECTOR_11;

  }

#else

  else if(address >= ADDR_FLASH_SECTOR_7)

  {

    sector = FLASH_SECTOR_6;

  }

#endif

 

  return sector;

}

 

// 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。

void SocFlashErase(uint32_t addr, uint8_t count)

{

  FLASH_EraseInitTypeDef flash_erase;

  uint32_t flash_error;

 

  HAL_FLASH_Unlock();

 

  flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除

  flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区

  flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1

  flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!

 

  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |

                         FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);

 

  HAL_FLASHEx_Erase(&flash_erase, &flash_error);

 

  FLASH_WaitForLastOperation(50000);

 

  HAL_FLASH_Lock();

}

 

uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)

{

  uint32_t i;

  uint16_t data = 0;

 

  if (length == 0)

  {

    return 0;

  }

 

  HAL_FLASH_Unlock();

 

  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |

                         FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);

 

  // 按半字编程

  for (i = 0; i < length; i += 2)

  {

    data = (*(buffer + i + 1) << 8) + (*(buffer + i));

    HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);

  }

 

  HAL_FLASH_Lock();

 

  return 0;

}

 

uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)

{

  memcpy(buffer, (void *)addr, length);

 

  return length;

}


推荐阅读

史海拾趣

Anadigm公司的发展小趣事

Anadigm是一家曾经存在的半导体公司,专注于可编程模拟信号处理器(PASP)技术。以下是Anadigm公司发展的相关故事:

  1. 公司成立与初期发展:Anadigm公司成立于1997年,总部位于美国加利福尼亚州圣塔莫尼卡市。公司的创始人致力于开发一种新型的可编程模拟信号处理器(PASP),以应对传统模拟电路设计的局限性。通过引入数字技术,Anadigm旨在提供更灵活、高性能的模拟信号处理解决方案。

  2. PASP技术的推出与市场应用:Anadigm公司于2000年推出了其首款可编程模拟信号处理器产品系列。这些器件具有灵活的可编程性和高度集成的特点,能够适应多种应用场景,包括电力管理、医疗设备、汽车电子和工业控制等领域。Anadigm的PASP技术受到了行业的关注,并在市场上取得了一定的成功。

  3. 技术创新与产品优化:Anadigm公司不断投入研发,致力于改进其PASP技术并推出更先进的产品。公司持续与客户合作,了解市场需求并进行技术创新,以满足不断变化的行业需求。Anadigm的产品不断优化,性能不断提升,赢得了客户的信赖和市场份额的扩大。

  4. 合并与收购:尽管Anadigm公司在PASP技术方面取得了一定的成就,但面临着激烈的市场竞争和资金压力。在公司运营一段时间后,Anadigm于2008年被美国半导体公司Exar Corporation收购。此次收购使得Anadigm成为Exar的全资子公司,继续在模拟信号处理领域发展。

  5. 最终终止业务:然而,随着时间的推移,Anadigm在市场上的地位逐渐下滑,未能在激烈的竞争中保持竞争优势。最终,Exar Corporation于2014年宣布终止Anadigm的业务,并关闭其产品线。这标志着Anadigm作为一个独立的实体在半导体行业的终结。

以上是Anadigm公司发展的一些主要故事,展示了该公司从创立到终止业务的发展历程。

Displaytech公司的发展小趣事

Displaytech一直致力于技术创新和产品升级。在多年的发展过程中,公司不断推出新的LCD产品,包括触摸屏TFT、单色图形LCD和字符显示模块等。同时,公司还加强了表面贴装能力、PCB组装服务、工具和注塑成型等业务的拓展,进一步提升了整体竞争力。

CalAmp公司的发展小趣事

CalAmp公司以其卓越的无线产品、设备和方案供应能力,赢得了业界的广泛认可。某年,CalAmp与全球知名的电子分销商Mouser签署了全球分销协议。这一合作使得Mouser能够备有CalAmp公司的一系列产品,如UHF和VHF收发器模块、遥感勘测模块以及适用于不同频带的无线通信装置。这些产品广泛应用于各种无线通信领域,其方便快速集成的特点大大加快了客户产品的上市时间,同时提供了性价比极高的无线解决方案。这一协议的签署不仅进一步巩固了CalAmp在全球无线产品市场的领导地位,也为Mouser带来了更多的业务机会。

C&K Components公司的发展小趣事

进入60年代,随着计算机和电子行业的迅猛发展,C&K敏锐地捕捉到了微型开关市场的巨大潜力。公司果断进行业务重组,将重心转向计算机和电子行业的微型开关生产。这一转型不仅使C&K在技术上取得了重大突破,也使其在市场上获得了更多的机会。凭借对客户需求的深入理解和优质服务的提供,C&K迅速赢得了客户的信赖,并逐渐成为行业内的佼佼者。

HEIMANN公司的发展小趣事

进入60年代,随着计算机和电子行业的迅猛发展,C&K敏锐地捕捉到了微型开关市场的巨大潜力。公司果断进行业务重组,将重心转向计算机和电子行业的微型开关生产。这一转型不仅使C&K在技术上取得了重大突破,也使其在市场上获得了更多的机会。凭借对客户需求的深入理解和优质服务的提供,C&K迅速赢得了客户的信赖,并逐渐成为行业内的佼佼者。

Heimann Optoelectronics Gmbh公司的发展小趣事

2018年,Hei Inc Optoelectronic Division抓住行业整合的机遇,成功并购了一家在光电子材料领域具有领先地位的企业。这次并购不仅使公司获得了先进的光电子材料生产技术,还极大地丰富了公司的产品线。通过整合双方资源和技术优势,公司在光电子器件的研发和生产上实现了质的飞跃。并购后的Hei Inc Optoelectronic Division不仅在市场上占据了更大的份额,还进一步提升了自身的技术实力和品牌影响力。

问答坊 | AI 解惑

女生学嵌入式怎么样??希望有经验人士给点建议

我本科专业电子信息,考研准备考这个方向,专业名叫电路与系统,方向有嵌入式,估计算是硬件方面吧,我想问问女生学这个就业怎么样啊??工作环境呢?待遇呢??谢谢啦哦~~~我是初级者,积分少见谅哦,呜呜本想增加点分数,结果点错了~~见谅哦~~…

查看全部问答>

Uart_GetIntNum()的问题!

一个简单程序 y=Uart_GetIntNum(); Uart_Printf(\"%d\",y); 比如我在超级终端输入233 返回却是2 这是怎么回事啊? …

查看全部问答>

有关mw5.0,directshow中NondelegatingRelease问题

请问,我在debug下就出现1个问题:error LNK2001: unresolved external symbol \"public: virtual unsigned long __cdecl CBaseFilter::NonDelegatingRelease(void)\" (?NonDelegatingRelease@CBaseFilter@@UAAKXZ) 在release下就没有(wchar_t as ...…

查看全部问答>

注册表中IRQ该添加多少?

#define AT91C_ID_IRQ1   ((unsigned int) 30) // Advanced Interrupt Controller (IRQ1) 我用的是IRQ1,IRQ1定义为上. 那我注册表中的IRQ添加多少呢? 1E 还是30? 我试了1E不行啊!…

查看全部问答>

wince, windows mobile, ppc, smartphone 等等一系列的疑惑???

刚入门,对这些东西之间的区别不是很明了. Windows Mobile搭建于WinCE之上 ,而Pocket PC和Smartphone是Windows Mobile的两个不同版本. 这个对不? 另外,WinCE最新版本是不是6.0? Windows Mobile的最新版本是不是5.0? WinCE5.0版本上搭建起来 ...…

查看全部问答>

我使用pwm,按照例程写了程序,但是有问题

TBCCR0 = 4096-1;                           // PWM Period      TBCCTL4 = OUTMOD_7;        &nbs ...…

查看全部问答>

K60 PDB KEIL编程

1.各位高手,想请教一下,可编程延迟模块PDB所谓的延时是针对于什么延时?应该是分ADC,DAC模块而不同的是吗?那针对于不同的操作模块,他又是对哪一步操作进行延时呢?     2. PDB0->SC =  PDB_SC_CONT_MASK   &n ...…

查看全部问答>

【SensorTag】之 CC Debugger 固件!!!

先前没有接触过无线的东西,所以很多东西都不太明白。 昨天收到CC Debugger,马上下载、安装软件测试。 大家注意 SmartRF Flash Programmer 这个软件,是可以刷CC Debugger固件的,点击的千万小心! 在这个模式里,是刷固件的,USB就是通过USB直 ...…

查看全部问答>

什么是射频信号?

什么是射频信号?谢谢…

查看全部问答>