STM32实现USB摄像头显示到LCD屏幕上
第一章:簡介
1.1 開發環境
USB攝像頭型號:100w前置攝像頭
主機型號:野火霸天虎開發版
外設:USB-HOST接口:連接USB攝像頭設備
??????外部Sram:存放USB攝像頭數據
??????LCD屏幕:顯示圖像數據
- 第二章、UVC獲得攝像頭數據的過程
2.1 UVC枚舉過程
當USB設備連接的時候,主機采用總線枚舉過程來識別和管理接入的設備。并安裝下面順序進行行動:
用戶把USB設備插入USB端口,此時USB設備除于加點狀態,他所連接的端口是無效的。
(2)Hub檢測電壓變化,報告主機hub會實時監測端口的電平變化,一旦HUB檢測到端口有電壓變化,hub將利用自己的中斷端點將信息反饋給主控制器,告訴主機有設備連接。
(3)主機了解連接設備
如果有連接/斷開事件發生,那么主機會發送一個 Get_Port_Status請求給hub以了解此次狀態改變的確切含義。Get_Port_Status等請求屬于所有hub都要求支持的hub類標準請求。
4.主機檢測所插入的設備是全速還是低速
?hub通過檢測USB總線空閑時的差分線的高低電壓來判斷所連接設備的速度類型,當host發來Get_Port_Status請求時,hub就可以將此設備的速度類型信息回復給host。USB 2.0規范要求速度檢測要先于復位(Reset)操作。
根據是D+還是D-被拉高來判斷到底是什么設備(全速/低速)插入端口。如下圖。
(5)主機通過hub復位設備
主機一旦得知新設備已連上以后,它至少等待100ms以使得插入操作的完成以及設備電源穩定工作。然后主機控制器就向hub發出一個 Set_Port_Feature請求讓hub復位剛才設備插上的端口。hub通過驅動數據線到復位狀態(D+和D-全為低電平 ),并持續至少10ms。當然,hub不會把這樣的復位信號發送給其他已有設備連接的端口,所以其他連在該hub上的設備自然看不到復位信號,不會受影響。
(6)?主機進一步檢測全速設備是否是支持高速模式
?因為根據USB 2.0協議,高速(High Speed)設備在初始時是默認全速(Full Speed )狀態運行,所以對于一個支持USB 2.0的高速hub,當它發現它的端口連接的是一個全速設備時,會進行高速檢測,看看目前這個設備是否還支持高速傳輸,如果是,那就切到高速信號模式,否則就一直在全速狀態下工作。同樣的,從設備的角度來看,如果是一個高速設備,在剛連接到hub時或上電只能用全速模式運行。隨后hub會進行高速檢測,之后這個設備才會切換到高速模式下工作。假如所連接的hub不支持USB 2.0,即不是高速hub,不能進行高速檢測,設備將一直以全速工作。
(7)通過Hub建立主機和設備之間的信息通道
主機不停地向hub發送Get_Port_Status請求,以查詢設備是否復位成功。Hub返回的報告信息中有專門的一位用來標志設備的復位狀態。當hub撤銷了復位信號,設備就處于默認/空閑狀態(Default state),準備接收主機發來的請求。設備和主機之間的通信通過控制傳輸管道,默認管道為地址0、端點0。此時,設備能從總線上得到的最大電流是100mA。此后主機就可以通過默認控制管道和設備進行控制傳輸。
(8)主機獲取默認控制管道的最大數據包長度
默認管道其實連接到設備一端其實就是端點0。主機此時發送的請求是默認地址0,端點0,雖然所有未分配地址的設備都是通過地址0來獲取主機發來的請求,但由于枚舉過程不是多個設備并行處理,而是一次枚舉一個設備的方式進行,所以不會發生多個設備同時響應主機發來的請求。
主機會發送Get_Descriptor獲取設備描述符,設備描述符的第8字節代表設備端點0的最大包大小,只有知道端點0 的最大包長度,才知道一次控制傳輸要從設備請求多少字節數據。
(9)主機收到設備描述符后,返回一個0長度的數據確認包。
(10)主機對設備再次復位,復位后主機對地址為0的設備端點0發送一個設置地址SetAddress請求(新的設備地址在數據包中)。
(11)主機發送請求狀態返回,設備返回0長度的狀態數據包。
(12)主機收到狀態數據 包后,發送應答包ACK給設備,設備收到ACK后,啟用新的設備地址。
(13)主機再次使新的地址獲取設備描述符GetDescriptor,設備返回地址描述符。上圖描述此步動作
(14)主機獲取第一次配置描述符有前18個字節,設備返回配置描述符的前18個字節,其數據包中含有配置描述符的總長度。
(15)主機根據配置描述符的總長度再次獲取配置描述符,設備返回全總的配置描述符,此時就可以根據獲得的設備描述符進行分析判斷。《USB設備描述符》有對各類描述符的描述。
(16)如果還有字符串描述符,系統還會獲取字符串描述符。像HID設備還有報告描述符,它也需要單獨獲取。
2.2 獲取數據過程
該過程主要是進行攝像頭數據幀格式進行選擇,以及選擇分辨率和設置FPS,同時進行數據最大獲取值(由分辨率決定)和數據的一幀可以最多獲得多少。需要注意,UVC1.0的描述有26個字節,UVC1.1的描述符有34個字節,UVC1.5的描述符有48個字節。
(1)先進行SET_CUR設置分辨率,幀格式,FPS和數據最大獲取值以及一幀的最大值。
21:表示設置接口數據
01:表示SET_CUR
00 01:高位為01,低為為00,表示視頻流控制接口選擇子CS的VS_PROBE_CONTROL請求。
01 00:表示接口01,表示發向的是視頻流接口(通過上節可知,視頻控制接口VC為0,視頻流接口VS為01)。
1a 00 :表示接收數據長度為26個字節。
設置的值中
01 00:參照視頻流控制接口,dwFrameInterval=1,指定在視頻流傳輸過程中幀速率不變。
01:bFormatIndex=1,表示視頻流格式為1,為YUY2.
03:bFrameIndex=2,表示分辯率為 176*144。
15 16 05 00:0x051615=333333百納秒,即33.3333ms,即幀間隔為33ms.
00 00:即wKeyFrameRate=0x0000,即只有第一幀是關鍵幀。
00 00:wPFrameRate=0x0000
00 00:wCompQuality=00
00 00 :wCompQuality=00
00 00:wDelay=00,內部視頻流接口延遲(毫秒).
00?00?00 00:dwMaxVideoFrameSize
00 00?00 00 :dwMaxPayloadTransferSize
(2)GET_CUR 獲得一系列的配置。
a1:表示獲取接口數據
81:表示GET_CUR
00 01:高位為01,低為為00,表示視頻流控制接口選擇子CS的VS_PROBE_CONTROL請求。
01 00:表示接口01,表示發向的是視頻流接口(視頻控制接口VC為0,視頻流接口VS為01)。
1a 00 :表示接收數據長度為26個字節。
00?00:參照視頻流控制接口,dwFrameInterval=0未進行任何設置
01:bFormatIndex=1,表示視頻流格式為1,為YUY2.
00:bFrameIndex=2,表示分辯率為 176*144。
0F?42?40?00:0x0f4240=1000000百納秒,即100ms,即幀間隔為100ms.
00 00:即wKeyFrameRate=0x0000,即只有第一幀是關鍵幀。
00 00:wPFrameRate=0x0000
00 00:wCompQuality=00
00 00 :wCompQuality=00
00 00:wDelay=00,內部視頻流接口延遲(毫秒).
00?00?C6?00:dwMaxVideoFrameSize??????177*144*2
00 00?03?BC?:dwMaxPayloadTransferSize 一幀最大的傳輸數據大小
(3)SET_CUR這里改變了選擇子,使用了VS_COMMIT_CONTROL選擇子,提交上面的參數,以激活視頻流接口,表示開始傳遞數據。
?
21:表示獲取接口數據
01:表示SET_CUR
00 02:高位為02,低為為00,表示視頻流控制接口選擇子CS的VS_COMMIT_CONTROL請求。
01 00:表示接口01,表示發向的是視頻流接口(視頻控制接口VC為0,視頻流接口VS為01)。
(4)SET INTERFACE
視頻流接口需要使用端點0X81來讀取數據,但此接口處于視頻流接口1的轉換接口1中
完成上述的操作以后就可以進行攝像頭的數據傳輸了,但是判斷一幀的方式可以通過判斷負載描述符中第二個字節中的第二位進行判斷,同時也可以通過接收的字符數據的長度和一張圖片的數據長度進行對比從而得出是否接收完一張圖片的數據。
在此特別感謝USB中文網的站長,給了我很多指引,如果要搞UVC或者USB的設備類,可以去http://www.usbzh.com/article/forum-12.html這個網站上,先把上面的概念知識搞懂,會對你完成驅動有很大的幫助的!
代碼是在這個https://github.com/iliasam/STM32_HOST_UVC_Camera下面進行更改的,移植到霸天虎上調試完成的,需要注意的就是分辨率是否支持,要看USB攝像頭上支持哪幾個分辨率進行選擇。
總結
以上是生活随笔為你收集整理的STM32实现USB摄像头显示到LCD屏幕上的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Navicat连接mysql报错
- 下一篇: Python + selenium 爬取