Giỏ hàng
Danh mục sản phẩm

Lập Trình FLASH EEPROM Arduino STM32H7

Đăng bởi Trần Văn Bùi ngày bình luận

Hôm nay mình giới thiệu các bạn lập trình Flash STM32H7

Mục đích lưu dữ liệu khi mất điện giống EEPROM

FLASH STM32H743ZIT6 Tới 2M Flash

Các bạn có thể ghi các ô nhớ còn lại từ 250Kbyte đến 2M 

Sơ qua về Sơ đồ trên STM32H7 

Về chương trình :

#include "stm32h7xx.h"
#include "core_cm7.h"
#include "stm32h7xx_hal.h"

//
/*
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO¿ÚµØÖ·Ó³Éä
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14    
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010 
 
//IO¿Ú²Ù×÷,Ö»¶Ôµ¥Ò»µÄIO¿Ú!
//È·±£nµÄֵСÓÚ16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //Êä³ö 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //ÊäÈë 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //Êä³ö 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //ÊäÈë 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //Êä³ö 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //ÊäÈë 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //Êä³ö 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //ÊäÈë 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //Êä³ö 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //ÊäÈë

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //Êä³ö 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //ÊäÈë

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //Êä³ö 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //ÊäÈë

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //Êä³ö 
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //ÊäÈë

#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //Êä³ö 
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //ÊäÈë

 
//IO ho?t d?ng , ch? có m?t IO duy nh?t!
//giá tr? n bé hon 16!
//PAout(0); //PA0 ngõ ra
//PAin(2) ; // PA2 ngõ vào
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  // ngõ ra
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  // ngõ vào

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)   
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)   

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)   
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)   
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)   

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)   
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)   
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n) 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  

#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //ngõ ra 
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //ngõ vào
*/

#define FLASH_SAVE_ADDR  0X08020000 

typedef int32_t  s32;
typedef int16_t s16;
typedef int8_t  s8;

typedef const int32_t sc32;  
typedef const int16_t sc16;  
typedef const int8_t sc8;  

typedef __IO int32_t  vs32;
typedef __IO int16_t  vs16;
typedef __IO int8_t   vs8;

typedef __I int32_t vsc32;  
typedef __I int16_t vsc16; 
typedef __I int8_t vsc8;   

typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;

typedef const uint32_t uc32;  
typedef const uint16_t uc16;  
typedef const uint8_t uc8; 

typedef __IO uint32_t  vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t  vu8;

typedef __I uint32_t vuc32;  
typedef __I uint16_t vuc16; 
typedef __I uint8_t vuc8; 
#define STM32_FLASH_BASE 0x08000000   //STM32 FLASHµÄÆðʼµØÖ·
#define FLASH_WAITETIME  50000          //FLASHµÈ´ý³¬Ê±Ê±¼ä
u32 Data_save[10]={123,123,123,12,44,55,66,77,88,99};
u32 Data_save1[10];
//STM32H7 FLASH ÉÈÇøµÄÆðʼµØÖ·
//BANK1
#define ADDR_FLASH_SECTOR_0_BANK1     ((uint32_t)0x08000000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_1_BANK1     ((uint32_t)0x08020000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_2_BANK1     ((uint32_t)0x08040000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_3_BANK1     ((uint32_t)0x08060000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_4_BANK1     ((uint32_t)0x08080000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_5_BANK1     ((uint32_t)0x080A0000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_6_BANK1     ((uint32_t)0x080C0000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_7_BANK1     ((uint32_t)0x080E0000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  

//BANK2
#define ADDR_FLASH_SECTOR_0_BANK2     ((uint32_t)0x08100000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_1_BANK2     ((uint32_t)0x08120000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_2_BANK2     ((uint32_t)0x08140000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_3_BANK2     ((uint32_t)0x08160000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_4_BANK2     ((uint32_t)0x08180000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_5_BANK2     ((uint32_t)0x081A0000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_6_BANK2     ((uint32_t)0x081C0000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
#define ADDR_FLASH_SECTOR_7_BANK2     ((uint32_t)0x081E0000) //ÉÈÇø0ÆðʼµØÖ·, 128 Kbytes  
u32 STMFLASH_ReadWord(u32 faddr)
{
  return *(__IO uint32_t *)faddr; 
}
uint16_t STMFLASH_GetFlashSector(u32 addr)
{
  if(addr<ADDR_FLASH_SECTOR_1_BANK1)return FLASH_SECTOR_0;
  else if(addr<ADDR_FLASH_SECTOR_2_BANK1)return FLASH_SECTOR_1;
  else if(addr<ADDR_FLASH_SECTOR_3_BANK1)return FLASH_SECTOR_2;
  else if(addr<ADDR_FLASH_SECTOR_4_BANK1)return FLASH_SECTOR_3;
  else if(addr<ADDR_FLASH_SECTOR_5_BANK1)return FLASH_SECTOR_4;
  else if(addr<ADDR_FLASH_SECTOR_6_BANK1)return FLASH_SECTOR_5;
  else if(addr<ADDR_FLASH_SECTOR_7_BANK1)return FLASH_SECTOR_6;
  return FLASH_SECTOR_7;  
}
void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)  

    FLASH_EraseInitTypeDef FlashEraseInit;
    HAL_StatusTypeDef FlashStatus=HAL_OK;
    u32 SectorError=0;
  u32 addrx=0;
  u32 endaddr=0;  
    if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;  //·Ç·¨µØÖ·
    
  HAL_FLASH_Unlock();             //½âËø  
  addrx=WriteAddr;        //дÈëµÄÆðʼµØÖ·
  endaddr=WriteAddr+NumToWrite*4; //дÈëµÄ½áÊøµØÖ·
    
    if(addrx<0X1FF00000)
    {
        while(addrx<endaddr)    //ɨÇåÒ»ÇÐÕÏ°­.(¶Ô·ÇFFFFFFFFµÄµØ·½,ÏȲÁ³ý)
    {
      if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//ÓзÇ0XFFFFFFFFµÄµØ·½,Òª²Á³ýÕâ¸öÉÈÇø
      {   
        FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //²Á³ýÀàÐÍ£¬ÉÈÇø²Á³ý 
        FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx);   //Òª²Á³ýµÄÉÈÇø
        FlashEraseInit.Banks=FLASH_BANK_1;            //²Ù×÷BANK1
                FlashEraseInit.NbSectors=1;                             //Ò»´ÎÖ»²Á³ýÒ»¸öÉÈÇø
                FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //µçѹ·¶Î§£¬VCC=2.7~3.6VÖ®¼ä!!
                if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK) 
                {
                    break;//·¢Éú´íÎóÁË  
                }
                SCB_CleanInvalidateDCache();                            //Çå³ýÎÞЧµÄD-Cache
      }else addrx+=4;
            FLASH_WaitForLastOperation(FLASH_WAITETIME,FLASH_BANK_1);    //µÈ´ýÉϴβÙ×÷Íê³É
        }
    }
    FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME,FLASH_BANK_1);       //µÈ´ýÉϴβÙ×÷Íê³É
  if(FlashStatus==HAL_OK)
  {
    while(WriteAddr<endaddr)//дÊý¾Ý
    {
            if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,WriteAddr,(uint64_t)pBuffer)!=HAL_OK)//дÈëÊý¾Ý
      { 
        break;  //дÈëÒì³£
      }
      WriteAddr+=32;
      pBuffer+=8;
    } 
  }
  HAL_FLASH_Lock();           //ÉÏËø

//´ÓÖ¸¶¨µØÖ·¿ªÊ¼¶Á³öÖ¸¶¨³¤¶ÈµÄÊý¾Ý
//ReadAddr:ÆðʼµØÖ·
//pBuffer:Êý¾ÝÖ¸Õë
//NumToRead:×Ö(32λ)Êý
void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)     
{
  u32 i;
  for(i=0;i<NumToRead;i++)
  {
    pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//¶ÁÈ¡4¸ö×Ö½Ú.
    ReadAddr+=4;//Æ«ÒÆ4¸ö×Ö½Ú.  
  }
}
void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOE_CLK_ENABLE();          //¿ªÆôGPIOBʱÖÓ
  
    GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3;     //PB0£¬1
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;      //ÍÆÍìÊä³ö
    GPIO_Initure.Pull=GPIO_PULLUP;              //ÉÏÀ­
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;   //¸ßËÙ
    HAL_GPIO_Init(GPIOE,&GPIO_Initure);         //³õʼ»¯GPIOB.0ºÍGPIOB.1
  
    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET); //PB0ÖÃ0
    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_SET); //PB1ÖÃ1 
}
#define PEout(n)       (n?HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET))
int i_cnt=0;
void setup() {
    pinMode(PE2, OUTPUT);
   // LED_Init();
   Serial.begin(9600);
  // put your setup code here, to run once:
//  STMFLASH_Write(FLASH_SAVE_ADDR,Data_save,10);
  STMFLASH_Read(FLASH_SAVE_ADDR,Data_save1,10);
  for(i_cnt=0;i_cnt<10;i_cnt++)
   {
    Serial.println(Data_save1[i_cnt]);
    }
  

}

void loop() {
   //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET); delay(1000);
  //  HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET); delay(1000);
 PEout(1);delay(100); PEout(0);delay(100);
// PEout(2)=1;delay(100); PEout(2)=0;delay(100);
  // put your main code here, to run repeatedly:

}

Chương trình có thể chạy Trên Nhân Arduino hoặc Keilc các bạn nhé 

Cảm ơn các bạn đã ghé thăm shop .

 


Cũ hơn Mới hơn