STM32

您所在的位置:网站首页 flash句子 STM32

STM32

2024-07-12 20:17| 来源: 网络整理| 查看: 265

本文记录了对一些知识点的理解、操作方法,如有错误,请务必批评指正!!

最终的测试截图:

目录​ 

一、内部FLASH要点

关于地址:

关于解锁:

关于擦除:

关于写入:

二、读取数据

三、存储数据

四、应用示例

一、内部FLASH要点

关于地址: 内部FLASH地址开始地址:0x0800 0000;结束地址:0x08000000+FLASH大小FLASH的大小,可根据芯片型号得知,如F103x8=64K,  F103xC=256K, F103xE=512KFLASH的大小,也可读*(uint16_t*)0x1FFFF7E0直接获得; 关于解锁: 对FLASH寄存器的操作, 需要在操作之前解锁;如果解锁过程发生错误,FLASH寄存器操作将死锁至掉电;解锁步骤(1): FLASH->KEYR= (uint32_t)0x45670123;解锁步骤(2): FLASH->KEYR= (uint32_t)0xCDEF89AB; 关于擦除: 内部FLASH空间,按页划分成连续的数据块;每次擦除的最小单位是:页;F103中,中小容量FLASH的页(扇区)大小为1K, 而大容量的页大小为2K每页擦除时长:中小容量约30ms, 大容量约50ms页寿命:中小容量约可擦: 1K次, 大容量约可擦: 10K次擦除步骤(1):FLASH->CR|= 1CR|= 0x40;             // 开始擦除擦除步骤(4):while((FLASH->SR & 0x01); // 等待空闲,即BSY=0 关于写入: 写入的地址,必须是偶数;每一次写入,必须以半字进行(uint16_t)!单字节或全字将发生错误;写入步骤(1):  FLASH->CR |= 0x01CR &= ((uint32_t)0x00001FFE);  // 关闭编程 二、读取数据 可以按byte读取,也可以按半字、全字方式读取;读取的方式很简单,如:short value = *(uint16_t*)readAddr;

下面的读取函数,经多次完善,按字节读取,方便匹配奇数数量的数据读取;

/****************************************************************************** * 函 数: System_ReadInteriorFlash * 功 能: 在芯片的内部FLASH里,读取指定长度数据 * 参 数: uint32_t readAddr 数据地址 * uint8_t *pBuffer 读出后存放位置 * uint16_t numToRead 读取的字节数量 * 返回值: 0_成功 1_失败,地址小于FLASH基址 2_失败,地址大于FLASH最大值 ******************************************************************************/ uint8_t System_ReadInteriorFlash (uint32_t readAddr, uint8_t *pBuffer, uint16_t numToRead) { // 获取芯片FLASH大小 uint16_t flashSize = *(uint16_t*)(0x1FFFF7E0); // 读取芯片FLASH大小;本寄存器值为芯片出厂前写入的FLASH大小,只读单位:KByte // 判断地址有效性 if(readAddr < STM32_FLASH_ADDR_BASE) return 1; // 如果读的地址,小于FLASH的最小地址,则退出 if(readAddr > (STM32_FLASH_ADDR_BASE+(flashSize*1024))) return 2; // 如果读的地址,超出FLASH的最大地址,则退出 // 开始复制 while(numToRead--){ *pBuffer = *(__IO uint8_t*)readAddr; pBuffer++; // 指针后移一个数据长度 readAddr++; // 偏移一个数据位 } return 0; // 成功,返回0; } 三、存储数据

1:在存储函数前,需要三个数据的定义:

// 下面这三个定义,用于存取内部FLASH数据,F103系列都不用修改 #ifdef STM32F10X_HD #define STM32_FLASH_SECTOR_SIZE 2048 // 内部FLASH页大小, 单位:bytes  (注:STM32F10xx系列下,小中容量存储器扇区为1K, 大容量存储器扇区为2K) #else #define STM32_FLASH_SECTOR_SIZE 1024     // 内部FLASH页大小, 单位:bytes  (注:STM32F10xx系列下,小中容量存储器扇区为1K, 大容量存储器扇区为2K) #endif #define STM32_FLASH_ADDR_BASE 0x08000000 // 芯片内部FLASH基址(这个基本不用修改) static uint8_t sectorbufferTemp[STM32_FLASH_SECTOR_SIZE]; // 开辟一段内存空间,作用:在内部FLASH写入时作数据缓冲

2:等待空闲的函数:

// 作用:内部FLASH写入时,等待空闲,BSY位标志:0闲1忙 static uint8_t waitForFlashBSY(uint32_t timeOut) { while((FLASH->SR & 0x01) && (timeOut-- != 0x00)) ; // 等待BSY标志空闲 if(timeOut ==0) return 1; // 失败,返回1, 等待超时;  return 0; // 正常,返回0 }

3:完整可用的存储函数:

/****************************************************************************** * 函 数: System_WriteInteriorFlash * 功 能: 在芯片的内部FLASH里,写入指定长度数据 * 参 数: uint32_t writeAddr 写入地址,重要:写入地址必须是偶数!!! * uint8_t *writeToBuffer * uint16_t numToWrite * * 返回值: 0_成功, * 1_失败,地址范围不正确 * 2_失败,FLASH->SR:BSY忙超时 * 3_失败,擦除超时 ******************************************************************************/ uint8_t System_WriteInteriorFlash(uint32_t writeAddr, uint8_t *writeToBuffer, uint16_t numToWrite) { uint16_t flashSize = *(uint16_t*)(0x1FFFF7E0); // 读取芯片FLASH大小;本寄存器值为芯片出厂前写入的FLASH大小,只读,单位:KByte uint32_t addrOff = writeAddr - STM32_FLASH_ADDR_BASE; // 去掉0x08000000后的实际偏移地址 uint32_t secPos = addrOff / STM32_FLASH_SECTOR_SIZE;; // 扇区地址,即起始地址在第几个扇区 uint16_t secOff = addrOff%STM32_FLASH_SECTOR_SIZE ; // 开始地始偏移字节数: 数据在扇区的第几字节存放 uint16_t secRemain = STM32_FLASH_SECTOR_SIZE - secOff; // 本扇区需要写入的字节数 ,用于判断够不够存放余下的数据 // 判断地址有效性 if(writeAddr < STM32_FLASH_ADDR_BASE) return 1; // 如果读的地址,小于FLASH的最小地址,则退出,返回1_地址失败 if(writeAddr > (STM32_FLASH_ADDR_BASE+(flashSize*1024))) return 1; // 如果读的地址,超出FLASH的最大地址,则退出, 返回1_地址失败 // 0_解锁FLASH FLASH->KEYR = ((uint32_t)0x45670123); FLASH->KEYR = ((uint32_t)0xCDEF89AB); if(numToWrite SR:BSY忙超时 System_ReadInteriorFlash ( secPos*STM32_FLASH_SECTOR_SIZE+STM32_FLASH_ADDR_BASE , sectorbufferTemp, STM32_FLASH_SECTOR_SIZE ); // 读取扇区内容到缓存 // 2_擦险指定页(扇区) if(waitForFlashBSY(0x00888888)) return 2; // 失败,返回:2, 失败原因:FLASH->SR:BSY忙超时 FLASH->CR|= 1CR|= 0x40; // STRT:写1时触发一次擦除运作  if(waitForFlashBSY(0x00888888)) return 2; // 失败,返回:3, 失败原因:擦除超时 FLASH->CR &= ((uint32_t)0x00001FFD); // 关闭页擦除功能 for(uint16_t i=0; iCR |= 0x01CR |= 1


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3