找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5938|回復(fù): 0
收起左側(cè)

關(guān)于STM32F102/103的USB模塊和USB庫(kù)函數(shù)

[復(fù)制鏈接]
ID:426142 發(fā)表于 2018-11-14 08:39 | 顯示全部樓層 |閱讀模式
STM32 USB模塊詳解,供大家學(xué)習(xí)。
今天有空,開(kāi)貼講講,怎樣配合 ST 提供的庫(kù)函數(shù)理解 STM32F102/103 的 USB 模塊,以及 怎么調(diào)用這些庫(kù)函數(shù)來(lái)實(shí)現(xiàn)基本的 USB 通信。

題目很大,先只講講最簡(jiǎn)單的應(yīng)用。

1 關(guān)于 512 字節(jié)的 Packet Buffer

在 STM32F103 的 USB 模塊中有一個(gè) RAM 區(qū),稱為 Packet Buffer,共有 512 字節(jié)。


USB 模塊中有個(gè) Buffer Description Table,這個(gè) Table 位于 512 字節(jié)的 Packet Buffer
中,可以在 Packet Buffer 的任意位置。
USB 模塊提供一個(gè)寄存器 USB_BTABLE 來(lái)設(shè)置 Buffer Description Table 在 Packet
Buffer 的偏移地址。

在庫(kù)函數(shù)中,Define 了這個(gè)偏移地址:
usb_conf.h:
#define BTABLE_ADDRESS  (0x00)

這意味著 Buffer Description Table 位于 Packet Buffer 的首地址。




在 Buffer Description Table 中的,是所用到的端點(diǎn)的緩存區(qū)地址寄存器和緩存區(qū)長(zhǎng)度寄存器 。 所有用到的端點(diǎn)的這兩個(gè)寄存器都位于這個(gè) Table 中。

如上所說(shuō),由于這個(gè) Table 位于 Packet Buffer 的首地址。所以端點(diǎn) 0 的發(fā)送緩沖區(qū)地址寄存 器就位于 Packet Buffer 的首地址,緊接的是端點(diǎn) 0 發(fā)送緩沖區(qū)長(zhǎng)度寄存器,接著的是端點(diǎn) 0 接收緩存區(qū)的地址寄存器,跟著是端點(diǎn) 0 的接收緩存區(qū)的長(zhǎng)度寄存器,等等等等,一直到最 后一個(gè)端點(diǎn) 8 的接收緩存區(qū)的長(zhǎng)度寄存器。
每個(gè)端點(diǎn)的一個(gè)方向有 2 個(gè)寄存器,共 8 個(gè)端點(diǎn) 16 個(gè)方向,一共 32 個(gè)寄存器,每個(gè)寄存器 為 4 個(gè)字節(jié),所以這個(gè) Table 一共占有 128 字節(jié)。


在端點(diǎn)
0 發(fā)送緩存區(qū)的地址寄存器中的值,是端點(diǎn) 0 發(fā)送緩存區(qū)在 Packet Buffer 中的偏移地
址。而端點(diǎn) 0 接收緩存區(qū)的地址寄存器中的值,是端點(diǎn) 0 接收緩存區(qū)在 Packet Buffer 中的偏 移地址。

如前所說(shuō),Buffer Description Table 從理論上占有 128 個(gè)字節(jié)。但對(duì)于具體的應(yīng)用,不是每 個(gè)應(yīng)用都會(huì)用到 8 個(gè)端點(diǎn)的 16 個(gè)方向的。所以,對(duì)于那些沒(méi)有用到的端點(diǎn)寄存器,我們可 以不考慮為他們預(yù)留位置。



在 ST 提供的例程中,通常這么定義:
#define BTABLE_ADDRESS    (0x00)


/* EP0 */
/* rx/tx buffer base address */
#define ENDP0_RXADDR  (0x18)
#define ENDP0_TXADDR  (0x58)

這 3 句定義,意味著:

1, 端點(diǎn) 0 的接收緩存區(qū)位于 Packet Buffer 的 0x18 地址。
2, 端點(diǎn) 0 的發(fā)送緩存區(qū)位于 Packet Buffer 的 0x58 地址。
3, Buffer Description Table 位于 Packet Buffer 的前 24 字節(jié)。24 個(gè)字節(jié)意味著
應(yīng)用需要使用 6 個(gè)寄存器,即 3 個(gè)端點(diǎn)。
4, 端點(diǎn) 0 的接收緩存區(qū)長(zhǎng)度為 64 字節(jié)。

好了,
關(guān)于這個(gè) Packet Buffer 講解完畢。

要做一個(gè) USB 應(yīng)用,第一步就是要根據(jù)應(yīng)用合理的分配好這個(gè) Packet Buffer。 出個(gè)題目給大家做做
假設(shè),需要使用端點(diǎn) 0 的 IN,OUT 傳輸,端點(diǎn)長(zhǎng)度為 8 字節(jié),端點(diǎn) 1 的 IN 傳輸,長(zhǎng)度為 16
字節(jié)。端點(diǎn) 2 的 OUT 傳輸,長(zhǎng)度為 64 字節(jié)。端點(diǎn) 2 的 IN 傳輸,長(zhǎng)度為 64 字節(jié)。

該怎么分配這個(gè) Packet Buffer?

2 使用 STM32F102/103 USB 函數(shù)庫(kù) 進(jìn)行 USB 通信


第一步: 根據(jù)應(yīng)用的需求,定義使用到的端點(diǎn)數(shù)量

usb_conf.h
#define EP_NUM (3)
以上意味著應(yīng)用需要使用到 EP0,EP1 和 EP2

第二步: 初始化每個(gè)使用到的端點(diǎn)
usb_prop.c
SetEPType(ENDP2, EP_INTERRUPT);
定義端點(diǎn) 2 為中斷端點(diǎn)

SetEPTxAddr(ENDP2, ENDP2_TXADDR);
如果需要進(jìn)行 EP2 IN 通信,需要定義端點(diǎn) 2 的發(fā)送緩存區(qū)的地址,也就是在 Packet Buffer
中的偏移地址

SetEPRxAddr(ENDP2, ENDP2_RXADDR);
如果需要進(jìn)行 EP2 OUT 通信,需要定義端點(diǎn) 2 的接收緩存區(qū)在 Packet Buffer 中的偏移地址

SetEPRxStatus(ENDP2, EP_RX_NAK);
設(shè)置端點(diǎn) 2 的接收狀態(tài)為 NAK,設(shè)備將以 NAK 來(lái)響應(yīng)主機(jī)發(fā)起的所有 OUT 通信。

SetEPTxStatus(ENDP2, EP_TX_NAK);
設(shè)置端點(diǎn) 2 的發(fā)送狀態(tài)為 NAK,設(shè)備將以 NAK 來(lái)響應(yīng)主機(jī)發(fā)起的所有 IN 通信。

第三步: 使能端點(diǎn)的通信

對(duì)于 IN 端點(diǎn)的使能:
UserToPMABufferCopy(Send_Buffer, ENDP2_TXADDR, 8);
拷貝用戶數(shù)據(jù)到端點(diǎn) 2 的發(fā)送緩存區(qū)

SetEPTxCount(ENDP2, 8);
設(shè)置端點(diǎn) 2 發(fā)送數(shù)據(jù)長(zhǎng)度


SetEPTxValid(ENDP2);
設(shè)置端點(diǎn) 2 的發(fā)送狀態(tài)為 VALID

以上三句可以在應(yīng)用代碼的任意位置調(diào)用,一旦調(diào)用,即使能了一次 USB IN 通信。

USB 設(shè)備將在收到主機(jī)的 IN TOKEN 后,自動(dòng)發(fā)送緩存區(qū)中的數(shù)據(jù)到主機(jī),并在發(fā)送完畢 后產(chǎn)生 EP2_IN_Callback 中斷,同時(shí)將端點(diǎn) 2 的發(fā)送狀態(tài)自動(dòng)改為NAK。

如果需要再次進(jìn)行數(shù)據(jù)傳送,需要再次調(diào)用以上的三句函數(shù)。 對(duì)于 OUT 端點(diǎn)的使能:

SetEPRxValid(ENDP2);
設(shè)置端點(diǎn) 2 的接收狀態(tài)為 VALID。

以上的這句函數(shù)即使能了端點(diǎn) 2 的 OUT 通信,可以在任意位置調(diào)用。 一旦調(diào)用,即使能了一次 OUT 通信。USB 設(shè)備將以 ACK 來(lái)響應(yīng)主機(jī)隨后的 OUT 通信,并
在接收數(shù)據(jù)完畢后,產(chǎn)生 EP2_OUT_Callback 中斷,同時(shí)自動(dòng)將端點(diǎn)的接收狀態(tài)改為 NAK。

在 EP2_OUT_Callback 中斷函數(shù)中調(diào)用
USB_SIL_Read(EP2_OUT, Receive_Buffer);
可以將端點(diǎn) 2 接收緩存區(qū)中收到的數(shù)據(jù)拷貝到用戶數(shù)據(jù)區(qū)。

完整的pdf格式文檔51黑下載地址:
STM32_USB模塊講解.pdf (345.42 KB, 下載次數(shù): 91)


回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表