STM32CubeMX+Keil實現 STM32F4 SDcard+SPI Flash讀卡器

STM32CubeMX+Keil實現 STM32F4 SDcard+SPI Flash讀卡器

本人今天由於項目的原因,要用到將STM32作爲一個大容量的存儲器,網上看了許多教程,這方面寫的都不是較好,最後參考原子哥的例程,實現了這一功能。廢話不多說。

總體流程

首先大致介紹一下整體的流程

  1. STM32CubeMX中 ,配置USB deviceMass Storage Class
  2. 打開SDIO外設,根據SD卡的類型,選擇對應的Mode
  3. 打開SPI外設,設置爲全雙工主機模式,不使能硬件NSS
  4. 生成MDK工程
  5. MDK中修改usbd_storage_if.c文件的內容;
  6. 下載驗證;

STM32CubeMX設置

首先基本的時鐘設置等,就不再贅述。

  1. 下面首先選擇USB爲Device模式。
    在這裏插入圖片描述
  2. 選擇之後,列表會多出來一個USB_DEVICE選項,在裏面設置爲Mass Storage Class
    在這裏插入圖片描述

好了,基本的USB模式設置已經完成,之後需要設置SD卡的模式

  1. SD卡基本設置,本人用的是4線的SD卡,所以選擇的是4 bits的模式
    在這裏插入圖片描述
  2. 然後是設置SPI,這裏我們選擇全雙工主機模式,不使能硬件NSS
    在這裏插入圖片描述
  3. 然後需要設置一下時鐘,我這裏設置的是64分頻,其他默認就行了
    在這裏插入圖片描述

需要修改heap的大小,我這裏修改爲0x1000,如果不修改,就不能正常運行,最後生成MDK代碼

MDK代碼修改

首先我們需要加入SPI Flash的驅動,我用的是W25Q128這個閃存芯片,這部分驅動代碼省略。

找到usbd_storage_if.c文件,先修改STORAGE_LUN_NBR宏定義爲2,這樣就表示我們有兩個設備

增加設備的標識等,按格式增加就行了,如果後面設置正常,插入usb之後,電腦usb設備的標識會和這裏的一樣

const int8_t STORAGE_Inquirydata_FS[] = {/* 36 */
  
  /* LUN 0 */
  0x00,
  0x80,
  0x02,
  0x02,
  (STANDARD_INQUIRY_DATA_LEN - 5),
  0x00,
  0x00,	
  0x00,
  'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
  'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product      : 16 Bytes */
  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
  '0', '.', '0' ,'1',                      /* Version      : 4 Bytes */
	
	/* LUN 1 */
  0x00,
  0x80,
  0x02,
  0x02,
  (STANDARD_INQUIRY_DATA_LEN - 5),
  0x00,
  0x00,	
  0x00,
  'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
  'S', 'P', 'I', 'F', 'L', 'A', 'S', 'H', /* Product      : 16 Bytes */
  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
  '0', '.', '0' ,'1'                      /* Version      : 4 Bytes */
	
}; 

之後,在裏面修改下面這個函數int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)

主要需要修改的內容是block_num block_size,在裏面需要指出容量的大小和扇區的大小,到此,如果我們下載代碼,插上USB,就會發現電腦裏面已經能夠識別大容量USB設備了,但是無法進行格式化等操作。

int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */
	if(lun==0)/*指定爲SD*/
	{
		HAL_SD_CardInfoTypeDef CardInfo;
		HAL_SD_GetCardInfo(&hsd,&CardInfo);
		
		*block_num  = CardInfo.BlockNbr;
		*block_size = CardInfo.BlockSize;
	}
	else/*指定爲Flash*/
	{
		*block_num = 1024*1024*12/512;
		*block_size = 512;
	}
  return (USBD_OK);
  /* USER CODE END 3 */
}

完成之後,接下來需要修改讀寫操作的函數,這樣才能實現U盤的正常讀寫

修改int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)這個函數,修改的內容如下:

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
	int8_t res=0;
	if(lun==0)
	{
		res=HAL_SD_ReadBlocks(&hsd,buf,blk_addr,blk_len,0xffff);
	}
	else
	{
		W25QXX_Read(buf,blk_addr*512,blk_len*512);
	}
  	return (USBD_OK);
  /* USER CODE END 6 */
}

修改int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)這個函數,修改的內容如下:

int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 7 */
	int8_t res=0;
	if(lun==0)
	{
		res=HAL_SD_WriteBlocks(&hsd,buf,blk_addr,blk_len,0xffff);
	}
	else
	{
		W25QXX_Write(buf,blk_addr*512,blk_len*512);
	}
  	return (USBD_OK);
  /* USER CODE END 7 */
}

還需要注意的一個地方是生成的main函數中,我們要在usb初始化之前,初始化sd卡和spi flash

	MX_GPIO_Init();
	MX_SDIO_SD_Init();
	//  MX_USB_DEVICE_Init();
	//  MX_SPI1_Init();
	/* USER CODE BEGIN 2 */
	MX_SPI1_Init();
	W25QXX_Init();

	MX_USB_DEVICE_Init();
	/* USER CODE END 2 */

好了,基本的修改就完成了,我們就可以下載代碼進行驗證
在這裏插入圖片描述
如果一切正常,就會像這樣,多出來兩個磁盤,名稱就是我們最開始數組中設置的
在這裏插入圖片描述
也能在裏面正常的讀寫文件,如此,這樣就完成了基本的功能

在這裏插入圖片描述

最後

本文中,簡單介紹瞭如何使用STM32CubeMX+Keil實現 STM32F4 SDcard+SPI Flash讀卡器,下面將在此基礎上,增加FATFS文件系統,此部分的代碼上傳至Github.,有需要的朋友可以下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章