华大单片机HC32F460系列MCU内部FLASH制作成U盘 -----芯虎论坛

2021-09-28 14:42 113.232.58.101 6次
发布企业
沈阳芯硕科技有限公司商铺
认证
资质核验:
已通过营业执照认证
入驻顺企:
4
主体名称:
沈阳芯硕科技有限公司
组织机构代码:
91210106MA107DAT3B
报价
请来电询价
关键词
华大单片机 ,华大MCU ,国产单片机,低功耗MCU
所在地
辽宁省沈阳市铁西区建设西路5号(14B13)
联系电话
024-85718900
手机
19972041966
联系人
宣宣  请说明来自顺企网,优惠更多
请卖家联系我

产品详细介绍

关于如何在华大单片机HC32F460USB msc功能下使用内部Flash制作成小U盘,方法如下。

华大单片机HC32F460内部USBFS支持Device和OTG,支持msc协议。

使用华大MCU官方例程hc32f46x_ddl_Rev1.2.0\example\usb\usbd_msc,此例程使用外部Flash作为U盘空间。
想把存储器作为U盘FAT32文件系统挂载,需要在此例程中实现以下几个函数:
int8_t STORAGE_Init(uint8_tlun);
int8_t STORAGE_GetCapacity(uint8_tlun, uint32_t *block_num, uint32_t *block_size);
int8_t STORAGE_IsReady(uint8_tlun);
int8_tSTORAGE_IsWriteProtected(uint8_t lun);
int8_t STORAGE_Read(uint8_t lun,uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_t STORAGE_Write(uint8_t lun,uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_tSTORAGE_GetMaxLun(void);


其中主要的是GetCapacity,Read,Write。
1. GetCapacity获取U盘block大小和block个数,上位机可以通过这连个信息计算出U盘容量。此处需要注意FAT32格式需要用到大概20K的空间来存储文件系统信息。
   我想用内部Flash32k空间作为小U盘使用,有20K被文件系统信息占用。剩下存储空间大概剩下12KB。block个数是64个,一个block大小是512字节。
2.Read 读U盘文件系统的的数据,buf是读取数据存储的内存指针,blk_addr是读取数据在整个文件系统内的偏移(从0开始计数的,第几个block)
   blk_len本次读取数据的长度,同样也是指block个数。FAT32一个block设定为512字节。
3.Write 函数的blk_addr,blk_len,和Read函数中的意义一样。

对于华大M4内核单片机HC32F460需要考虑到,readflash内容因为有ARMAHB加持,是可以做到字节读,只需要类似memcpy函数直接复制给buf。
华大单片机HC32F460内部flash只能分页擦除,写可以调用SDKEFM API单字节写入(EFM_SingleProgram)。
而Flash的特点就是想写入必须要擦除,再写入。这样就需要一个8K大小的RAM作为写入时一个page的缓存。
因为在FAT32协议下,一次写入一个block,而不改动其他page中的block内容。这样就需要我们先把一个page读出到RAM,再在此缓存RAM内修改对应block内容后,整页page再写入到对应FLashpage中。
比如我想修改Flashpage中第二个block中的内容,其他block数据不变。就需要先把page读到RAM,再把要写入的数据写入RAM中第二个block的位置,其他block不动,整个8kRAM数据整体再写入到对应FLashpage中。

通过以上分析,实际上我们要实现的主要三个函数GetCapacity、Read、Write,主要的就是Write这个函数的实现。实现需要考虑以下几点:

1. Write需要保证FAT32写入一个512字节block而不改变HC32F460内部flash一个page中的其他block数据。
2. 定位Write传入的blk_addr在哪一个内部flashpage上,而这个blk_addr对于这个page的偏移是多少。
3. 如果Write传入的blk_len长度跨越了一个page,或已经跨越了多个page,那么我们需要考虑跨page写。

 

以下就是这个Write的实现,做到了在32kflash内对任意512字节的block,任意位置,任意长度的写入。

#define INNER_FLASH_START   0x00076000  // 内部FLash作为U盘使用时的开始地址
#define INNER_FLASH_SIZE    0x8000            //  Flash大小
#define INNER_FLASH_PAGE_SIZE    (1024u * 8u)  //  内部Flash一个page大小
#define INNER_FLASH_BLOCK_SIZE    512u             //  Fat32协议中一个读写单位(block)的大小



// 以下内容中temp_flash8K大小的RAM空间,作为写入时先读取一个Flashpage的缓存。
// 



int8_t STORAGE_Write(uint8_tlun, uint8_t *buf, uint32_t blk_addr, uint16_tblk_len)
{
    int8_t res = (int8_t)0;


    uint32_t i = 0;
    uint32_t pg_sum = 0;    // 写数据一共落到了几个page
    uint32_t blk_offset = 0; //一个page,blk_addr落在了第几块block
    uint32_t pg_num = 0;    // 从第几个page开始
    uint32_t data_sz = 0;    //写入数据大小(多少块block)
    uint32_t blk_left = 0;   //还剩下多少块block数据没写
    /* blk_max_num U盘中一共多少块block*/
    uint32_t blk_max_num= 
        INNER_FLASH_SIZE /INNER_FLASH_BLOCK_SIZE;
    /* blk_mun_ppg page页内有多少块block*/
    uint32_t blk_mun_ppg= 
        INNER_FLASH_PAGE_SIZE /INNER_FLASH_BLOCK_SIZE;


    if ((!buf) || (blk_addr >=blk_max_num)
     || (!blk_len) || (blk_len >blk_max_num))
    {
        printf("[%s] param err\r\n",__FUNCTION__);
        return-1;
    }
    blk_left = blk_len;
    blk_offset = blk_addr %blk_mun_ppg;
    pg_num = blk_addr /blk_mun_ppg;


    if (blk_len %blk_mun_ppg)
        pg_sum = (blk_len /blk_mun_ppg) + 1;
    else
        pg_sum = (blk_len /blk_mun_ppg);


    /* (blk_mun_ppg -blk_offset):是一个page内还剩下多少个block可写*/
    if (blk_left > (blk_mun_ppg - blk_offset)){
        data_sz = blk_mun_ppg -blk_offset;
    }
    else {
        data_sz =blk_left;
    }


    for (i = 0; i < pg_sum;i++)
    {
        if(inner_flash_Write(pg_num,blk_offset, data_sz *INNER_FLASH_BLOCK_SIZE,
            &buf[(blk_len - blk_left) * INNER_FLASH_BLOCK_SIZE]))
        {
            printf("[%s]inner_flash_Write1 err\r\n",__FUNCTION__);
            returnres;
        }


       pg_num++;
        blk_offset =0;
        blk_left = blk_left -data_sz;


        if (blk_left >blk_mun_ppg)
            data_sz =blk_mun_ppg;
       else
            data_sz =blk_left;
    }


    return res;
}

 

同样还需要实现GetCapacity和Read。实现后把板子插入电脑看效果, 格式化U盘,可以看到U盘容量大小,格式,分配单元大小;U盘存入文件。


所属分类:中国电子元件网 / 单片机
华大单片机HC32F460系列MCU内部FLASH制作成U盘 -----芯虎论坛的文档下载: PDF DOC TXT
关于沈阳芯硕科技有限公司商铺首页 | 更多产品 | 联系方式 | 黄页介绍
成立日期2020年03月04日
法定代表人吴迪
注册资本510
主营产品华大单片机、华润微单片机、蓝牙MCU、澎湃微产品、维晟产品、贝岭产品
经营范围电子产品、计算机软硬件技术开发、技术咨询、技术服务;电子元器件、电子产品、仪器仪表、计算机软硬件及外辅设备销售。(依法须经批准的项目,经相关部门批准后方可开展经营活动。)
公司简介沈阳芯硕科技术有限公司(ShenyangICInformationTechnologiesCo.,Ltd.)成立于2020年,公司总部位于沈阳。随着公司业务的扩大,在深圳,广州,宁波,青岛等均设有销售分支,团队成立至今一直致力于集成电路产品的市场推广。公司集销售,技术服务,技术开发于一体,为客户提供全面解决方案与技术服务。目前,公司涉足的主要领域包括医疗,消防,家电,汽车电子,电力系统,仪器仪表等 ...
公司新闻
顺企网 | 公司 | 黄页 | 产品 | 采购 | 资讯 | 免费注册 轻松建站
免责声明:本站信息由企业自行发布,本站完全免费,交易请核实资质,谨防诈骗,如有侵权请联系我们   法律声明  联系顺企网
© 11467.com 顺企网 版权所有
ICP备案: 粤B2-20160116 / 粤ICP备12079258号 / 粤公网安备 44030702000007号 / 互联网药品信息许可证:(粤)—经营性—2023—0112