/*************************************************************************************/ // Set according to your needs #define STM32_FLASH_SIZE 64 // FLASH capacity of the selected MCU (unit is K) #define STM32_FLASH_WREN 1 // Enable FLASH write (0, disable; 1, enable)
/** * @brief Read the half word (16-bit data) of the specified address. * @param faddr: read address (this address must be a multiple of 2 !!). * @retval Corresponding data. */ staticuint16_tSTMFLASH_ReadHalfWord(uint32_t faddr) { return *(vu16*)faddr; }
// A sector size is (SECTOR_SIZE) bytes, // A uint16_t type data is 2 bytes, // So a sector can hold a maximum of (SECTOR_SIZE/2) uint16_t type data. uint16_t STMFLASH_BUF[SECTOR_SIZE/2];
/** * @brief Write data of specified length from the specified address. * @param WriteAddr: Start address(this address must be a multiple of 2 !!). * @param pBuffer: data pointer. * @param NumToWrite: Halfword (16-bit) number. * @retval None. */ voidSTMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite) { uint16_t i; uint32_t secpos; // Sector address uint16_t secoff; // Intra-sector offset address (16-bit word calculation) uint16_t secremain; // Remaining address in the sector (16-bit word calculation) uint32_t offaddr; // Remove the address after 0X08000000
FLASH_Unlock(); // Unlock flash offaddr = WriteAddr-STM32_FLASH_BASE; // Actual offset address. secpos = offaddr/SECTOR_SIZE; // Sector address 0 ~ 63 for STM32F103C8T6 secoff = (offaddr%SECTOR_SIZE)/2; // Offset within the sector (2 bytes as the basic unit) secremain = SECTOR_SIZE/2-secoff; // Sector remaining space if(NumToWrite <= secremain) // Not greater than the sector range secremain = NumToWrite;
while(1) { STMFLASH_Read(secpos*SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,SECTOR_SIZE/2); // Read the entire sector for(i=0;i<secremain;i++) // Check data { if(STMFLASH_BUF[secoff+i] != 0XFFFF) break; // Need to erase }
if(i < secremain) // Need to erase { FLASH_ErasePage(secpos*SECTOR_SIZE+STM32_FLASH_BASE); // Erase this sector for(i=0;i<secremain;i++) // Copy data { STMFLASH_BUF[i+secoff] = pBuffer[i]; } // Write entire sector STMFLASH_Write_NoCheck(secpos*SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,SECTOR_SIZE/2); } else// If it has been erased, it is directly written into the remaining sector. STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);
if(NumToWrite == secremain) // Writing is complete break; else// Writing is not complete { secpos++; // Sector address increased by 1 secoff = 0; // Offset position is 0 pBuffer += secremain; // Pointer offset WriteAddr += secremain; // Write address offset NumToWrite -= secremain;// Decrement the number of bytes (16 bits) if(NumToWrite > (SECTOR_SIZE/2))// Data cannot be written in the next sector secremain = SECTOR_SIZE/2; else// Data can be written in the next sector secremain = NumToWrite; } }; FLASH_Lock(); // Lock flash } #endif
/** * @brief Read data of specified length from specified address. * @param ReadAddr: Start address(this address must be a multiple of 2 !!). * @param pBuffer: data pointer. * @param NumToWrite: Halfword (16-bit) number. * @retval None. */ voidSTMFLASH_Read(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead) { uint16_t i; for(i=0;i<NumToRead;i++) { pBuffer[i] = STMFLASH_ReadHalfWord(ReadAddr); // Read 2 bytes. ReadAddr += 2; // Offset 2 bytes. } }
/* Configure the Rx pin for the alternate function */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
/* Configure the serial port to receive interrupts. */ NVIC_Configuration();
/* Enable serial port receive interrupt */ USART_ITConfig(DEBUG_USART, USART_IT_RXNE, ENABLE);
/* Enable serial */ USART_Cmd(DEBUG_USART, ENABLE); }
/***************** Send a character **********************/ voidUsart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* Send a byte of data to the USART */ USART_SendData(pUSARTx,ch);
/* Waiting for the transmit data register to be empty */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); }
/* Waiting for transmission to complete */ while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {} }
/***************** Send a 16-digit number **********************/ voidUsart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch) { uint8_t temp_h, temp_l;
/* Take out the high eight */ temp_h = (ch&0XFF00)>>8; /* Take the lower eight */ temp_l = ch&0XFF;
/* Send high eight */ USART_SendData(pUSARTx,temp_h); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
/* Send the lower eight digits */ USART_SendData(pUSARTx,temp_l); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); }
/* Redirect the c library function printf to the serial port, use the printf function after redirection. */ intfputc(int ch, FILE *f) { /* Send a byte of data to the serial port */ USART_SendData(DEBUG_USART, (uint8_t) ch);
/* Waiting to send */ while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);
return (ch); }
/* Redirect the c library function scanf to the serial port, rewrite backwards can use scanf, getchar and other functions. */ intfgetc(FILE *f) { /* Waiting for serial input data */ while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USART); } /*********************************************END OF FILE*********************************************/
printf("initialization successful.\n"); printf("Press the 'r' to Read data from flash.\n"); printf("Press the 'w' to write data to flash.\n"); printf("\n-------------------------------------------------\n\n");
while(1) { if(flag == 1) // Read data from flash { flag = 0; printf("Read data from flash:\n");
STMFLASH_Read(FLASH_SAVE_ADDR,Text_Buffer,ARRAY_SIZE); for(i=0;i<ARRAY_SIZE;i++) printf("Text_Buffer[%d]: %d\n",i,Text_Buffer[i]); printf("\n-------------------------------------------------\n\n"); } elseif(flag == 2) // Write data to flash { flag = 0; printf("Start write data to flash.\n"); STMFLASH_Write(FLASH_SAVE_ADDR,Data_Buffer,ARRAY_SIZE); printf("Write Finish.\n"); printf("\n-------------------------------------------------\n\n"); } } }
/*********************************************END OF FILE*********************************************/