CH32F103C8T6修改HAL库实现内部FLASH快速读写

发布时间 2023-07-26 09:39:08作者: SymPny

1、在stm32f103xe.h 文件中,在FLASH_TypeDef 结构体中,增加MODEKEYR 成员定义。
修改后如下图所示:

2、目前CH32F103 的FLASH 最大为64K,在chflash.c文件中,修改ValidAddrEnd。
修改后如下图所示:

注:大容量芯片可以相应修改ValidAddrEnd的“0x10000”数据即可

3、上述步骤完成后,即可执行单次128字节的编程,编写Flash_Test_Fast()函数,测试单次128字节编程。

备注:
chflash.c文件

  
#include "chflash.h"
#include "delay.h"
#include "usart.h"

define ACR_LATENCY_Mask ((uint32_t)0x00000038)

define ACR_HLFCYA_Mask ((uint32_t)0xFFFFFFF7)

define ACR_PRFTBE_Mask ((uint32_t)0xFFFFFFEF)

/* Flash Access Control Register bits */

define ACR_PRFTBS_Mask ((uint32_t)0x00000020)

/* Flash Control Register bits */

define CR_PG_Set ((uint32_t)0x00000001)

define CR_PG_Reset ((uint32_t)0x00001FFE)

define CR_PER_Set ((uint32_t)0x00000002)

define CR_PER_Reset ((uint32_t)0x00001FFD)

define CR_MER_Set ((uint32_t)0x00000004)

define CR_MER_Reset ((uint32_t)0x00001FFB)

define CR_OPTPG_Set ((uint32_t)0x00000010)

define CR_OPTPG_Reset ((uint32_t)0x00001FEF)

define CR_OPTER_Set ((uint32_t)0x00000020)

define CR_OPTER_Reset ((uint32_t)0x00001FDF)

define CR_STRT_Set ((uint32_t)0x00000040)

define CR_LOCK_Set ((uint32_t)0x00000080)

define CR_PAGE_PG ((uint32_t)0x00010000)

define CR_PAGE_ER ((uint32_t)0x00020000)

define CR_BUF_LOAD ((uint32_t)0x00040000)

define CR_BUF_RST ((uint32_t)0x00080000)

/* FLASH Status Register bits */

define SR_BSY ((uint32_t)0x00000001)

define SR_PGERR ((uint32_t)0x00000004)

define SR_WRPRTERR ((uint32_t)0x00000010)

define SR_EOP ((uint32_t)0x00000020)

/* FLASH Mask */

define RDPRT_Mask ((uint32_t)0x00000002)

define WRP0_Mask ((uint32_t)0x000000FF)

define WRP1_Mask ((uint32_t)0x0000FF00)

define WRP2_Mask ((uint32_t)0x00FF0000)

define WRP3_Mask ((uint32_t)0xFF000000)

define OB_USER_BFB2 ((uint16_t)0x0008)

/* FLASH Keys */

define RDP_Key ((uint16_t)0x00A5)

//#define FLASH_KEY1 ((uint32_t)0x45670123)
//#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)

/* FLASH BANK address */

define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF)

/* Delay definition */

define EraseTimeout ((uint32_t)0x000B0000)

define ProgramTimeout ((uint32_t)0x00002000)

/* Flash Program Vaild Address */

define ValidAddrStart (FLASH_BASE)

define ValidAddrEnd (FLASH_BASE + 0x10000)

/*********************************************************************

  • @fn FLASH_Unlock_Fast

  • @brief Unlocks the Fast Program Erase Mode.

  • @return none
    /
    void FLASH_Unlock_Fast( void )
    {
    /
    Authorize the FPEC of Bank1 Access */
    FLASH->KEYR = FLASH_KEY1;
    FLASH->KEYR = FLASH_KEY2;

    /* Fast program mode unlock */
    FLASH->MODEKEYR = FLASH_KEY1;
    FLASH->MODEKEYR = FLASH_KEY2;
    }

/*********************************************************************

  • @fn FLASH_Lock_Fast
  • @brief Locks the Fast Program Erase Mode.
  • @return none
    */
    void FLASH_Lock_Fast( void )
    {
    FLASH->CR |= CR_LOCK_Set;
    }

/*********************************************************************

  • @fn FLASH_Unlock_Fast
  • @brief Unlocks the Fast Program Erase Mode.
  • @return none
    */
    void FLASH_BufReset( void )
    {
    FLASH->CR |= CR_PAGE_PG;
    FLASH->CR |= CR_BUF_RST;
    while( FLASH->SR & SR_BSY );
    FLASH->CR &= ~CR_PAGE_PG;
    }

/*********************************************************************

  • @fn FLASH_BufLoad

  • @brief Flash Buffer load(128 bit).

  • @param Address - specifies the address to be programmed.

  •      Data0 - specifies the data0 to be programmed.
    
  •      Data1 - specifies the data1 to be programmed.
    
  •      Data2 - specifies the data2 to be programmed.
    
  •      Data3 - specifies the data3 to be programmed.
    
  • @return none
    */
    void FLASH_BufLoad( uint32_t Address, uint32_t Data0, uint32_t Data1, uint32_t Data2, uint32_t Data3 )
    {
    if( ( Address >= ValidAddrStart ) && ( Address < ValidAddrEnd ) )
    {
    FLASH->CR |= CR_PAGE_PG;
    *( __IO uint32_t * )( Address + 0x00 ) = Data0;
    *( __IO uint32_t * )( Address + 0x04 ) = Data1;
    *( __IO uint32_t * )( Address + 0x08 ) = Data2;
    *( __IO uint32_t * )( Address + 0x0C ) = Data3;
    FLASH->CR |= CR_BUF_LOAD;
    while( FLASH->SR & SR_BSY );
    FLASH->CR &= ~CR_PAGE_PG;

     *( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Address ^ 0x00000100 );
    

    }
    }

/*********************************************************************

  • @fn FLASH_ErasePage_Fast

  • @brief Erases a specified FLASH page (1page = 256Byte).

  • @param Page_Address - The page address to be erased.

  • @return none
    */
    void FLASH_ErasePage_Fast( uint32_t Page_Address )
    {
    if( ( Page_Address >= ValidAddrStart ) && ( Page_Address < ValidAddrEnd ) )
    {
    FLASH->CR |= CR_PAGE_ER;
    FLASH->AR = Page_Address;
    FLASH->CR |= CR_STRT_Set;
    while( FLASH->SR & SR_BSY );
    FLASH->CR &= ~CR_PAGE_ER;

     *( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Page_Address ^ 0x00000100 );
    

    }
    }

/*********************************************************************

  • @fn FLASH_ProgramPage_Fast

  • @brief Program a specified FLASH page (1page = 256Byte).

  • @param Page_Address - The page address to be programed.

  • @return none
    */
    void FLASH_ProgramPage_Fast( uint32_t Page_Address )
    {
    if( ( Page_Address >= ValidAddrStart ) && ( Page_Address < ValidAddrEnd ) )
    {
    FLASH->CR |= CR_PAGE_PG;
    FLASH->AR = Page_Address;
    FLASH->CR |= CR_STRT_Set;
    while( FLASH->SR & SR_BSY );
    FLASH->CR &= ~CR_PAGE_PG;

     *( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Page_Address ^ 0x00000100 );
    

    }
    }

chflash.h文件

    
#ifndef __CHFLASH_H__
#define __CHFLASH_H__
#include "sys.h"  

define FLASH_SAVE_ADDR 0x0800FC00 //ÉèÖÃFLASH ±£´æµØÖ·(±ØÐëΪżÊý£¬ÇÒÆäÖµÒª´óÓÚ±¾´úÂëËùÕ¼ÓÃFLASHµÄ´óС+0X08000000)

void Flash_Test_Fast( void );

endif