一、USB簡介
USB(Universal Serial BUS)通用串行總線,是一個外部總線標準,用于規范電腦與外部設備的連接和通訊。是應用在PC領域的接口技術。USB接口支持設備的即插即用和熱插拔功能。USB是在1994年底由英特爾、康柏、IBM、Microsoft 等多家公司聯合提出的。
USB 發展到現在已經有USB1.0/1.1/2.0/3.0等多個版本。目前用的最多的就是USB1.1,USB2.0和USB3.0 目前已經開始普及。
STM32F103 自帶的USB符合USB2.0規范,不過STM32F103的USB 都只能用來做設備,而不能用作主機。
標準USB共四根線組成,除VCC/GND外,另外為D+,D-,這兩根數據線采用的是差分電壓的方式進行數據傳輸的。在USB主機上,D-和D+都是接了15K的電阻到GND的,所以在沒有設備接入的時候,D+和D-均是低電平。而在USB設備中,如果是高速設備,則會在D+上接一個1.5K的電阻到 VCC,而如果是低速設備,則會在D-上接一個1.5K 的電阻到VCC。這樣當設備接入主機的時候,主機就可以判斷是否有設備接入,并能判斷設備是高速設備還是低速設備。
STM32F103的MCU自帶USB 從控制器,符合USB規范的通信連接;PC主機和微控制器之間的數據傳輸是通過共享一專用的數據緩沖區來完成的,該數據緩沖區能被USB外設直接訪問。這塊專用數據緩沖區的大小由所使用的端點數目和每個端點最大的數據分組大小所決定,每個端點最大可使用 512 字節緩沖區(專用的512字節,和CAN共用),最多可用于16個單向或8個雙向端點。
USB模塊同PC主機通信,根據USB規范實現令牌分組的檢測,數據發送/接收的處理,和握手分組的處理。整個傳輸的格式由硬件完成,其中包括 CRC 的生成和校驗。
1.1 USB MSC簡介
USB大容量存儲設備類是一種計算機和移動設備之間的傳輸協議,它允許一個通用串行總線(USB)設備來訪問主機的計算設備,使兩者之間進行文件傳輸。通過這個標準的計算機連接到的設備包括:移動硬盤、移動光驅、U盤、SD、TF等儲存卡讀卡器、數碼相機、各種數字音頻播放器和便攜式媒體播放器、智能卡閱讀器、掌上電腦和手機。
MSC的通用性和操作簡單使他成為移動設備上最常見的文件系統,USB MSC并不需要任何特定的文件系統, 相反,它提供了一個簡單的界面來讀寫接口用于訪問任何硬盤驅動器。操作系統可以把MSC像本地硬盤一樣格式化,并可以與他們喜歡的任何文件系統格式它,當然也可以創建多個分區。
1.2 SDIO簡介
SD卡在我們生活中已經非常普遍了,控制器對SD卡進行讀寫通信操作一般有兩種通信接口可選,一種是SPI接口,另外一種就是SDIO接口。SDIO 全稱是安全數字輸入/輸出接口,多媒體卡(MMC)、SD 卡、SD I/O 卡都有SDIO接口。MMC卡可以說是SD卡的前身,現階段已經用得很少。STM32F1系列控制器有一個SDIO主機接口,它可以與MMC卡、SD 卡、SD I/O卡以及CE-ATA設備進行數據傳輸。另外,STM32F1系列控制器的SDIO是不支持SPI通信模式的,如果需要用到SPI通信只能使用SPI外設。
1.3 SD卡簡介
SD卡除了SD-Micro卡之外,還有兩種分別是SD和mini-SD,他們分別長這樣:
SD卡的四個角有一個是沒有的,以便我們認識正反來使用它,SD卡的一側還有一個可以扳動的讀寫保護開關,這三種卡里面SD卡最大,SD-Micro最小。根據SD卡的容量,可劃分為SDSC、SDHC、SDXC三種標準。現今,市場的主流SD產品是SDHC和SDXC這兩種較大容量的存儲卡,而SDSC卡因容量過小,已逐漸被市場淘汰。SD卡(三種卡的統稱)的存儲空間是由一個一個扇區組成的,SD卡的扇區大小是固定的,為512byte(這一點很重要) ,若干個扇區又可以組成一個分配單元(也被成為簇),分配單元常見的大小為4K、8K、16K、32K、64K。需要注意的是,SD-Micro只有8個引腳,而SD卡是有九個引腳的,這兩種都可以直線4線通訊。
二、新建工程2.1打開軟件,點擊“新建工程”
2.2選擇 MCU 和封裝
2.3配置時鐘
RCC設置,選擇HSE為 Crystal/Ceramic Resonator。
配置系統時鐘 SYSCLK為 72MHz,修改HCLK的值為72后,輸入回車,軟件會自動修改所有配置。
2.4配置調試模式
非常重要的一步,否則會造成第一次燒錄程序后續無法識別調試器,SYS 設置,選擇 Debug 為 Serial Wire。
三、USB3.1 參數配置
在 Connectivity 中選擇 USB 設置,并勾選 Device(FS) 激活 USB 設備。
在 Parameter Settings 進行具體參數配置。
Speed:Full Speed 12MBit/s(固定為全速)
Low Power:默認 Disabled(在任何不需要使用usb模塊的時候,通過寫控制寄存器可以使usb模塊置于低功耗模式。在這種模式下,不產生任何靜態電流消耗,同時usb時鐘也會減慢或停止。通過對usb線上數據傳輸的檢測,可以在低功耗模式下喚醒usb模塊。也可以將一特定的中斷輸入源直接連接到喚醒引腳上,以使系統能立即恢復正常的時鐘系統,并支持直接啟動或停止時鐘系統)
3.2 引腳配置
USB 的 DP 引腳必須上拉 1.5K 歐的電阻,電腦才能檢測到 USB,否則檢測不到。
查看野火指南者開發板原理圖可知,需要將 PD6 配置為低電平使能 USB。在右邊圖中找到 PD6 引腳,選擇 GPIO_Output。
在GPIO output level 中選擇 Low 輸出低電平。
3.3 配置時鐘
選擇 Clock Configuration,USB 時鐘配置為 48MHz,且來源最好是外部晶振分頻得到。
3.4 USB Device
USB有主機(Host)和設備(Device)之分。一般電腦的USB接口為主機接口,而鍵盤、鼠標、U盤等則為設備。
部分型號的STM32芯片有1~2個USB接口。像STM32F103系列的有一個USB Device接口,STM32F407系列的有2個USB接口,既可以作為HOST,又可以作為Device,還可以作為OTG接口。
在 Middleware 中選擇 USB_DEVICE 設置,在 Class For FS IP 設備類別選擇 Mass Storage Class(HID) 大容量存儲設備類。
參數配置保持默認(或根據存儲介質的最小存儲單元修改緩沖區大小)。
MSC_MEDIA_PACKET (Media I/O buffer Size)(讀寫緩沖區大小):512(默認為512,這個的大小對于USB讀寫速度會有一些影響,最好和存儲介質的最小存儲單元一致)
本實驗板使用的SD卡(三種卡的統稱)的存儲空間是由一個一個扇區組成的,SD卡的扇區大小是固定的,為512byte(這一點很重要) ,若干個扇區又可以組成一個分配單元(也被成為簇),分配單元常見的大小為4K、8K、16K、32K、64K。
設備描述符保持默認。
四、SDIO
STM32 控制器可以控制使用單線或 4 線傳輸,本開發板設計使用 4 線傳輸。
4.1 參數配置
在 Connetivity 中選擇 SDIO 設置,并選擇 SD 4 bits Wide bus 四線SD模式
此時 SDIO 對應的管腳也被選中。
在 Parameter Settings 進行具體參數配置。
Clock transition on which the bit capture is made:Rising transition。主時鐘 SDIOCLK 產生 CLK 引腳時鐘有效沿選擇,可選上升沿或下降沿,它設定 SDIO 時鐘控制寄存器(SDIO_CLKCR)的 NEGEDGE 位的值,一般選擇設置為上升沿。
SDIO Clock divider bypass:Disable。時鐘分頻旁路使用,可選使能或禁用,它設定 SDIO_CLKCR 寄存器的 BYPASS 位。如果使能旁路,SDIOCLK 直接驅動 CLK 線輸出時鐘;如果禁用,使用 SDIO_CLKCR 寄存器的 CLKDIV 位值分頻 SDIOCLK,然后輸出到 CLK 線。一般選擇禁用時鐘分頻旁路。
SDIO Clock output enable when the bus is idle:Disable the power save for the clock。節能模式選擇,可選使能或禁用,它設定 SDIO_CLKCR 寄存器的 PWRSAV 位的值。如果使能節能模式,CLK 線只有在總線激活時才有時鐘輸出;如果禁用節能模式,始終使能 CLK 線輸出時鐘。
SDIO hardware flow control:The hardware control flow is disabled。硬件流控制選擇,可選使能或禁用,它設定 SDIO_CLKCR 寄存器的 HWFC_EN 位的值。硬件流控制功能可以避免 FIFO 發送上溢和下溢錯誤。
SDIOCLK clock divide factor:6。時鐘分頻系數,它設定 SDIO_CLKCR 寄存器的 CLKDIV 位的值,設置 SDIOCLK 與 CLK 線輸出時鐘分頻系數:CLK 線時鐘頻率=SDIOCLK/([CLKDIV+2])。
SDIO_CK 引腳的時鐘信號在卡識別模式時要求不超過 400KHz,而在識別后的數據傳輸模式時則希望有更高的速度(最大不超過 25MHz),所以會針對這兩種模式配置 SDIOCLK 的時鐘。
這里參數描述建議將SDIOCLK clock divede factor 參數使用默認值為0,SDIOCLK為72MHz,可以得到最大頻率36MHz,但請注意,有些型號的SD卡可能不支持36MHz這么高的頻率,所以還是要以實際情況而定。
4.2 配置DMASDIO 外設支持生成 DMA 請求,使用 DMA 傳輸可以提高數據傳輸效率,因此在 SDIO 的控制代碼中,可以把它設置為 DMA 傳輸模式或輪詢模式,ST 標準庫提供 SDIO 示例中針對這兩個模式做了區分處理。應用中一般都使用DMA 傳輸模式。點擊 DMA Settings 添加 SDIO 對應 DMA2 的通道4。DMA模式選擇循環模式,方向選為內存到外設。
Priority:當發生多個 DMA 通道請求時,就意味著有先后響應處理的順序問題,這個就由仲裁器也管理。仲裁器管理 DMA 通道請求分為兩個階段。第一階段屬于軟件階段,可以在 DMA_CCRx 寄存器中設置,有 4 個等級:非常高、高、中和低四個優先級。第二階段屬于硬件階段,如果兩個或以上的 DMA 通道請求設置的優先級一樣,則他們優先級取決于通 道編號,編號越低優先權越高,比如通道 0 高于通道 1。在大容量產品和互聯型產品中,DMA1 控制器擁有高于 DMA2 控制器的優先級。
Mode:Normal 表示單次傳輸,傳輸一次后終止傳輸。Circular 表示循環傳輸,傳輸完成后又重新開始繼續傳輸,不斷循環永不停止。
Increment Address:Peripheral 表示外設地址自增。Memory 表示內存地址自增。Data Width:Byte 一個字節。Half Word 半個字,等于兩字節。Word 一個字,等于四字節。
4.3 配置NVIC
首先SD可以開啟DMA讀取或者單純的SD的中斷,但是其中優先級一定要為 SD > SD DMA Rx/Tx > USB,不然當SD卡在讀寫的時候被其他中斷打斷,會直接導致U盤掉盤,中途卡頓。
五、生成代碼六、修改usbd_storage_if.c
打開工程文件夾usbd_storage_if.c文件
6.1 聲明SD卡句柄
/* USER CODE BEGIN EXPORTED_VARIABLES */extern SD_HandleTypeDef hsd;/*USERCODEENDEXPORTED_VARIABLES*/
6.2 修改獲取SD卡容量信息函數
/** * @brief . * @param lun: . * @param block_num: . * @param block_size: . * @retval USBD_OK if all operations are OK else USBD_FAIL */int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size){ /* USER CODE BEGIN 3 */ HAL_SD_CardInfoTypeDef info; if(HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER) { HAL_SD_GetCardInfo(&hsd, &info); *block_num = info.LogBlockNbr; *block_size = info.LogBlockSize; return USBD_OK; } return USBD_FAIL; /* USER CODE END 3 */}
6.3 修改存儲讀寫函數
/** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */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 ret = USBD_FAIL; if(HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK) { ret = USBD_OK; while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY); while HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); } return ret; /* USER CODE END 6 */}
/** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */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 ret = USBD_FAIL; if(HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK) { ret = USBD_OK; while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY); while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); } return ret; /* USER CODE END 7 */}
七、查看效果
編譯工程,下載到板子上,插上USB線連接到電腦上,識別出為大容量存儲設備。
注意:如果設備帶有感嘆號,則參考下面八、注意事項。
彈出格式化對話框,直接格式化就行,文件系統選擇FAT模式。
新建一個文檔,名為測試.txt。然后在文檔中輸入一些內容。
重新上電斷開后再次打開U盤看里面的內容和已用空間。
八、注意事項
用戶代碼要加在 USER CODE BEGIN N 和 USER CODE END N 之間,否則下次使用 STM32CubeMX 重新生成代碼后,會被刪除。
如果USB端口出現感嘆號設備無法啟動的問題,可適當將堆改大,如0x400
-
usb
+關注
關注
60文章
7979瀏覽量
265580 -
STM32
+關注
關注
2270文章
10923瀏覽量
357076
發布評論請先 登錄
相關推薦
評論