国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

嵌入式開(kāi)發(fā)--STM32G4系列片上FLASH的讀寫(xiě)

這篇具有很好參考價(jià)值的文章主要介紹了嵌入式開(kāi)發(fā)--STM32G4系列片上FLASH的讀寫(xiě)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

這個(gè)玩意吧,說(shuō)起來(lái)很簡(jiǎn)單,就是幾行代碼的事,但楞是折騰了我大半天時(shí)間才搞定。原因后面說(shuō),先看代碼吧:

讀操作

讀操作很簡(jiǎn)單,以32位方式讀取的時(shí)候是這樣的:

data = *(__IO uint32_t *)(0x0800F000);

需要注意的是,當(dāng)以32位方式讀取時(shí),地址需要是4的整數(shù)倍,即32位。
8位或16位方式類似操作即可
嵌入式開(kāi)發(fā)--STM32G4系列片上FLASH的讀寫(xiě),stm32,嵌入式硬件,單片機(jī)

寫(xiě)操作

需要注意的是,寫(xiě)操作時(shí),是以64位方式寫(xiě)入數(shù)據(jù),即以雙字的方式寫(xiě)入,以下代碼是將一個(gè)u64的值0x12345678aabbccdd,寫(xiě)入0x0800F000這個(gè)地址

HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
HAL_FLASH_Program(0, 0x0800F000, 0x12345678aabbccdd);
HAL_FLASH_Lock();

扇區(qū)擦除

  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;    //刪除方式
  EraseInitStruct.Page        = start;                    //超始頁(yè)號(hào)
  EraseInitStruct.NbPages     = len;                      //頁(yè)的數(shù)量
  EraseInitStruct.Banks       = bank;                     //bank號(hào)
  
  HAL_FLASH_Unlock();         //解鎖,以準(zhǔn)備進(jìn)行FLASH操作
  HAL_FLASHEx_Erase(&EraseInitStruct, &err);      //擦除
  HAL_FLASH_Lock();           //上鎖,以結(jié)束FLASH操作

調(diào)試

寫(xiě)完燒錄開(kāi)始調(diào)試,發(fā)現(xiàn)問(wèn)題了,有時(shí)能寫(xiě)入,有時(shí)不能寫(xiě)入。

先找了正點(diǎn)原子的例程來(lái)做參考,他的可以寫(xiě)入,但原子的例程是操作寄存器進(jìn)行讀寫(xiě)的,不直觀,移植性也不好,個(gè)人還是喜歡用HAL庫(kù)的方式來(lái)做東西,于是作罷。

然后又找了ST的例程來(lái)看,剛好手上有一塊G4的開(kāi)發(fā)板,于是編譯,報(bào)錯(cuò),可能是我的開(kāi)發(fā)環(huán)境比較新,與ST官方的編譯環(huán)境不同,又是一通折騰,編譯通過(guò),但一加載調(diào)試,就卡死不動(dòng)。

于是新建工程,再把ST的例程移植到我的工程中,編譯通過(guò),可以調(diào)試,還是有時(shí)能寫(xiě)有時(shí)不能寫(xiě)。又回到了起點(diǎn)。

不過(guò)在前面的折騰中總結(jié)了一個(gè)規(guī)律,第1次寫(xiě)入幾乎都會(huì)失敗,第2次有一半的機(jī)率成功,但后續(xù)成功率很高,幾乎不會(huì)寫(xiě)入失敗。于是改進(jìn)一下,增加對(duì)寫(xiě)入的判斷,如果發(fā)生錯(cuò)誤,會(huì)重復(fù)寫(xiě)入不超過(guò)10次,如果超過(guò)10次仍然錯(cuò)誤,則寫(xiě)入失敗。這樣就可以保證寫(xiě)入成功了。

測(cè)試代碼如下

未包含寫(xiě)入失敗的相關(guān)代碼,需要的自行添加。

if(GET_KEY() == 0)
{
  data32[0] = *(__IO uint32_t *)(0x08010000+i*8);		//FLASH讀數(shù)據(jù),以字的方式讀取
  data32[1] = *(__IO uint32_t *)(0x08010000+i*8+4);
  if((data32[0] == 0xffffffff) && (data32[1] == 0xffffffff))	//FLASH內(nèi)容為空
  {
    LED1(1);
     HAL_FLASH_Unlock();
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
    
    flash_count=0;
    while(flash_count < 10)
    {
      if(HAL_FLASH_Program(0, 0x08010000+i*8, 0xaabbccdd12340000+i) == HAL_OK)
        break;
      else
        flash_count++;
    
    }
    HAL_FLASH_Lock();
  }
  data32[0] = *(__IO uint32_t *)(0x08010000+i*8);
  data32[1] = *(__IO uint32_t *)(0x08010000+i*8+4);
  while(GET_KEY() == 0)
    ;
  LED1(0);
  i++;
}

嵌入式開(kāi)發(fā)--STM32G4系列片上FLASH的讀寫(xiě),stm32,嵌入式硬件,單片機(jī)

本段代碼能正確運(yùn)行的前提,是待寫(xiě)入?yún)^(qū)域是空的,即全都是0xFF才行。

封裝為函數(shù)

將代碼封裝一下,以便后續(xù)調(diào)用,并增加了一些條件判斷

頭文件如下:

//********************************************************************************************************
//*                                                                                   
//*  文件名:LL_flash.h                                                               
//*  文件說(shuō)明:STM32G系列片上FLASH的相關(guān)操作                                                     
//*  作者:李佳                                                                       
//*  微信:LAOLIDESENLIN                                                              
//*  說(shuō)明:本文檔遵循GNU3.0開(kāi)源許可證規(guī)范,即代碼可開(kāi)源并免費(fèi)使用,引用、修改、衍生代碼也需要開(kāi)源、免費(fèi)使用,
//*        但不允許修改后和衍生的代碼做為閉源的商業(yè)軟件發(fā)布和銷售
//*
//********************************************************************************************************

#ifndef __LL_FLASH_H__
#define __LL_FLASH_H__

#include "LL_define.h"


/**************************************************************************************/
/* G431芯片的128KFLASH容量的頁(yè)地址分布如下,共有1個(gè)BANK,64頁(yè),每一頁(yè)2kb大小 */
#define STM32_FLASH_BASE        0x08000000      /* STM32 FLASH 起始地址 */
#define STM32_FLASH_SIZE        0x20000         /* STM32 FLASH 總大小*/
#define STM32_FLASH_PAGE_SIZE   0x800           /* STM32 FLASH 頁(yè)大小*/


u8 LL_flash_erase_page(u16 start, u8 len, u8 bank);     //刪除FLASH扇區(qū)
u8 LL_flash_read(u32 addr, u64* pdata64, u32 len_64);   //讀片上FLASH
u8 LL_flash_write(u32 addr, u64* pdata64, u32 len_64);  //向片上FLASH寫(xiě)入數(shù)據(jù)

#endif

C文件如下

//********************************************************************************************************
//*                                                                                   
//*  文件名:LL_flash.c                                                               
//*  文件說(shuō)明:STM32G系列片上FLASH的相關(guān)操作                                                     
//*  作者:李佳                                                                       
//*  微信:LAOLIDESENLIN                                                              
//*  說(shuō)明:本文檔遵循GNU3.0開(kāi)源許可證規(guī)范,即代碼可開(kāi)源并免費(fèi)使用,引用、修改、衍生代碼也需要開(kāi)源、免費(fèi)使用,
//*        但不允許修改后和衍生的代碼做為閉源的商業(yè)軟件發(fā)布和銷售
//*
//*
//*
//********************************************************************************************************


#include "LL_flash.h"
#include "LL_IO.h"


//按頁(yè)刪除片上FLASH數(shù)據(jù)
//start: 起始頁(yè)號(hào)
//len:  待刪除的頁(yè)的數(shù)量
//bank: bank編號(hào)
//返回值:錯(cuò)誤類型,0表示無(wú)錯(cuò)誤
u8 LL_flash_erase_page(u16 start, u8 len, u8 bank)
{
  u32 err;
  u8 ret;
  FLASH_EraseInitTypeDef EraseInitStruct;
  u8 flash_count=0;
  
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;    //刪除方式
  EraseInitStruct.Page        = start;                    //超始頁(yè)號(hào)
  EraseInitStruct.NbPages     = len;                      //頁(yè)的數(shù)量
  EraseInitStruct.Banks       = bank;                     //bank號(hào)
  
  HAL_FLASH_Unlock();         //解鎖,以準(zhǔn)備進(jìn)行FLASH操作
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
  
  for(u8 i=0; i<10; i++)      //最多重復(fù)10次,如果仍然失敗,則返回
  {
    ret = HAL_FLASHEx_Erase(&EraseInitStruct, &err);      //擦除
    if (ret == HAL_OK)
      break;
  }
  
  if(ret != 0)
    led_err_flash(10, 100);   //擦除失敗后閃燈提示, 供調(diào)試階段使用, 正式使用時(shí)可刪除
  
  HAL_FLASH_Lock();           //上鎖,以結(jié)束FLASH操作
  return ret;
}


//讀片上FLASH
//addr: 32位的地址值,該值應(yīng)當(dāng)是8的整數(shù)倍,因?yàn)槭前凑?4位的方式讀取數(shù)據(jù)的
//pdata: 返回的數(shù)據(jù)首地址
//len: 待讀取數(shù)據(jù)的長(zhǎng)度, 長(zhǎng)度是按u64的數(shù)量
//返回值: 錯(cuò)誤類型,0表示無(wú)錯(cuò)誤
u8 LL_flash_read(u32 addr, u64* pdata64, u32 len_64)
{
  u64 data;
  
  for(u32 i=0; i<len_64; i++)
  {
    data = *(__IO uint64_t *)(addr+i*8);
    pdata64[i] = data;
  }
  return 0;
}


//向片上FLASH寫(xiě)入數(shù)據(jù),每次寫(xiě)入8字節(jié),不夠8字節(jié)的,以0xFF補(bǔ)足
//addr: 32位的地址值,該值應(yīng)當(dāng)是8的整數(shù)倍,因?yàn)槭前凑?4位的方式讀取數(shù)據(jù)的
//pdata: 待寫(xiě)入的數(shù)據(jù)首地址
//len: 待寫(xiě)入數(shù)據(jù)的長(zhǎng)度,長(zhǎng)度是按u64的數(shù)量
//返回值: 錯(cuò)誤類型,0表示無(wú)錯(cuò)誤
u8 LL_flash_write(u32 addr, u64* pdata64, u32 len_64)
{
  u8 ret;
  u64 read;
  
  HAL_FLASH_Unlock();           //上鎖,以結(jié)束FLASH操作
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);

  for(u16 j=0; j<len_64; j++) //按u64計(jì)算的
  {
    for(u8 i=0; i<10; i++)    //不超過(guò)10次的重復(fù)操作,以保證寫(xiě)入成功
    {
      ret = HAL_FLASH_Program(0, addr+j*8, *(pdata64+j));
      if(ret == HAL_OK)
      {
        read = *(__IO uint64_t *)(addr+j*8);  //在MCU認(rèn)為寫(xiě)入正確以后,再次讀取一下數(shù)據(jù),并進(jìn)行比對(duì),如果比對(duì)不成功,也說(shuō)明寫(xiě)入出錯(cuò)
        if(read != *(pdata64+j))
          ret = 255;
        return ret;
      }
    }
  }
  
  if(ret != 0)
    led_err_flash(10, 100);   //擦除失敗后閃燈提示, 供調(diào)試階段使用, 正式使用時(shí)可刪除
  
  HAL_FLASH_Lock();           //上鎖,以結(jié)束FLASH操作

  return ret;
}

封裝后的測(cè)試函數(shù)

u64 data64[32]={0};
u8 g_text_buf[64] = {"LIJIA000LIJIA001LIJIA002LIJIA003LIJIA004LIJIA005LIJIA006LIJIA007"};

    if(GET_KEY() == 0)
    {
      HAL_Delay(200);
      LL_flash_read(0x08010000, data64, 4);
      if(data64[0] == 0xffffffffffffffff)       //如果是空的,則寫(xiě)入
      {
        LED1(1);
        LED2(1);
        if(LL_flash_write(0x08010000, (u64*)g_text_buf, 4) != 0)
          continue;
      }
      else                                      //如果為非空,則擦除
      {
        LL_flash_erase_page(32, 1, 0);    //第32頁(yè),長(zhǎng)度1頁(yè),BANK 0
      }
      LL_flash_read(0x08010000, data64, 4);
      while(GET_KEY() == 0)
        ;
      LED1(0);
      LED2(0);
      i++;
    }

測(cè)試結(jié)果如下圖,如果寫(xiě)入成功,LED燈會(huì)在操作之后滅掉,如果寫(xiě)入失敗,則LED燈會(huì)保持點(diǎn)亮狀態(tài),
嵌入式開(kāi)發(fā)--STM32G4系列片上FLASH的讀寫(xiě),stm32,嵌入式硬件,單片機(jī)

總結(jié)

絕對(duì)不能只寫(xiě)入一次,就認(rèn)為寫(xiě)入正確,恰恰相反,最開(kāi)始的2次寫(xiě)入,極有可能寫(xiě)入失敗。
所以必須重復(fù)寫(xiě)入幾次,并且增加校驗(yàn),即寫(xiě)入完成后,再讀取數(shù)據(jù),并進(jìn)行比較,以確保正確。

下載

h和c文件已更新,可以讀寫(xiě)任意連續(xù)頁(yè)(扇區(qū)),對(duì)于只寫(xiě)一部分的頁(yè),未寫(xiě)的那部分的已有數(shù)據(jù)會(huì)予以保留,比如:一個(gè)扇區(qū)總共256個(gè)u64(雙字)寫(xiě)入了若干數(shù)據(jù),如果只需要改寫(xiě)其中的10個(gè)雙字,該寫(xiě)函數(shù)會(huì)自動(dòng)保留其他原始數(shù)據(jù),只更新其中的10個(gè)雙字,該功能已封裝到c文件中,可直接下載使用
下載地址:https://download.csdn.net/download/13011803189/88763405文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-801564.html

到了這里,關(guān)于嵌入式開(kāi)發(fā)--STM32G4系列片上FLASH的讀寫(xiě)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32開(kāi)發(fā)環(huán)境搭建&工程創(chuàng)建(嵌入式學(xué)習(xí))

    STM32開(kāi)發(fā)環(huán)境搭建&工程創(chuàng)建(嵌入式學(xué)習(xí))

    簡(jiǎn)介 STM32CubeMX是STMicroelectronics公司提供的一款集成開(kāi)發(fā)環(huán)境(IDE)工具,用于快速配置和初始化STM32微控制器系列的軟件工程。它提供了圖形化界面和交互式工具,使開(kāi)發(fā)者能夠輕松地生成STM32微控制器的初始化代碼和配置文件。 STM32CubeMX具有以下主要功能和特點(diǎn): 微控制器

    2024年02月11日
    瀏覽(98)
  • 藍(lán)橋杯嵌入式(G4系列)HAL:IIC通信之AT24C02與MCP4017

    藍(lán)橋杯嵌入式(G4系列)HAL:IIC通信之AT24C02與MCP4017

    目錄 前言: IIC協(xié)議簡(jiǎn)介: 1、起始信號(hào)和停止信號(hào): 2、應(yīng)答信號(hào): 3、讀寫(xiě)字節(jié): AT24C02: 字節(jié)寫(xiě)操作: 頁(yè)寫(xiě)操作: 讀操作: MCP4017: 寫(xiě)操作: 讀操作: ? ? ? ? 本篇文章主要介紹IIC通信協(xié)議,同時(shí)給大家介紹一下藍(lán)橋杯嵌入式的模塊的AT24C02和MCP4017,此外本篇博客會(huì)采

    2023年04月09日
    瀏覽(96)
  • 嵌入式物聯(lián)網(wǎng)STM32實(shí)戰(zhàn)開(kāi)發(fā)代碼例程庫(kù)

    幾百個(gè)例程清單,CSDN下載地址: https://download.csdn.net/download/weixin_39804904/88671879 開(kāi)發(fā)例程清單(持續(xù)新增中,歡迎點(diǎn)贊關(guān)注): 0001基于STM32F103單片機(jī)GPIO實(shí)現(xiàn)控制LED燈閃爍的程序代碼0001.rar 0002基于STM32F103單片機(jī)GPIO實(shí)現(xiàn)按鍵KEY的檢測(cè)程序代碼0002.rar 0003基于STM32F103單片機(jī)GPIO實(shí)現(xiàn)

    2024年02月02日
    瀏覽(94)
  • 嵌入式系統(tǒng)開(kāi)發(fā)13——STM32輸出PWM實(shí)現(xiàn)呼吸燈

    嵌入式系統(tǒng)開(kāi)發(fā)13——STM32輸出PWM實(shí)現(xiàn)呼吸燈

    本文主要介紹在STM32F103C8T6上,利用定時(shí)器輸出PWM波形,進(jìn)而驅(qū)動(dòng)LED實(shí)現(xiàn)呼吸燈。 使用TIM3和TIM4,分別輸出一個(gè)PWM波形,PWM的占空比隨時(shí)間變化,去驅(qū)動(dòng)你外接的一個(gè)LED以及最小開(kāi)發(fā)板上已焊接的LED(固定接在 PC13 GPIO端口),實(shí)現(xiàn)2個(gè) LED呼吸燈的效果。 脈沖寬度調(diào)制(PWM) ,是

    2023年04月08日
    瀏覽(90)
  • 嵌入式系統(tǒng)開(kāi)發(fā)筆記104:在STM32CubeIDE中導(dǎo)入工程

    嵌入式系統(tǒng)開(kāi)發(fā)筆記104:在STM32CubeIDE中導(dǎo)入工程

    ??本文講述如何在STM32CubeIDE中導(dǎo)入現(xiàn)有工程。

    2024年02月16日
    瀏覽(89)
  • 【STM32嵌入式系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)】——7有源蜂鳴器應(yīng)用

    【STM32嵌入式系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)】——7有源蜂鳴器應(yīng)用

    STM32資料包: 百度網(wǎng)盤(pán)下載鏈接:鏈接:https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd=8888 提取碼:8888 觀察電路圖,核心板PD14連接底板中的P2外接排針,將正負(fù)極接上直流電壓即可持續(xù)發(fā)聲,頻率固定。LED的PA0連接底板的D1燈。 步驟1:復(fù)制工程模板“1_Template”重命名為“4_Active

    2024年03月21日
    瀏覽(102)
  • 【嵌入式開(kāi)發(fā)工具】STM32+Keil實(shí)現(xiàn)軟件工程搭建與開(kāi)發(fā)調(diào)試

    【嵌入式開(kāi)發(fā)工具】STM32+Keil實(shí)現(xiàn)軟件工程搭建與開(kāi)發(fā)調(diào)試

    本篇文章介紹了使用Keil來(lái)對(duì)STM32F103C8芯片進(jìn)行初始工程搭建,以及開(kāi)發(fā)與工程調(diào)試的完整過(guò)程,幫助讀者能夠在實(shí)戰(zhàn)中體會(huì)到Keil這個(gè)開(kāi)發(fā)環(huán)境的使用方法,了解一個(gè)嵌入式工程從無(wú)到有的過(guò)程,并且具備快速搭建一個(gè)全新芯片對(duì)應(yīng)最小軟件工程的基本能力思路。文章首先介紹

    2024年02月05日
    瀏覽(95)
  • STM32F4+FreeRTOS+LVGL實(shí)現(xiàn)嵌入式快速開(kāi)發(fā)(縫合怪)

    STM32F4+FreeRTOS+LVGL實(shí)現(xiàn)嵌入式快速開(kāi)發(fā)(縫合怪)

    極速進(jìn)行項(xiàng)目開(kāi)發(fā),只需要懂一款芯片架構(gòu)+一個(gè)操作系統(tǒng)+一個(gè)GUI。各種部件程序全靠抄 ,成為究極縫合怪。本文用stm32f407+FreeRTOS+lvgl演示一些demo。 原文鏈接:STM32F4+FreeRTOS+LVGL實(shí)現(xiàn)快速開(kāi)發(fā)(縫合怪) lvgl官方的音樂(lè)播放器demo: 百問(wèn)網(wǎng)的2048小游戲: STM32F407這款芯片就不多介紹

    2024年02月08日
    瀏覽(96)
  • 嵌入式開(kāi)發(fā)--STM32用DMA+IDLE中斷方式串口接收不定長(zhǎng)數(shù)據(jù)

    嵌入式開(kāi)發(fā)--STM32用DMA+IDLE中斷方式串口接收不定長(zhǎng)數(shù)據(jù)

    之前講過(guò)用 利用IDLE空閑中斷來(lái)接收不定長(zhǎng)數(shù)據(jù) ,但是沒(méi)有用到DMA,其實(shí)用DMA會(huì)更加的高效,MCU也可以騰出更多的性能去處理應(yīng)該做的事情。 IDLE顧名思義,就是空閑的意思,即當(dāng)監(jiān)測(cè)到串口空閑超過(guò)1個(gè)串口的數(shù)據(jù)幀時(shí),會(huì)使?fàn)顟B(tài)寄存器(SR或ISR)的IDLE位置位,如果此時(shí)控制

    2024年04月17日
    瀏覽(39)
  • 嵌入式開(kāi)發(fā)的學(xué)習(xí)與未來(lái)展望:借助STM32 HAL庫(kù)開(kāi)創(chuàng)創(chuàng)新之路

    嵌入式開(kāi)發(fā)的學(xué)習(xí)與未來(lái)展望:借助STM32 HAL庫(kù)開(kāi)創(chuàng)創(chuàng)新之路

    ? 引言: 嵌入式開(kāi)發(fā)作為計(jì)算機(jī)科學(xué)領(lǐng)域的重要分支,為我們的日常生活和產(chǎn)業(yè)發(fā)展提供了無(wú)限的可能。STMicroelectronics的STM32系列芯片以其出色的性能和廣泛的應(yīng)用領(lǐng)域而備受關(guān)注。而STM32 HAL庫(kù)作為嵌入式開(kāi)發(fā)的高級(jí)庫(kù),為學(xué)習(xí)者提供了更高效、更簡(jiǎn)單的開(kāi)發(fā)方式。本文將結(jié)

    2024年02月12日
    瀏覽(30)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包