使用方法
直接修改以下宏以匹配不同芯片即可
1 2 3 4 |
#define MAX_SIZE 40960 // 定义总共 40K的FLASH做为EEPROM用,必须为PAGE_SIZE的整数倍 #define PAGE_SIZE 2048 // MD器件 1KB为1页 CL与HD为2KB #define ADDR_OFFSET (0x8000000+0x40000-MAX_SIZE) // STM32 flash起始地址+总大小需要写的大小,需要注意的是不同芯片不一样 |
程序代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
/******************** (C) COPYRIGHT 2014 ************************************** * Author : Justchen * Version : V1.0 * Date : 2017.02.07 * Description : STM32F10X Flash读写API,支持夸页读写,无需字节对齐 ********************************************************************************/ #include "stm32f10x.h" #define MAX_SIZE 40960 // 定义总共 40K的FLASH做为EEPROM用,必须为PAGE_SIZE的整数倍 #define PAGE_SIZE 2048 // MD器件 1KB为1页 CL与HD为2KB #define ADDR_OFFSET (0x8000000+0x40000-MAX_SIZE) // STM32 flash起始地址+总大小需要写的大小,需要注意的是不同芯片不一样 /**--------------------------------------------------------------------------------- * @brief FLASH读出函数 * @param 地址 --------------------------------------------------------------------------------*/ u8 FLASH_READ( u32 addr) { u8 *pointer; pointer = (u8*)ADDR_OFFSET; return pointer[addr]; } /**--------------------------------------------------------------------------------- * @brief FLASH读出函数 * @param 地址 --------------------------------------------------------------------------------*/ void FLASH_READBUFF( u32 addr, u16 num, u8 *data) { u16 i; for( i=0; i<num; i++ ) { data[i] = FLASH_READ(addr+i); } } /**--------------------------------------------------------------------------------- * @brief FLASH写入必不可少步骤 * @param 地址, 数量, buff --------------------------------------------------------------------------------*/ void FLASH_WRITE( u32 addr, u16 num, u8 *data ) { u32 pageAddr; u8 buff [PAGE_SIZE]; u8 *pointer; u16 i; u16 *p; u16 pageWriteLen; u16 writeLen; u16 totalWriteLen = 0; RCC_HSICmd(ENABLE); FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR); while(1) { pageAddr = ADDR_OFFSET + addr - addr%PAGE_SIZE; // 页地址 pageWriteLen = PAGE_SIZE - addr%PAGE_SIZE; // 当前页最大可写入字节数 pointer = (u8*)pageAddr; for( i=0; i<PAGE_SIZE; i++) // 先读出当前页数据保存到buff buff[i] = pointer[i]; if( num > pageWriteLen ) // 计算本次可写入的字节数 writeLen = pageWriteLen; else writeLen = num; for( i=0; i<writeLen; i++) // 数据先写到buff中 buff[ (addr%PAGE_SIZE)+i ] = data[totalWriteLen+i]; FLASH_ErasePage(pageAddr); // 擦出数据 p = (u16*)&buff[0]; for( i=0; i<(PAGE_SIZE/2); i++ ) // 写入数据 FLASH_ProgramHalfWord( pageAddr + i*2, p[i] ); totalWriteLen += writeLen; num -= writeLen; addr += writeLen; if( 0 == num ) break; // 数据写完 } FLASH_Lock(); RCC_HSICmd(DISABLE); } |