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