复旦微FM33LC046N评测+FLASH存储
[复制链接]
一、概述
1、FLASH容量64K * 32=256K
页---page(512B)
扇区--sector(2K)
2、支持页擦除,扇区擦除,全擦(仅支持SWD程序下载模式)
3、flash内存
大小:256k
范围:0x00000000 -- 0x00040000
Flash 扇区(Sector)大小为 512 字节,每 16 个扇区组成一个 8K 字节的块(Block)。
Flash 包含 4 个 information 扇区, 2 个 LDT 扇区, 1 个冗余扇区, 1 个DCT 扇区。其中 DCT 和 LDT为芯片原厂保留扇区,不对用户开放。Information 为用户配置扇区,用于保存用户配置信息。所有
option 扇区在地址上与 Flash 主区域互相隔离。
二、flash擦除方法
三、软件实现步骤
1、在串口通信的基础上,通过串口发送数据到MCU,操作读/写flash
2、命令判断
指令码:flash操作固定0x01;
操作码:0x01--读, 0x04--写
以上命令均以HEX数据格式发送
范例:
(1)写数据
68 01 04 02 12 34 16 //向flash中写两个字节的数据,数据为0x12, 0x34
无返回,可通过读取数据来进行检验
(2)读数据
[2021-03-02 13:36:37:313] 68 01 01 01 05 16 (6 bytes) //从flash中读取5个字节的数据
[2021-03-02 13:36:37:518] 68 01 81 05 11 22 33 44 55 16 (10 bytes)//读到的数据为:11 22 33 44 55
3、flash读函数
- ErrorStatus FL_FLASH_Read_Dma(FLASH_Type* FLASHx, uint32_t address, uint32_t *data, uint16_t length)
-
-
-
-
- ErrorStatus FL_FLASH_Read_Dma(FLASH_Type* FLASHx, uint32_t address, uint32_t *data, uint16_t length)
- {
- ErrorStatus ret;
- uint32_t Timeout;
-
- FL_DMA_InitTypeDef initStruct={0};
-
-
- assert_param(IS_FLASH_ALL_INSTANCE(FLASHx));
- assert_param(IS_FL_FLASH_MAX_ADDR(address));
-
-
- if(address & (FL_FLASH_SECTOR_SIZE_BYTE / 2 - 1))
- {
-
- return FAIL;
- }
-
- initStruct.circMode = DISABLE;
- initStruct.direction = FL_DMA_DIR_FLASH_TO_RAM;
- initStruct.memoryAddressIncMode = FL_DMA_CH7_MEMORY_INC_MODE_INCREASE;
- initStruct.flashAddressIncMode = FL_DMA_CH7_FLASH_INC_MODE_INCREASE;
- initStruct.priority = FL_DMA_PRIORITY_HIGH;
- initStruct.periphAddress = address >> 2;
- FL_DMA_Init(DMA, &initStruct, FL_DMA_CHANNEL_7);
-
- FL_DMA_WriteFlashAddress(DMA, address >> 2);
- FL_DMA_WriteMemoryAddress(DMA, (uint32_t)data >> 2, FL_DMA_CHANNEL_7);
- FL_DMA_WriteTransmissionSize(DMA, length - 1, FL_DMA_CHANNEL_7);
-
- FL_DMA_ClearFlag_TransferComplete(DMA, FL_DMA_CHANNEL_7);
- FL_DMA_EnableChannel(DMA, FL_DMA_CHANNEL_7);
- FL_DMA_Enable(DMA);
-
- Timeout = 0;
- while (1)
- {
- Timeout++;
- if(Timeout > FL_FLASH_ERASE_TIMEOUT)
- {
- ret = FAIL;
- break;
- }
-
- if (FL_DMA_IsActiveFlag_TransferComplete(DMA, FL_DMA_CHANNEL_7) == SET)
- {
- ret = PASS;
- break;
- }
- }
-
- return ret;
- }
4、flash写函数
- ErrorStatus FL_FLASH_PageErase(FLASH_Type* FLASHx, uint32_t address)
-
-
-
-
- ErrorStatus FL_FLASH_Program_Page(FLASH_Type* FLASHx, uint32_t pageNum, uint32_t *data)
-
-
-
- ErrorStatus FL_FLASH_Program_Page(FLASH_Type* FLASHx, uint32_t pageNum, uint32_t *data)
- {
- uint32_t count;
- uint32_t primask;
- uint32_t address;
- uint32_t timeout;
- ErrorStatus ret;
-
-
- assert_param(IS_FLASH_ALL_INSTANCE(FLASHx));
- assert_param(IS_FL_FLASH_MAX_PAGE((uint32_t)pageNum));
- address = pageNum*FL_FLASH_PAGE_SIZE_BYTE;
-
-
- if(address & (FL_FLASH_PAGE_SIZE_BYTE-1))
- {
-
- return FAIL;
- }
- FL_RCC_EnableGroup2BusClock(FL_RCC_GROUP2_BUSCLK_FLASH);
- FL_RCC_EnableGroup2OperationClock(FL_RCC_GROUP2_OPCLK_FLASH);
-
- FL_FLASH_EnableProgram(FLASHx);
-
- if(FL_FLASH_GetFlashLockStatus(FLASHx) != FL_FLASH_KEY_STATUS_PROGRAM)
- {
-
- primask = __get_PRIMASK();
- __disable_irq();
- FL_FLASH_UnlockFlash(FLASHx,FL_FLASH_PROGRAM_KEY1);
- FL_FLASH_UnlockFlash(FLASHx,FL_FLASH_PROGRAM_KEY2);
- __set_PRIMASK(primask);
- }
- for (count = 0; count < FL_FLASH_PAGE_SIZE_BYTE; count += 4)
- {
- timeout = 0;
- FL_FLASH_EnableProgram(FLASHx);
- *((uint32_t*)address) = *(data++);
- address += 4;
- while(1)
- {
- timeout++;
- if((timeout > FL_FLASH_ERASE_TIMEOUT)\
- ||(FL_FLASH_IsActiveFlag_ClockError(FLASHx))\
- ||(FL_FLASH_IsActiveFlag_KeyError(FLASHx))\
- ||(FL_FLASH_IsActiveFlag_AuthenticationError(FLASHx)))
- {
-
- ret = FAIL;
- break;
- }
- if(FL_FLASH_IsActiveFlag_ProgramComplete(FLASHx))
- {
-
- FL_FLASH_ClearFlag_ProgramComplete(FLASHx);
- ret = PASS;
- break;
- }
- }
- }
- FL_FLASH_LockFlash(FLASHx);
- FL_RCC_DisableGroup2OperationClock(FL_RCC_GROUP2_OPCLK_FLASH);
- return ret;
- }
5、串口通信测试
- if(uc_uart0_revok==1)
- {
- uc_uart0_revok=0;
- if(uc_uart0_rev[1]==0x01)
- {
- if(uc_uart0_rev[2]==0x01)
- {
- FL_FLASH_Read_Dma(FLASH,0x00004000,(uint32_t * )DataTowrite,512);
- uc_uart0_sendbuf[0]=0x68;
- uc_uart0_sendbuf[1]=0x01;
- uc_uart0_sendbuf[2]=0x81;
- uc_uart0_sendbuf[3]=uc_uart0_rev[4];
- for(i1=0;i1<uc_uart0_rev[4];i1++)
- {
- uc_uart0_sendbuf[4+i1]=DataTowrite[i1];
- }
- uc_uart0_sendbuf[4+uc_uart0_rev[4]]=0x16;
- uc_uart0_sendlight=5+uc_uart0_rev[4];
- uart0_send();
- }
- else if(uc_uart0_rev[2]==0x04)
- {
- memset(DataTowrite,0,512);
- for(i1=0;i1<uc_uart0_rev[3];i1++)
- {
- DataTowrite[i1]=uc_uart0_rev[4+i1];
- }
- FL_FLASH_PageErase(FLASH, 0x00004000);
- FL_FLASH_Program_Page(FLASH,32,DataTowrite);
- }
-
- }
- }
6、串口中断服务函数
- void UART0_IRQHandler(void)
- {
- uint8_t tmp08;
-
-
- if((ENABLE == FL_UART_IsEnabledIT_RXBuffFull(UART0))
- &&(SET == FL_UART_IsActiveFlag_RXBuffFull(UART0)))
- {
-
- uc_uart0_rev[uc_uart0_num]=FL_UART_ReadRXBuff(UART0);
- uc_uart0_num++;
- uc_uart0_revouttime=20;
-
- }
-
-
- if((ENABLE == FL_UART_IsEnabledIT_TXShiftBuffEmpty(UART0))
- &&(SET == FL_UART_IsActiveFlag_TXShiftBuffEmpty(UART0)))
- {
-
-
- if(uc_uart0_sendnum<uc_uart0_sendlight)
- {
- FL_UART_WriteTXBuff(UART0, uc_uart0_sendbuf[uc_uart0_sendnum]);
- uc_uart0_sendnum++;
- }
- else
- {
- uc_uart0_sendnum=0;
- uc_uart0_sendlight=0;
- }
-
- FL_UART_ClearFlag_TXShiftBuffEmpty(UART0);
- }
- }
7、串口发送函数
-
- void uart0_send(void)
- {
- uc_uart0_sendnum=1;
- FL_UART_ClearFlag_TXShiftBuffEmpty(UART0);
- FL_UART_EnableIT_TXShiftBuffEmpty(UART0);
- FL_UART_WriteTXBuff(UART0, uc_uart0_sendbuf[0]);
- DelayMs(50);
- FL_UART_DisableIT_TXShiftBuffEmpty(UART0);
- FL_UART_EnableIT_RXBuffFull(UART0);
- }
8、串口助手通信报文截图
|