历史上的今天
返回首页

历史上的今天

今天是:2024年10月29日(星期二)

正在发生

2020年10月29日 | STM32 USB 使用芯片内部flash模拟U盘

2020-10-29 来源:eefocus

这次是实现一个使用STM32内部的flash模拟一个U盘。我使用的STM32芯片是STM32F103ZE,该芯片有512K的内部flash,本次工程,我准备用最后的400K空间来模拟一个U盘。本次的工程在之前用NAND或SD卡模拟U盘的工程基础上进行修改。


首次要做的是在外设库组中添加stm32f10x_flash.c文件,因为涉及到内部flash,所以必须添加此文件。接下去,需要修改的文件只有mass_mal.c和memory.c两个了。


先来讲讲memory.c,这个文件修改量很小。在函数的前面,我们可以看到有个:uint32_t Data_Buffer[];数组的定义,该数组的数组元素个数,跟大家所使用的存储器的块大小有关。比如说,在NNAD工程里,带数组这样定义:uint32_t Data_Buffer[BULK_MAX_PACKET_SIZE *2];( BULK_MAX_PACKET_SIZE  =64 )可以看到总共有128个字,也就是512字节;在SD卡的程序中也是512字节;为这次我们使用内部的flash,需要定义成2K字节:uint32_t Data_Buffer[BULK_MAX_PACKET_SIZE *8]。还有需要注意下,在Write_Memory()和Read_Memory()中MAL层读写函数我们使用官方例程上的调用代码,而不是之前我们讲过的NAND无法格式化解决的那篇文章的调用代码。调用如下:

MAL_Read(lun , Offset ,  Data_Buffer, Mass_Block_Size[lun]);

MAL_Write(lun , W_Offset - Mass_Block_Size[lun], Data_Buffer, Mass_Block_Size[lun]);


接着是mass_mal.c这个文件修改量比较大。首先,得在该文件的最前面需要定义一些与flash相关的宏定义:

#define     FLASH_START_ADDR        0x08016000    // Flash start address 

#define     FLASH_SIZE              0x64000    // 400K 的U盘 

#define     FLASH_PAGE_SIZE         0x800         // 2k Bytes per page,只有2K才能格式化

#define     FLASH_WAIT_TIMEOUT      100000        //操作等待时间


然后要编写MAL_Init()、MAL_Write()、MAL_Read()、MAL_GetStatus()这里不多做介绍,贴出代码:

#include "mass_mal.h"




#define     FLASH_START_ADDR        0x08016000    // Flash start address 

#define     FLASH_SIZE              0x64000    // 400K 的U盘 

#define     FLASH_PAGE_SIZE         0x800         // 2k Bytes per page,只有2K才能格式化

#define     FLASH_WAIT_TIMEOUT      100000


/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

uint32_t Mass_Memory_Size[2];

uint32_t Mass_Block_Size[2];

uint32_t Mass_Block_Count[2];

__IO uint32_t Status = 0;


/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

/*******************************************************************************

* Function Name  : MAL_Init

* Description    : 初始化STM32的媒体设备

* Input          : lun

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t MAL_Init(uint8_t lun)

{

  u16 status = MAL_OK;


  switch (lun)

  {

    case 0:  

FLASH_Unlock(); 

             break;

    default:

             return MAL_FAIL;

  }

  return status;

}

/*******************************************************************************

* Function Name  : MAL_Write

* Description    : 写扇区

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)

{

  uint16_t i;

  switch (lun)

  {

    case 0:     

for(i=0;i {

if(FLASH_WaitForLastOperation(FLASH_WAIT_TIMEOUT)!=FLASH_TIMEOUT)

{

FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);

}

FLASH_ErasePage(FLASH_START_ADDR + Memory_Offset + i);

}

for(i=0;i {

if(FLASH_WaitForLastOperation(FLASH_WAIT_TIMEOUT)!=FLASH_TIMEOUT)

{

FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|


FLASH_FLAG_WRPRTERR);

}

FLASH_ProgramWord(FLASH_START_ADDR + Memory_Offset + i , Writebuff[i>>2]);

}

      break;

    default:

      return MAL_FAIL;

  }

  return MAL_OK;

}


/*******************************************************************************

* Function Name  : MAL_Read

* Description    : 读取扇区

* Input          : None

* Output         : None

* Return         : Buffer pointer

*******************************************************************************/

uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length)

{

  uint16_t i;

  switch (lun)

  {

    case 0:  

for(i=0;i {

Readbuff[i>>2] = ((vu32*)(FLASH_START_ADDR + Memory_Offset))[i>>2];

}

             break;

    default:

      return MAL_FAIL;

  }

  return MAL_OK;

}


/*******************************************************************************

* Function Name  : MAL_GetStatus

* Description    : 获取状态

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t MAL_GetStatus (uint8_t lun)

{

    if (lun == 0)

    {

  Mass_Block_Count[0] = FLASH_SIZE/FLASH_PAGE_SIZE; 

Mass_Block_Size[0] = FLASH_PAGE_SIZE;                    

Mass_Memory_Size[0] = FLASH_SIZE;

LED2_ON();

return MAL_OK;

}

  LED2_OFF();


 

  return MAL_FAIL;

}



虽然说,我们上面定义了400KB留作空间,但,我们在电脑上只看见375K左右的空间,这属于正常现象。还有,之前在调代码的时候,又出现了无法格式化的问题,经过一番推敲,才发现是定义flash也的大小出现了问题,之前定义成1K,发现不想,修改成2K才成功,就是我们上面的 :# define FLASH_PAGE_SIZE 0x800。


推荐阅读

史海拾趣

Gold Peak Group公司的发展小趣事
在控制电路周围设置必要的安全防护措施,如防护罩、警示标志等,防止人员误操作或触电事故的发生。
Electronic Transistors Corp公司的发展小趣事

ETC公司非常重视团队建设和文化塑造。公司注重培养员工的创新能力和团队协作精神,为员工提供广阔的发展空间和良好的职业前景。同时,ETC还积极营造积极向上、开放包容的企业文化,使员工能够在轻松愉悦的氛围中工作和学习。这些举措不仅提高了员工的满意度和忠诚度,也为公司的长期发展奠定了坚实的基础。

Custom LeatherCraft Manufacturing Co Inc公司的发展小趣事

随着电子行业的迅速发展,工程师和技术人员需要携带的工具和设备也越来越多。CLC敏锐地捕捉到了这一变化,开始研发具有更多功能和口袋的工具包。同时,他们还引入了新的材料和技术,使产品更加轻便、耐用。这些创新设计不仅满足了客户的需求,还进一步巩固了CLC在市场上的地位。

COILCRAFT公司的发展小趣事

COILCRAFT公司成立于1945年,是美国较早的磁性元件制造商。在创立初期,公司以生产高频电感器和变压器为主,凭借着卓越的技术和稳定的质量,逐渐在电子元器件市场中崭露头角。公司总部位于伊利诺伊州卡里,这个地理位置为其提供了便捷的物流和人才资源,为其后续的发展奠定了坚实的基础。

ETERNA公司的发展小趣事

2014年,ETERNA成为了ATP世界网球巡回赛瑞士公开赛的指定合作伙伴。这一合作标志着ETERNA在品牌建设和市场推广方面取得了新的突破。通过与ATP的合作,ETERNA不仅成功地将品牌与高端体育赛事相结合,还进一步提升了品牌形象和知名度。同时,ETERNA还为赛事提供了精准的计时服务,展现了其在电子技术领域的实力。

Emerson公司的发展小趣事

1890年,Emerson在美国密苏里州圣路易斯市成立,最初是一家电机和风扇制造商。1892年,新公司靠交流电机起家,并生产出了第一批销往北美的电风扇,净销售额接近6万美元。随着技术的不断革新,Emerson于1897年开始生产吊扇,这一创新使得高层建筑更加宜居,吊扇业务迅速成为公司的重要收入来源。

问答坊 | AI 解惑

嵌入式系统的C程序设计

看到还行就顶一下啊~~~…

查看全部问答>

双绞线传输与同轴电缆及光纤的图表比较

双绞线是将一对或一对以上的双绞线封装在一个绝缘外套中而形成的一种传输介质。 同轴电缆是由一根空心的外圆柱导体(铜网)和一根位于中心轴线的内导线(电缆铜芯)组成,并且内导线和圆柱导体及圆柱导体和外界之间都是用绝缘材料隔开。 ...…

查看全部问答>

PFAA-可编程模拟电路

很长时间就梦想着模拟电路能够像FPGA一样方便设计,现在终于看到FPAA技术了!希望大家踊跃讨论!其中ISPPAC发展的很快…

查看全部问答>

TI公司新出了Piccolo系列的C2000 DSC,大家觉得怎么样啊?

高效率32位CPU(TMS320C28xTM核) 具有40MHz/60MHz主频; 单周期执行一次32×32或两次16×16乘加(MAC);   改进型哈佛总线结构;   原子操作;   快速中断响应与处理;   统一的存储器设 ...…

查看全部问答>

音频设置

我在WinCE下做个音频(我用的是vb.net),但是想引用System.Media这个包,但是没有提示,该怎么引用啊?? 我用的是arm9 qq2440是不是要把底层修改,还是怎么搞啊?? 大家,帮个忙谢谢了!!…

查看全部问答>

如何买块合适的学习板

现在在职工作一年了,从事软件开发,经常和硬件打交道!算是一个嵌入式门口的程序员!发现在自己的能力增加到一定之后,对应用层代码的兴趣就没那么高啦。可是公司的产品很成熟,底层驱动都很稳定,不需要改动,所以平时也没有机会学到那方面知识, ...…

查看全部问答>

AN900 ADI-DSP仿真器 - 支持BF561/BF54x/BF52x等ADI全系列DSP的仿真器

AnalogCN安诺电子 - http://www.analogcn.com 国内唯一专门针对ADI应用的中文技术网站 AN900 ADI-DSP仿真器 - 支持BF561/BF54x/BF52x等ADI全系列DSP的仿真器 http://www.analogcn.com/Shop/shop1/200801/20080102025545.html AN900 ADI-DSP仿真 ...…

查看全部问答>

我是一名初学者,请各位硬件工程指指路

我毕业快要两年了,我们公司是工业仪表的计量产品的,我现在是做硬件,但是感觉基本上没我什么事可以做。PCB和软件搞定后才给我们了,我就是硬件调试和测试及维修工作,我现在基本和软件不沾边。数字芯片类的电路不比纯模拟电路,电路不用自己怎么 ...…

查看全部问答>

usb 2.0 协议

  谁有usb 2.0协议啊 ?上传,我找得好辛苦啊!…

查看全部问答>