4751|11

12

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

复旦微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)
  • //FLASHx:外设地址
  • //address:操作的地址(页首地址)
  • //data:读回的数据存放地址
  • //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)
  • //页擦写函数
  • //FLASHx:外设地址
  • //address:操作的地址(页首地址)
  • ErrorStatus FL_FLASH_Program_Page(FLASH_Type* FLASHx, uint32_t pageNum, uint32_t *data)
  • //FLASHx:外设地址
  • //pageNum:扇区号
  • //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)
  • {
  • /* Key 序列*/
  • 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)//flash操作
  • {
  • if(uc_uart0_rev[2]==0x01)//读flash
  • {
  • 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)//写flash
  • {
  • 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);//接收中断标志可通过读取rxreg寄存器清除
  • uc_uart0_num++;
  • uc_uart0_revouttime=20;//200ms超时
  • }
  • //发送中断处理
  • if((ENABLE == FL_UART_IsEnabledIT_TXShiftBuffEmpty(UART0))
  • &&(SET == FL_UART_IsActiveFlag_TXShiftBuffEmpty(UART0)))
  • {
  • //发送中断标志可通过写txreg寄存器清除或txif写1清除
  • //发送指定长度的数据
  • 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、串口发送函数

  • //uart0 串口发送函数
  • void uart0_send(void)
  • {
  • uc_uart0_sendnum=1;
  • FL_UART_ClearFlag_TXShiftBuffEmpty(UART0);//清除UART发送移位寄存器标志
  • FL_UART_EnableIT_TXShiftBuffEmpty(UART0);//启用UART发送移位寄存器中断
  • FL_UART_WriteTXBuff(UART0, uc_uart0_sendbuf[0]);
  • DelayMs(50);//软件延时
  • FL_UART_DisableIT_TXShiftBuffEmpty(UART0); //禁用UART发送移位寄存器中断
  • FL_UART_EnableIT_RXBuffFull(UART0);//启用UART接收缓冲区中断
  • }

8、串口助手通信报文截图

 
 
 

最新回复

串口通信最后的图片,读数据返回和读数据一致?   详情 回复 发表于 2021-3-9 20:31

赞赏

1

查看全部赞赏

点赞(1) 关注
 
 

回复
举报

1938

帖子

2

TA的资源

版主

沙发
 

感谢分享!

 
 
 

回复

2万

帖子

341

TA的资源

版主

板凳
 

可以总结一下FM33LC046N存储Flash情况是什么样,有没有读取Flash内容时卡死

点评

FM33LC046N的flash资源的详细介绍在官方文档中可查询到,我只是验证了简单的flash读写操作;至于读取时会不会卡死这个问题,我暂时并没有发现过  详情 回复 发表于 2021-3-9 16:39
 
 
 

回复

7755

帖子

18

TA的资源

五彩晶圆(高级)

4
 

自己写这么多代码,这个评测做的很认真了!

点评

新的东西总能提起人的兴趣,开发板也一样  详情 回复 发表于 2021-3-9 16:47
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

6997

帖子

0

TA的资源

五彩晶圆(高级)

5
 

flash擦除之前需要key验证

点评

[attachimg]527326[/attachimg][attachimg]527327[/attachimg]文档介绍是需要先进行校验才能操作flash  详情 回复 发表于 2021-3-9 16:43
 
 
 

回复

2万

帖子

71

TA的资源

管理员

6
 

能得到FREE肯定不容易,楼主继续加油

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

谢谢  详情 回复 发表于 2021-3-9 16:44
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

7
 
qwqwqw2088 发表于 2021-3-5 11:53 可以总结一下FM33LC046N存储Flash情况是什么样,有没有读取Flash内容时卡死

FM33LC046N的flash资源的详细介绍在官方文档中可查询到,我只是验证了简单的flash读写操作;至于读取时会不会卡死这个问题,我暂时并没有发现过

 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

8
 
Jacktang 发表于 2021-3-8 20:27 flash擦除之前需要key验证

文档介绍是需要先进行校验才能操作flash

 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

9
 
soso 发表于 2021-3-9 16:02 能得到FREE肯定不容易,楼主继续加油

谢谢

 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

10
 
freebsder 发表于 2021-3-6 21:40 自己写这么多代码,这个评测做的很认真了!

新的东西总能提起人的兴趣,开发板也一样

 
 
 

回复

6997

帖子

0

TA的资源

五彩晶圆(高级)

11
 

串口通信最后的图片,读数据返回和读数据一致?

点评

是不同的,绿色是发送,蓝色是接收  详情 回复 发表于 2021-3-11 14:34
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

12
 
Jacktang 发表于 2021-3-9 20:31 串口通信最后的图片,读数据返回和读数据一致?

是不同的,绿色是发送,蓝色是接收

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
报名最后一周!2025 英飞凌消费、计算与通讯创新大会-北京站
会议时间:3月18日(周二)09:30签到
参会奖励:电动螺丝刀套装、户外登山包、京东卡

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表