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