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

STM32CubeMX學(xué)習(xí)筆記16--- STM32內(nèi)部FLASH

這篇具有很好參考價值的文章主要介紹了STM32CubeMX學(xué)習(xí)筆記16--- STM32內(nèi)部FLASH。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 內(nèi)部FLASH簡介

????????之前的文章中介紹過STM32F1利用SPI與外部FLASH(W25QXX芯片)通訊的例程,本例程將介紹STM32F1的內(nèi)部FLASH,通過內(nèi)部FLASH實(shí)現(xiàn)數(shù)據(jù)讀寫操作。 不同型號的STM32,其FLASH容量也有所不同,最小的只有16K字節(jié),最大的則達(dá)到了1024K字節(jié)。此處我們使用的是STM32F103ZET6,其FLASH容量為512K字節(jié),屬于大容量產(chǎn)品,大容量產(chǎn)品的閃存模塊組織圖如下圖示

cubemx 配置stm32內(nèi)部flash存,stm32學(xué)習(xí),stm32,學(xué)習(xí),筆記

STM32F1的閃存模塊由:主存儲器、信息塊和閃存存儲器接口寄存器3部分組成

  • 主存儲器:用來存放代碼和數(shù)據(jù)常量,起始地址是0x08000000,BOOT0和BOOT1都接GND時,就是從該起始地址運(yùn)行代碼的
  • 信息塊:分為2個小部分,啟動程序代碼是用來存儲ST自帶的啟動程序,用于串口下載代碼,BOOT0接3.3V,BOOT1接GND時,運(yùn)行的就是這部分代碼;選擇字節(jié)則一般用于配置寫保護(hù)、讀保護(hù)等功能
  • 閃存存儲器接口寄存器:用于控制閃存讀寫等,是整個閃存模塊的控制機(jī)構(gòu)

對主存儲器和信息塊的寫入由內(nèi)嵌的閃存編程/擦除控制器(FPEC)管理:編程與擦除的高電壓由內(nèi)部產(chǎn)生。在執(zhí)行閃存寫操作時,任何對閃存的讀操作都會鎖住總線,在寫操作完成后讀操作才能正確地進(jìn)行,即在進(jìn)行寫或擦除操作時,不能進(jìn)行代碼或數(shù)據(jù)的讀取操作。

下面介紹閃存的讀取、編程和擦除:

<1>. 閃存的讀取 內(nèi)置閃存模塊可以在通用地址空間直接尋址,任何32位數(shù)據(jù)的讀操作都能訪問閃存模塊的內(nèi)容并得到相應(yīng)的數(shù)據(jù)。

例如,要從地址addr,讀取一個半字,可通過如下語句讀?。? data = *(__IO uint16_t*)addr?將addr強(qiáng)制轉(zhuǎn)換為vu16指針,然后取該指針?biāo)赶虻牡刂返闹担吹玫搅薬ddr地址的值

<2>. 閃存的編程 STM32的閃存編程是由FPEC(閃存編程和擦除控制器)模塊處理的,這個模塊包含7個32位寄存器,它們分別是:

FPEC鍵寄存器(FLASH_KEYR)
選擇字節(jié)鍵寄存器(FLASH_OPTKEYR)
閃存控制寄存器(FLASH_CR)
閃存狀態(tài)寄存器(FLASH_SR)
閃存地址寄存器(FLASH_AR)
選擇字節(jié)寄存器(FLASH_OBR)
寫保護(hù)寄存器(FLASH_WRPR)

其中FPEC鍵寄存器共有3中鍵值:?PDPRT=0x000000A5; KEY1=0x45670123; KEY2=0xCDEF89AB?STM32復(fù)位后,F(xiàn)PEC模塊是被保護(hù)的,不能寫入FLASH_CR寄存器;通過寫入特定的序列到FLASH_KEYR寄存器可以打開FPEC模塊(即寫入KEY1和KEY2),只有在寫保護(hù)被解除后,才能操作相關(guān)寄存器。 閃存編程過程如下圖所示:

cubemx 配置stm32內(nèi)部flash存,stm32學(xué)習(xí),stm32,學(xué)習(xí),筆記

<3>. 閃存的擦除 閃存編程的時候,要先判斷其寫入地址的FLASH是被擦除了的(也就是其值必須是0xFFFF),否則無法寫入。閃存擦除分為頁擦除和整片擦除。 閃存頁擦除過程如下圖示:

cubemx 配置stm32內(nèi)部flash存,stm32學(xué)習(xí),stm32,學(xué)習(xí),筆記

官方固件HAL庫FLASH操作的幾個常見函數(shù):

//源文件: stm32f1xx_hal_flash.c和stm32f1xx_hal_flash_ex.c
HAL_FLASH_Unlock(void); //解鎖函數(shù)
HAL_FLASH_Lock(void);   //鎖定函數(shù)
HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);   //寫操作函數(shù)
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);   //擦除函數(shù)
HAL_FLASH_WaitForLastOperation(uint32_t Timeout);   //等待操作完成函數(shù)

?

2、 硬件設(shè)計(jì)

led2指示燈用來提示系統(tǒng)運(yùn)行狀態(tài),s1按鍵用來控制FLASH的數(shù)據(jù)寫入,s2按鍵用來控制FLASH的數(shù)據(jù)讀取,數(shù)據(jù)的寫入與讀取信息通過串口1打印出來

  • LED2指示燈
  • S2和S1按鍵
  • USART1
  • STM32F1內(nèi)部FLASH

?3、STM32CubeMX設(shè)置

  • RCC設(shè)置外接HSE,時鐘設(shè)置為72M
  • PE5設(shè)置為GPIO推挽輸出模式、上拉、高速、默認(rèn)輸出電平為高電平
  • USART1選擇為異步通訊方式,波特率設(shè)置為115200Bits/s,傳輸數(shù)據(jù)長度為8Bit,無奇偶校驗(yàn),1位停止位
  • PE3,PE4設(shè)置為GPIO輸入模式、上拉模式
  • 輸入工程名,選擇工程路徑(不要有中文),選擇MDK-ARM V5;勾選Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;點(diǎn)擊GENERATE CODE,生成工程代碼

4、程序編程

  • 創(chuàng)建按鍵驅(qū)動文件key.c 和相關(guān)頭文件key.h

如果要對FLASH進(jìn)行寫入數(shù)據(jù),需要執(zhí)行以下四步:

  1. 解鎖FLASH
  2. 擦除FLASH
  3. 寫入FLASH
  4. 鎖住FLASH
  • 創(chuàng)建FLASH驅(qū)動文件stmflash.c 和相關(guān)頭文件stmflash.h
#ifndef __STMFLASH_H__
#define __STMFLASH_H__

#include "main.h"  

//FLASH起始地址
#define STM32_FLASH_BASE 0x08000000 		//STM32 FLASH的起始地址

#define FLASH_WAITETIME 50000

extern void FLASH_PageErase(uint32_t PageAddress);
uint16_t STMFLASH_ReadHalfWord(uint32_t faddr);		  //讀出半字  
void STMFLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite);
void STMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite);		//從指定地址開始寫入指定長度的數(shù)據(jù)
void STMFLASH_Read(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead);   		//從指定地址開始讀出指定長度的數(shù)據(jù)

							   
#endif


#include "stmflash.h"



uint16_t STMFLASH_ReadHalfWord(uint32_t faddr)
{
	return *(__IO uint16_t*)faddr; 
}


void STMFLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)   
{ 			 		 
	uint16_t i;
	for(i=0;i<NumToWrite;i++)
	{
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);
	  WriteAddr+=2;		//地址增加2.
	}  
} 



#define STM_SECTOR_SIZE	2048	//大容量STM32的扇區(qū)大小為2K
		 
uint16_t STMFLASH_BUF[STM_SECTOR_SIZE/2];

void STMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)	
{
	uint32_t secpos;	   //扇區(qū)地址
	uint16_t secoff;	   //扇區(qū)內(nèi)偏移地址(16位字計(jì)算)
	uint16_t secremain; //扇區(qū)內(nèi)剩余地址(16位字計(jì)算)	   
 	uint16_t i;    
	uint32_t offaddr;   //去掉0X08000000后的地址
	
	if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*512)))return;//非法地址
	
	HAL_FLASH_Unlock();					//解鎖
	offaddr=WriteAddr-STM32_FLASH_BASE;		//實(shí)際偏移地址.
	secpos=offaddr/STM_SECTOR_SIZE;			//扇區(qū)地址  0~127 for STM32F103RBT6
	secoff=(offaddr%STM_SECTOR_SIZE)/2;		//在扇區(qū)內(nèi)的偏移(2個字節(jié)為基本單位.)
	secremain=STM_SECTOR_SIZE/2-secoff;		//扇區(qū)剩余空間大小   
	if(NumToWrite<=secremain)secremain=NumToWrite;//不大于該扇區(qū)范圍
	while(1) 
	{	
		STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//讀出整個扇區(qū)的內(nèi)容
		for(i=0;i<secremain;i++)	//校驗(yàn)數(shù)據(jù)
		{
			if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除  	  
		}
		if(i<secremain)				//需要擦除
		{
			FLASH_PageErase(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);	//擦除這個扇區(qū)
			FLASH_WaitForLastOperation(FLASH_WAITETIME);            	//等待上次操作完成
			CLEAR_BIT(FLASH->CR, FLASH_CR_PER);							//清除CR寄存器的PER位,此操作應(yīng)該在FLASH_PageErase()中完成!
																		//但是HAL庫里面并沒有做,應(yīng)該是HAL庫bug!
			for(i=0;i<secremain;i++)//復(fù)制
			{
				STMFLASH_BUF[i+secoff]=pBuffer[i];	  
			}
			STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//寫入整個扇區(qū)  
		}else 
		{
			FLASH_WaitForLastOperation(FLASH_WAITETIME);       	//等待上次操作完成
			STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//寫已經(jīng)擦除了的,直接寫入扇區(qū)剩余區(qū)間. 
		}

		if(NumToWrite==secremain)break;//寫入結(jié)束了
		else//寫入未結(jié)束
		{
			secpos++;				//扇區(qū)地址增1
			secoff=0;				//偏移位置為0 	 
		   	pBuffer+=secremain;  	//指針偏移
			WriteAddr+=secremain*2;	//寫地址偏移(16位數(shù)據(jù)地址,需要*2)	   
		   	NumToWrite-=secremain;	//字節(jié)(16位)數(shù)遞減
			if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一個扇區(qū)還是寫不完
			else secremain=NumToWrite;//下一個扇區(qū)可以寫完了
		}	 
	};	
	HAL_FLASH_Lock();		//上鎖
}



void STMFLASH_Read(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead)   	
{
	uint16_t i;
	for(i=0;i<NumToRead;i++)
	{
		pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//讀取2個字節(jié).
		ReadAddr+=2;//偏移2個字節(jié).	
	}
}

  • 在main.c文件下編寫STM32 flash測試代碼
/* USER CODE BEGIN 0 */
const uint8_t Text_Buf[] = {"STM32F103ZET6 FLASH TEST"};
#define TEXTSIZE sizeof(Text_Buf)
#define FLASH_SAVE_ADDR 0x08070000

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

///***省略***///
 /* USER CODE BEGIN WHILE */
	
	uint8_t key;
  uint8_t Read_Buf[TEXTSIZE];
	printf1("STM32 Flash Test...\r\n");
	
  while (1)
  {
		 key = KEY_Scan(0);
    if(key == 1){
        STMFLASH_Write(FLASH_SAVE_ADDR,(uint16_t *)Text_Buf,TEXTSIZE);
        printf1("FLASH Write : %s\r\n",Text_Buf);
    }

    if(key == 2){
        STMFLASH_Read(FLASH_SAVE_ADDR,(uint16_t *)Read_Buf,TEXTSIZE);
        printf1("FLASH Read : %s\r\n",Read_Buf);
    }

    HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
    HAL_Delay(200);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

5、下載驗(yàn)證

編譯無誤下載到開發(fā)板后,可以看到LED2指示燈不斷閃爍,當(dāng)按下S1按鍵后數(shù)據(jù)寫入到FLASH內(nèi),當(dāng)按下S2按鍵后將寫入的數(shù)據(jù)讀取出來,同時串口打印出相應(yīng)信息

cubemx 配置stm32內(nèi)部flash存,stm32學(xué)習(xí),stm32,學(xué)習(xí),筆記

6、參考文獻(xiàn)?

STM32CubeMX系列 | STM32內(nèi)部FLASH - 知乎 (zhihu.com)

?STM32CUBEMX-讀寫內(nèi)部Flash_stm32cubemx flash-CSDN博客

STM32CubeMX學(xué)習(xí)筆記(51)——讀寫內(nèi)部Flash_cubemx flash-CSDN博客文章來源地址http://www.zghlxwxcb.cn/news/detail-845825.html

到了這里,關(guān)于STM32CubeMX學(xué)習(xí)筆記16--- STM32內(nèi)部FLASH的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【STM32CubeMX學(xué)習(xí)】SPI讀寫W25Q16

    【STM32CubeMX學(xué)習(xí)】SPI讀寫W25Q16

    ????????SPI分為主從工作模式,通常有一個主設(shè)備和一個或多個從設(shè)備,本文中MCU為主機(jī),W25Q16為從機(jī)。 SPI通信有以下四根線: MISO:主設(shè)備數(shù)據(jù)輸入,從設(shè)備數(shù)據(jù)輸出。 MOSI:主設(shè)備數(shù)據(jù)輸出,從設(shè)備數(shù)據(jù)輸入。 SCLK:時鐘信號,由主設(shè)備產(chǎn)生。 CS:從設(shè)備片選信號,由

    2024年02月03日
    瀏覽(17)
  • STM32初學(xué)入門筆記(2):STM32CubeMX配置STM32輸出可調(diào)PWM方波

    STM32初學(xué)入門筆記(2):STM32CubeMX配置STM32輸出可調(diào)PWM方波

    PWM是一種應(yīng)用廣泛的利用微處理器的數(shù)字輸出來對模擬電路進(jìn)行控制的一種技術(shù)(即對脈沖寬度的控制)PWM同時也是驅(qū)動蜂鳴器,驅(qū)動舵機(jī),通信等重要的一環(huán),而對于初學(xué)者而言,點(diǎn)完燈的下一個程序就是驅(qū)動蜂鳴器,本篇將講述如何使用及調(diào)整PWM輸出頻率,占空比 工程文

    2024年02月14日
    瀏覽(19)
  • STM32CubeMX學(xué)習(xí)六 之ADC配置

    STM32CubeMX學(xué)習(xí)六 之ADC配置

    記錄一下STM32CubeMX的學(xué)習(xí)筆記,同時分享給初學(xué)的小白,希望一起進(jìn)步。 如何使用STM32CubeMX以及工程創(chuàng)建在之前的博客有提到,這里就直接從ADC配置講起。 編譯環(huán)境:KEIL 代碼生成:STM32CubeMX 庫:HAL MCU:STM32F072 假設(shè)你的cubeMX工程已經(jīng)建好,這里我們開始配置ADC引腳(PA1設(shè)置為

    2023年04月10日
    瀏覽(22)
  • STM32初學(xué)入門筆記(3):STM32CubeMX配置STM32實(shí)現(xiàn)多通道ADC+DMA讀取模擬量

    STM32初學(xué)入門筆記(3):STM32CubeMX配置STM32實(shí)現(xiàn)多通道ADC+DMA讀取模擬量

    模擬信號的讀取是我們在做很多項(xiàng)目是都要用到的,而模擬量的讀取就要依賴于ADC數(shù)模轉(zhuǎn)換器。對于初學(xué)者,學(xué)習(xí)使用ADC可以很大的幫助以后的STM32學(xué)習(xí)。 目錄 ADC簡介 : DMA簡介:? 工程開始: STM32CubeMX配置區(qū): 配置外部時鐘: 配置調(diào)試: 配置ADC: 配置DMA: 配置串口: 配

    2024年02月09日
    瀏覽(31)
  • STM32CubeMX學(xué)習(xí)四 之定時器配置

    STM32CubeMX學(xué)習(xí)四 之定時器配置

    記錄一下STM32CubeMX的學(xué)習(xí)筆記,同時分享給初學(xué)的小白,希望一起進(jìn)步。 如何使用STM32CubeMX以及工程創(chuàng)建在之前的博客有提到,這里就直接從定時器講起。 編譯環(huán)境:KEIL 代碼生成:STM32CubeMX 庫:HAL MCU:STM32F072 假設(shè)你的cubeMX工程已經(jīng)建好,這里我們開始配置定時器2(TIM2),

    2024年02月01日
    瀏覽(16)
  • STM32基礎(chǔ)入門學(xué)習(xí)筆記:內(nèi)部高級功能應(yīng)用

    STM32基礎(chǔ)入門學(xué)習(xí)筆記:內(nèi)部高級功能應(yīng)用

    文章目錄: 一:低功耗模式 1.睡眠模式測試程序 NVIC.h NVIC.c key.h key.c main.c 2.停機(jī)模式測試程序 main.c 3.待機(jī)模式測試程序 main.c 二:看門狗 1.獨(dú)立看門狗測試程序 iwdg.h iwdg.c main.c 2.窗口看門狗測試程序 wwdg.h wwdg.c main.c 三:TIM定時器 tim.h tim.c main.c 四:CRC循環(huán)冗余校驗(yàn)計(jì)算單元與

    2024年02月13日
    瀏覽(21)
  • STM32CubeMX學(xué)習(xí)筆記(43)——USB接口使用(CDC虛擬串口)

    STM32CubeMX學(xué)習(xí)筆記(43)——USB接口使用(CDC虛擬串口)

    USB(Universal Serial BUS)通用串行總線 ,是一個外部總線標(biāo)準(zhǔn),用于規(guī)范電腦與外部設(shè)備的連接和通訊。是應(yīng)用在 PC 領(lǐng)域的接口技術(shù)。USB 接口支持設(shè)備的即插即用和熱插拔功能。USB 是在 1994 年底由英特爾、康柏、IBM、Microsoft 等多家公司聯(lián)合提出的。 USB 發(fā)展到現(xiàn)在已經(jīng)有 US

    2024年02月02日
    瀏覽(30)
  • STM32之CubeMX學(xué)習(xí)筆記(7)SPI驅(qū)動OLED及其優(yōu)化

    STM32之CubeMX學(xué)習(xí)筆記(7)SPI驅(qū)動OLED及其優(yōu)化

    購買了邏輯分析儀后,總想著把所有的通訊信號全都看一遍。之前一篇筆記講的是串口通信,做了一些小實(shí)驗(yàn),搞清楚了如何基于底層利用串口傳一些“非標(biāo)”的數(shù)據(jù)。關(guān)于通信協(xié)議的第二篇,我想來看看SPI通信。 SPI通信是Serial peripheral interface的縮寫,中文是串行外設(shè)接口,

    2024年02月04日
    瀏覽(20)
  • STM32CubeMX學(xué)習(xí)筆記(46)——USB接口使用(HID自定義設(shè)備)

    STM32CubeMX學(xué)習(xí)筆記(46)——USB接口使用(HID自定義設(shè)備)

    USB(Universal Serial BUS)通用串行總線 ,是一個外部總線標(biāo)準(zhǔn),用于規(guī)范電腦與外部設(shè)備的連接和通訊。是應(yīng)用在 PC 領(lǐng)域的接口技術(shù)。USB 接口支持設(shè)備的即插即用和熱插拔功能。USB 是在 1994 年底由英特爾、康柏、IBM、Microsoft 等多家公司聯(lián)合提出的。 USB 發(fā)展到現(xiàn)在已經(jīng)有 US

    2024年02月14日
    瀏覽(34)
  • STM32 學(xué)習(xí)筆記(六)定時器中斷:內(nèi)部時鐘模式,外部時鐘模式

    STM32 學(xué)習(xí)筆記(六)定時器中斷:內(nèi)部時鐘模式,外部時鐘模式

    定時器是功能最強(qiáng)大,內(nèi)容最復(fù)雜的32結(jié)構(gòu)。 之前51用過的功能,定時產(chǎn)生中斷。 輸出比較,常用于產(chǎn)生 PWM 波形,驅(qū)動電機(jī)等。 輸入捕獲,測量方波頻率。 編碼器,讀取正交編碼器的波形。 最大定時時間:72M/65536/65536=中斷頻率,中斷頻率取倒數(shù)是最大定時時間。 定時器可

    2024年02月08日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包