ผมลองหาวิธีเม็มค่าลงในชิพ stm32F072 Nucleo ไปเจอจากในเน็ตมากปรับๆดู ผมสร้างฟังชั่นกดปุ่มให้มันเขียนค่าลงไป แล้วผมลอง กดรีเซ็ตที่บอร์ดเพื่อเริ่มการทำงานใหม่ มันก็จะสามารถอ่านค่าได้ตรงกับที่เม็มไว้ แต่ถ้าผมกดรีเซ็ตอีกรอบ มันก็ไม่สามารถอ่านค่าได้แล้ว ต้องกดปุ่มให้เขียนค่าอีกที ถึงจะเรียกอ่านได้อีกรอบ เพิ่งเคยลองเล่นการflash ครั้งแรก ยังไม่มีประสบการณ์เท่าไหร่ ขอคำแนะนำหน่อยครับ
Quotevoid WriteToFlash(uint16_t MemA1){
//Declare and initialize variables
//Unlock Flash
while ((FLASH->SR & FLASH_SR_BSY) != 0); //Wait until flash not busy
if ((FLASH->CR & FLASH_CR_LOCK) != 0){ //If flash is locked, do unlk seq.
FLASH->KEYR = FLASH_KEY1; //Unlock code 1
FLASH->KEYR = FLASH_KEY2; //Unlock code 2
}
//Clear Flags
FLASH->SR |= FLASH_SR_EOP; //Clear end of operation flag
FLASH->SR |= FLASH_SR_WRPRTERR; //Clear write protect error flag
FLASH->SR |= FLASH_SR_PGERR; //Clear programming error
//Erase Page before writing
FLASH->CR |= FLASH_CR_PER; //Enable flash page erase
FLASH->AR = FLASH_PAGE; //Set page to erase
FLASH->CR |= FLASH_CR_STRT; //Start erase
while ((FLASH->SR & FLASH_SR_BSY) != 0);//Wait until flash no busy
if ((FLASH->SR & FLASH_SR_EOP) != 0){ //If flash finished operation
FLASH->SR |= FLASH_SR_EOP; //Clear flag
}
FLASH->CR &= ~FLASH_CR_PER; //Disable page erase
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Write to Page
FLASH->CR |= FLASH_CR_PG; //Write 1 to PG (programming bit)
//*pPage = Temperature; //Write to flash page
*(__IO uint16_t*)(FLASH_PAGE) = MemA1; //GET HARDFAULT HERE. CODE FROM ST
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
while ((FLASH->SR & FLASH_SR_BSY) != 0); //Wait until bus is not busy
if ((FLASH->SR & FLASH_SR_EOP) != 0){ //Check if flash is completed
FLASH->SR |= FLASH_SR_EOP; //Clear flag is flash is complete
}
FLASH->CR &= ~FLASH_CR_PG; //Clear prog bit to disable write to flash
HAL_Delay(10);
}
ผมจะอ่านค่าด้วยฟังก์ชั่นนี้
Quote
uint16_t ReadFromFlash(uint16_t memAdd){
uint16_t InitTemp;
//Read value in flash
InitTemp = *((uint16_t *) (FLASH_PAGE)); //GET HARDFAULT HERE. CODE FROM ST
HAL_Delay(10);
return InitTemp;
}
เท่าที่ดู Sequence การโปรแกรม Flash ก็ถูกหมดนะครับ ขาดแค่ Lock Flash หลังจากเขียนเสร็จเอง ไม่รู้เกี่ยวรึเปล่า
หลังจากเขียน Flash เสร็จลอง Lock flash เหมือนเดิมด้วยดูครับ
QuoteFLASH->CR |= FLASH_CR_LOCK;
ปกติผมจะแยก Function เขียนกับลบออกจากกัน
Quote#define FLASH_PAGE_START_ADDRESS 0x0803F800
#define FLASH_PAGE_END_ADDRESS 0x0803FFFF
#define FLASH_PAGE_SIZE 2048
uint8_t FlashErase(void)
{
uint8_t ret = 1;
uint32_t Address;
/* Unlock the Flash to enable the flash control register access *************/
if((FLASH->CR & FLASH_CR_LOCK) != RESET)
{
/* Unlocking the program memory access */
FLASH->KEYR = FLASH_FKEY1;
FLASH->KEYR = FLASH_FKEY2;
}
/* Erase the user Flash area ***********/
/* Clear pending flags (if any) */
FLASH->SR = (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
for(Address = FLASH_PAGE_START_ADDRESS; Address < FLASH_PAGE_END_ADDRESS; Address += FLASH_PAGE_SIZE)
{
/* Wait for last operation to be completed */
while((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY);
if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00)
{
/* Write protected error */
ret = 0;
break;
}
if((FLASH->SR & (uint32_t)(FLASH_SR_PGERR)) != (uint32_t)0x00)
{
/* Programming error */
ret = 0;
break;
}
/* If the previous operation is completed, proceed to erase the page */
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = Address;
FLASH->CR |= FLASH_CR_STRT;
/* Wait for last operation to be completed */
while((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY);
if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00)
{
/* Write protected error */
ret = 0;
break;
}
if((FLASH->SR & (uint32_t)(FLASH_SR_PGERR)) != (uint32_t)0x00)
{
/* Programming error */
ret = 0;
break;
}
/* Disable the PER Bit */
FLASH->CR &= ~FLASH_CR_PER;
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
/* Set the LOCK Bit to lock the FLASH control register and program memory access */
FLASH->CR |= FLASH_CR_LOCK;
return ret;
}
Quoteuint8_t FlashWrite(uint32_t Address, uint8_t *Data, uint32_t Length)
{
uint8_t ret = 1;
uint16_t TmpData;
if(Address >= FLASH_PAGE_START_ADDRESS && Address <= FLASH_PAGE_END_ADDRESS)
{
/* Unlock the Flash to enable the flash control register access *************/
if((FLASH->CR & FLASH_CR_LOCK) != RESET)
{
/* Unlocking the program memory access */
FLASH->KEYR = FLASH_FKEY1;
FLASH->KEYR = FLASH_FKEY2;
}
/* Clear pending flags (if any) */
FLASH->SR = (FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
while(Length > 0)
{
if(Length == 1)
{
TmpData = Data[0] | (0x00 << 8 );
Data = Data + 1;
Length = Length - 1;
}
else
{
TmpData = Data[0] | (Data[1] << 8 );
Data = Data + 2;
Length = Length - 2;
}
/* Wait for last operation to be completed */
while((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY);
if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00)
{
/* Write protected error */
ret = 0;
break;
}
if((FLASH->SR & (uint32_t)(FLASH_SR_PGERR)) != (uint32_t)0x00)
{
/* Programming error */
ret = 0;
break;
}
/* If the previous operation is completed, proceed to program the new data */
FLASH->CR |= FLASH_CR_PG;
*(__IO uint16_t*)Address = TmpData;
/* Wait for last operation to be completed */
while((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY);
if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00)
{
/* Write protected error */
ret = 0;
break;
}
if((FLASH->SR & (uint32_t)(FLASH_SR_PGERR)) != (uint32_t)0x00)
{
/* Programming error */
ret = 0;
break;
}
/* Disable the PG Bit */
FLASH->CR &= ~FLASH_CR_PG;
/* Next address */
Address = Address + 2;
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
/* Set the LOCK Bit to lock the FLASH control register and program memory access */
FLASH->CR |= FLASH_CR_LOCK;
}
else
ret = 0;
return ret;
}
อืม ถ้ามัน Flash สำเร็จแล้ว
อ่านหลังจากนั้น มันก็ต้องได้ค่านั้นนะ
เข้ามา งง @_@! เหมือนกัน
ผมใช้ HAL Library ที่มากับ CubeMX
โค้ดสั้นดี แต่ก็ read-write flash ได้ปกติครับ
แต่ เวลาผมอ่าน ผมใช้ pointer
ชี้ไปที่ addredd นั้นๆ เลย
และเวลา DBG ก็ดู Memory เอาอ่ะ
ไม่ก็ สร้างตัวแปร มารับ pointer ของ address นั้นๆ
ค่อยๆ วิเคราะห์ครับ เดี๋ยวก็คงหาเจอ
อ้อ ผมใช้ 32F051 กับ 32F103 อ่ะ คนละตัวกันกับ จขกท
^_^!
ลองใช้ HAL library ไหมครับ สะดวกดีนะครับ มี Reference manual มาให้ด้วยจาก st ครับ