色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于RTT驅(qū)動(dòng)“舵機(jī)轉(zhuǎn)向小車”的實(shí)現(xiàn)過(guò)程

冬至子 ? 來(lái)源:嵌入之夢(mèng) ? 作者:嵌入之夢(mèng) ? 2023-09-26 16:26 ? 次閱讀

一、背景
前些年,為了給學(xué)習(xí)單片機(jī)編程的學(xué)生提供一個(gè)方便使用的控制素材,我設(shè)計(jì)了一個(gè)輪式驅(qū)動(dòng)單元,其最大特點(diǎn)就是將電機(jī)驅(qū)動(dòng)和碼盤(pán)反饋集成到一起,用幾個(gè)TTL電平線就可以驅(qū)動(dòng),和舵機(jī)的驅(qū)動(dòng)類似,這樣使用時(shí)可以根據(jù)喜好、需要隨意選擇核心板驅(qū)動(dòng)

可以用它構(gòu)建不同驅(qū)動(dòng)方式的小車底盤(pán),最簡(jiǎn)單的一種驅(qū)動(dòng)方式就是使用一個(gè)輪式驅(qū)動(dòng)單元加一個(gè)舵機(jī)實(shí)現(xiàn)的“單輪驅(qū)動(dòng)舵機(jī)轉(zhuǎn)向小車”,它的運(yùn)動(dòng)方式和現(xiàn)實(shí)世界中的電動(dòng)叉車類似

因這種驅(qū)動(dòng)方式小車的轉(zhuǎn)向和行走兩個(gè)主要控制元素相互獨(dú)立,從學(xué)習(xí)編程角度考慮,相對(duì)于兩輪差分驅(qū)動(dòng)方式更為簡(jiǎn)單、容易。

當(dāng)時(shí)目標(biāo)是降低學(xué)習(xí)門檻,故選了Arduino作為控制器。為便于接線,選擇了市場(chǎng)上的一種 Nano 擴(kuò)展板,其外形和UNO一樣,只是將每個(gè)IO都配了一個(gè)地線和電源端,用杜邦線連接十分方便

后來(lái)覺(jué)得Arduino Nano控制器資源太少,考慮改用主流的 STM32F103C8T6核心板,但Nano擴(kuò)展板的構(gòu)思不錯(cuò),邊參考它自己設(shè)計(jì)了一塊 STM32F103C8核心板的擴(kuò)展板

由于大環(huán)境影響,國(guó)產(chǎn)OS被重視,在RTOS領(lǐng)域,RT-Thread無(wú)疑是國(guó)產(chǎn)系統(tǒng)中的佼佼者。故萌生了在小車平臺(tái)上嘗試一下的念頭,既然有可以方便使用的STM32F103C8擴(kuò)展板,又有和STM32F103C8核心板兼容的STM32F411CE核心板,小車的控制也應(yīng)該提升一下,跑跑我們自己的RTOS。

下面將完整地記錄實(shí)施過(guò)程,期望能對(duì)想選用 RT-Thread 開(kāi)發(fā)產(chǎn)品的朋友有幫助,因?yàn)樾≤嚳刂葡鄬?duì)實(shí)時(shí)性要求較高,有真實(shí)的多任務(wù)需求,不同于HMI(人機(jī)界面)類應(yīng)用,用事件驅(qū)動(dòng)即可,沒(méi)有那么強(qiáng)的實(shí)時(shí)性、并發(fā)性要求。

二、目標(biāo)
按實(shí)時(shí)多任務(wù)的思路,基于 RT-Thread,完成小車驅(qū)動(dòng),并可以通過(guò)串口(藍(lán)牙透?jìng)鳎┎倏v小車運(yùn)動(dòng)。
因?yàn)镽T-Thread 的特色是有豐富的組件和軟件包可以擴(kuò)展,但要享用這些,必須是標(biāo)準(zhǔn)版;如果用Nano版,和FreeRTOS區(qū)別不大。故選擇RT-Thread標(biāo)準(zhǔn)版。

三、實(shí)施過(guò)程
3.1 總體構(gòu)思及任務(wù)設(shè)計(jì)
我做項(xiàng)目通常是先構(gòu)思程序框架,將所需完成的功能合理拆解,根據(jù)功能確定框架。
選用成熟的RTOS,只是有了多任務(wù)實(shí)現(xiàn)的手段和工具,程序框架還是需要自己設(shè)計(jì)。
對(duì)于基于RTOS的程序而言,首先要設(shè)計(jì)的就是任務(wù)(在RT-Thread中為線程),根據(jù)RTOS所提供的工具,結(jié)合自己想要實(shí)現(xiàn)的功能,合理劃分任務(wù),創(chuàng)建相應(yīng)的線程,并確定線程之間的交互方式及內(nèi)容,從而完成一個(gè)基于RTOS的多任務(wù)控制程序。
任務(wù)劃分的首要目標(biāo)是相對(duì)獨(dú)立,即所構(gòu)建的任務(wù)是完整的,有清晰的輸入消息和輸出結(jié)果,其工作只是對(duì)輸入進(jìn)行相應(yīng)處理,給出輸出,中間過(guò)程不受其它因素所牽制。
其次是任務(wù)可一次完成,中間沒(méi)有長(zhǎng)時(shí)間的等待操作,任務(wù)通常是處在等待輸入的狀態(tài),收到輸入后,即刻完成對(duì)輸入的處理,輸出結(jié)果,之后再次回到等待輸入狀態(tài)。
這樣設(shè)計(jì)主要是因?yàn)椋核^多任務(wù)操作,表面上看每個(gè)任務(wù)都在連續(xù)執(zhí)行,實(shí)質(zhì)上MCU還是分時(shí)處理各個(gè)任務(wù),只是通過(guò)RTOS在后臺(tái)切換。
RTOS調(diào)度的方式?jīng)Q定了各個(gè)任務(wù)的分配時(shí)間和響應(yīng)速度,各家RTOS的調(diào)度方式雖有不同,但都遵循一個(gè)原則:即處于等待狀態(tài)的任務(wù)不分配運(yùn)行時(shí)間,這樣才能使程序達(dá)到最佳效率。
使用RTOS的等候消息函數(shù),就是告知OS,我目前“沒(méi)事”,在等新的消息。
基于這種方式構(gòu)建任務(wù)除了保證程序的執(zhí)行效率和實(shí)時(shí)性外,還便于調(diào)試。可人為注入消息觸發(fā)任務(wù)執(zhí)行,觀察輸出結(jié)果是否符合設(shè)計(jì)即可。而且可以用多模塊方式,一個(gè)任務(wù)一個(gè)模塊,由多人分別編寫(xiě)、合作完成。
基于RTOS編程,考慮到其多任務(wù)的特點(diǎn),通常是先做一個(gè)基礎(chǔ)框架,再根據(jù)不同的場(chǎng)景設(shè)計(jì)相應(yīng)的任務(wù)。
所謂“基礎(chǔ)框架”,就是結(jié)合單片機(jī)應(yīng)用的特點(diǎn),將一些通用需求納入,這樣在每次做新的項(xiàng)目時(shí)以此為基礎(chǔ),增加新的功能即可。

基礎(chǔ)框架包含:
1)串口命令接收:作為人機(jī)交互通道,代替以往通過(guò)按鍵實(shí)現(xiàn)的程序操控手段。操作命令的產(chǎn)生可以用PC、手機(jī)之類有豐富交互手段的設(shè)備,比實(shí)體按鍵更為靈活、直觀、豐富。
2)串口數(shù)據(jù)發(fā)送:作為人機(jī)交互通道,代替以往通過(guò)顯示器實(shí)現(xiàn)的信息輸出,同樣可以用PC、手機(jī)之類的設(shè)備接收后顯示,界面設(shè)計(jì)遠(yuǎn)比顯示屏靈活、豐富、隨心所欲。之所以將收、發(fā)分開(kāi),是考慮到輸出信息需要服務(wù)于所有任務(wù),以便功能設(shè)計(jì)更為合理。
3)調(diào)試信息輸出任務(wù):在沒(méi)有或不能使用IDE調(diào)試手段時(shí),需要在程序中輸出相應(yīng)的調(diào)試信息,以實(shí)現(xiàn) Debug ;不過(guò),RT-Thread 內(nèi)置Finsh 十分完善,故選用RT-Thread則不再需要設(shè)計(jì)此任務(wù),這是 RT-Thread 優(yōu)點(diǎn)之一。
4)看護(hù)任務(wù):利用RTOS的信息交互機(jī)制,周期性地與各任務(wù)交換信息,當(dāng)出現(xiàn)不應(yīng)答時(shí),說(shuō)明對(duì)應(yīng)的任務(wù)工作異常,可以做相應(yīng)的操作。這樣處理無(wú)需復(fù)位,導(dǎo)致其它任務(wù)被非正常中斷,增加了程序的可靠性。即便不處理,也能利用調(diào)試信息輸出及時(shí)發(fā)現(xiàn)是哪個(gè)任務(wù)異常,以便消除隱患。
5)主應(yīng)用任務(wù):前面幾個(gè)任務(wù)屬于框架的基礎(chǔ)任務(wù),未涉及程序需要執(zhí)行的實(shí)際功能,主應(yīng)用任務(wù)就是實(shí)現(xiàn)具體功能的核心。設(shè)計(jì)主應(yīng)用任務(wù)是考慮到一般來(lái)說(shuō),程序均有一個(gè)核心的部分,用于管理、協(xié)調(diào)一些子功能,使得程序運(yùn)行有序;它相當(dāng)于一個(gè)管理者。這個(gè)在抽象的框架設(shè)計(jì)時(shí)只完成了信息交互,在具體到特定的需求時(shí)再完善設(shè)計(jì)。
6)其它任務(wù):相當(dāng)于執(zhí)行者,完成特定的功能。同上,這個(gè)任務(wù)在框架設(shè)計(jì)時(shí)只是完成和主應(yīng)用任務(wù)的信息交互,具體實(shí)施時(shí)再詳細(xì)設(shè)計(jì)。

在本項(xiàng)目實(shí)施中,需要完成的功能如下:
1、接受串口操作命令,解析并執(zhí)行。具體而言就是2個(gè)命令:按指定速度前進(jìn)或后退指定距離、轉(zhuǎn)向角度。
2、電機(jī)驅(qū)動(dòng),實(shí)現(xiàn)調(diào)速和走指定距離。
3、舵機(jī)驅(qū)動(dòng),完成指定轉(zhuǎn)向角度。
據(jù)此,考慮設(shè)置兩個(gè)執(zhí)行任務(wù):電機(jī)驅(qū)動(dòng)、舵機(jī)驅(qū)動(dòng),以及一個(gè)主應(yīng)用任務(wù),負(fù)責(zé)接受、解析操作命令,將相應(yīng)操作信息發(fā)送給相應(yīng)的執(zhí)行任務(wù)。
舵機(jī)的操作方式按道理無(wú)需單設(shè)為一個(gè)任務(wù),因?yàn)樗陨黹]環(huán),無(wú)需程序去處理反饋和修正。但考慮到邏輯上的獨(dú)立性,以及未來(lái)用多個(gè)舵機(jī)和輪式驅(qū)動(dòng)單元構(gòu)成的全向小車驅(qū)動(dòng),舵機(jī)轉(zhuǎn)向構(gòu)建為一個(gè)獨(dú)立的任務(wù)有助于程序的可維護(hù)性和可擴(kuò)展性。
構(gòu)建如下應(yīng)用任務(wù):
1)主應(yīng)用任務(wù):解析所設(shè)計(jì)的操作命令,將命令參數(shù)提取后發(fā)送給相應(yīng)的執(zhí)行任務(wù),并應(yīng)答。
2)電機(jī)驅(qū)動(dòng):接收?qǐng)?zhí)行參數(shù)實(shí)現(xiàn)PWM電機(jī)驅(qū)動(dòng),并根據(jù)碼盤(pán)反饋實(shí)現(xiàn)調(diào)速和行走距離控制,反饋當(dāng)前運(yùn)行狀態(tài)給主應(yīng)用任務(wù)。
3)舵機(jī)驅(qū)動(dòng):接收?qǐng)?zhí)行參數(shù),執(zhí)行舵機(jī)操作;基于舵機(jī)特性,反饋舵機(jī)當(dāng)前狀態(tài)(正在運(yùn)行、已到位)。

3.2 任務(wù)(線程)間交互設(shè)計(jì)
一個(gè)任務(wù)常常需要接收多個(gè)消息,而且是來(lái)自不同的任務(wù);為了實(shí)現(xiàn)將這些消息通過(guò)一個(gè)等待函數(shù)獲取,RTOS提供了一個(gè)方便的手段:事件組;即將若干消息匯總在一起,一個(gè)消息對(duì)事件的一位;而且等待的方式也很靈活,可以是“與”的關(guān)系,即所關(guān)注的各個(gè)消息都出現(xiàn)才觸發(fā);也可以是“或”的關(guān)系,即出現(xiàn)任意一個(gè)消息就觸發(fā)。
事件組雖然解決了等待多個(gè)消息的問(wèn)題,但所傳遞的內(nèi)容往往不夠,一個(gè)消息有時(shí)包含許多參數(shù),如通訊命令的內(nèi)容。
為傳遞消息內(nèi)容,選擇了RTOS的另一個(gè)工具:郵箱。
郵箱只傳送一個(gè)字(4字節(jié)),很多時(shí)候也不夠,我習(xí)慣于用郵箱傳遞存放數(shù)據(jù)的指針,將要傳送的消息定義為一個(gè)數(shù)據(jù)結(jié)構(gòu),通過(guò)指針傳送,這樣比較靈活。
曾經(jīng)用過(guò)隊(duì)列傳輸,但需要預(yù)先確定隊(duì)列項(xiàng)長(zhǎng)度,很難一次規(guī)劃到位,后期修改比較麻煩,故改用郵箱。
通過(guò)事件組和郵箱的配合,基本上可以實(shí)現(xiàn)任務(wù)間的消息交互。

3.3 任務(wù)(線程)詳細(xì)設(shè)計(jì)
3.3.1 串口接收任務(wù)
串口是作為單片機(jī)的操作輸入通道,取代傳統(tǒng)模式下的按鍵操作。通過(guò)串口命令操作單片機(jī)遠(yuǎn)比設(shè)計(jì)實(shí)體按鍵靈活方便,而且硬件資源占用也少。
此任務(wù)要實(shí)現(xiàn)對(duì)串口命令的接收和初步解析,將命令內(nèi)容轉(zhuǎn)發(fā)給主應(yīng)用任務(wù)處理。
核心是能可靠的監(jiān)測(cè)和接收符合通訊協(xié)議的命令幀。
通訊協(xié)議的定義也是串口命令的重點(diǎn),要考慮的簡(jiǎn)潔性和可擴(kuò)展性的平衡,同時(shí)要兼顧應(yīng)用場(chǎng)景的需求。
目前協(xié)議是參考 ROS機(jī)器人操作系統(tǒng))中的ROS Serial 協(xié)議設(shè)計(jì)的。因?yàn)樾≤囉袩o(wú)線通訊的需求,故在協(xié)議中有相應(yīng)的通訊地址,以便在一個(gè)通道上實(shí)現(xiàn)多機(jī)通訊。
串口通訊協(xié)議如下:
字符格式: 115200 8 N 1
幀格式:(借鑒 ROS 的 ROS Serial 協(xié)議)
0xFF 0xFE(2字節(jié)幀同步字) 幀長(zhǎng)L 幀長(zhǎng)H 幀長(zhǎng)校驗(yàn)和 目標(biāo)地址 源地址 幀數(shù)據(jù)區(qū) 幀校驗(yàn)和
其中:
幀同步字 —— 2字節(jié)特征字,暫定為0xFF 0xFE,借鑒的ROS Serial協(xié)議。
幀長(zhǎng) —— 幀數(shù)據(jù)區(qū)數(shù)據(jù)字節(jié)數(shù),不含幀校驗(yàn)和、目標(biāo)地址和源地址;先低后高,最大支持65535字節(jié),實(shí)際不一定需要,但有可能超過(guò)256字節(jié),所以用2字節(jié)。
幀長(zhǎng)校驗(yàn)和 —— 2字節(jié)幀長(zhǎng)算數(shù)和取反,取最低字節(jié)。借鑒ROS Serial協(xié)議
目標(biāo)地址 —— 接收方的通訊地址, 1字節(jié)。
源地址 —— 發(fā)送此幀的通訊地址,1字節(jié),應(yīng)答時(shí)使用。
幀數(shù)據(jù)區(qū) —— 通訊數(shù)據(jù),字節(jié)數(shù)為幀長(zhǎng)
幀校驗(yàn)和 —— 數(shù)據(jù)區(qū)所有字節(jié)的算數(shù)和取反,取最低字節(jié)。如果數(shù)據(jù)長(zhǎng)度為0,則CS為0xFF。
按此設(shè)計(jì),最短的幀為 8字節(jié),數(shù)據(jù)區(qū)無(wú)數(shù)據(jù),可作為心跳幀或命令應(yīng)答幀。
幀的傳輸方向由兩個(gè)地址確定,無(wú)需再設(shè)計(jì)上、下行(應(yīng)答幀)標(biāo)志。

幀數(shù)據(jù)區(qū)定義如下:
Key: 操作命令,1字節(jié)
Len: 數(shù)據(jù)長(zhǎng)度,2字節(jié),先低后高,單位 - 字節(jié)
Val[Len] :N 字節(jié)數(shù)據(jù)
至于 Val的數(shù)據(jù)如何定義,取決于 Key,可以定義為結(jié)構(gòu)、數(shù)據(jù)、或者更復(fù)雜的數(shù)據(jù),也可以簡(jiǎn)單的定義為字節(jié)、字、整形。

串口數(shù)據(jù)幀的可靠接收源于可靠的幀提取方式,因?yàn)橛锌赡苁褂脽o(wú)線通訊(串口接無(wú)線透?jìng)髂K即可),就存在串口接收到的數(shù)據(jù)并非都是有效的、應(yīng)該收的,需要從接收的數(shù)據(jù)流中檢出發(fā)給自己的數(shù)據(jù)幀,不能根據(jù)數(shù)據(jù)絕對(duì)位置提取。
對(duì)于從連續(xù)數(shù)據(jù)流中檢出一段符合要求的數(shù)據(jù),使用滑窗比較方式較為可靠。
由于上述協(xié)議定義的是變長(zhǎng)幀,無(wú)法對(duì)整個(gè)數(shù)據(jù)幀進(jìn)行滑窗比較,只能基于協(xié)議,找到幀頭的特征后,再對(duì)整個(gè)數(shù)據(jù)幀接收,之后再通過(guò)校驗(yàn)判斷此幀是否正確。
此處所用的幀頭特征為:同步字、幀長(zhǎng)格式(2字節(jié)+校驗(yàn))、目標(biāo)地址。

除數(shù)據(jù)幀的可靠接收外,在串口命令接收任務(wù)中,還設(shè)計(jì)了兩個(gè)操作命令:
讀內(nèi)存、寫(xiě)內(nèi)存
目的是為了在小車運(yùn)行過(guò)程中檢測(cè)特定變量的值,從而發(fā)現(xiàn)程序出現(xiàn)的問(wèn)題,類似于在IDE環(huán)境下設(shè)置斷點(diǎn),停下程序后檢查內(nèi)存變量值。
這種方式可以在程序運(yùn)行中實(shí)現(xiàn),不影響程序運(yùn)行,更為真實(shí)。
將需要監(jiān)測(cè)的變量設(shè)計(jì)為全局變量或靜態(tài)變量,在編譯產(chǎn)生的 map 文件中可以查到相應(yīng)的地址,通過(guò)讀內(nèi)存操作可隨時(shí)觀察變量的變化。
由于STM32的內(nèi)存是線性的,其RAMROM、硬件工作寄存器均在一個(gè)地址空間,因此還可以通過(guò)讀內(nèi)存功能監(jiān)測(cè)MCU相應(yīng)硬件的工作狀態(tài)(讀取相應(yīng)寄存器值),以確定初始化是否正常,運(yùn)行是否正確。
這個(gè)功能作為調(diào)試信息輸出的補(bǔ)充,可以使調(diào)試手段更加豐富。調(diào)試信息輸出需要預(yù)先嵌入一段代碼,而讀內(nèi)存操作可以隨時(shí)使用,只要對(duì)象不是動(dòng)態(tài)變量。

寫(xiě)內(nèi)存功能也是作為調(diào)試手段的補(bǔ)充,可以通過(guò)串口命令修改程序中的相應(yīng)變量,從而激勵(lì)程序執(zhí)行所需的操作。

讀、寫(xiě)命令定義如下:
命令1(0x01):讀內(nèi)存操作
0x01 0x05 0x00 數(shù)據(jù)地址(4byte,L-H)讀字節(jié)數(shù)(1byte)
讀取從數(shù)據(jù)地址開(kāi)始的N字節(jié)數(shù)據(jù),用于調(diào)試及故障遠(yuǎn)程診斷。
應(yīng)答內(nèi)容:
0x01 lenL lenH 數(shù)據(jù)地址(4byte,L-H)讀字節(jié)數(shù)(1byte)數(shù)據(jù)(N字節(jié))
數(shù)據(jù)長(zhǎng)度len為 讀字節(jié)數(shù)+5

命令2(0x02):寫(xiě)內(nèi)存數(shù)據(jù)
0x02 lenL lenH 數(shù)據(jù)地址(4byte,L-H)寫(xiě)字節(jié)數(shù)(1byte)數(shù)據(jù)(N字節(jié))
從數(shù)據(jù)地址開(kāi)始寫(xiě) N 字節(jié)數(shù)據(jù),用于調(diào)試,及臨時(shí)性的參數(shù)設(shè)置,需要保護(hù),以免引起程序崩潰。
應(yīng)答內(nèi)容:
0x02 0x05 0x00 數(shù)據(jù)地址(4byte,L-H)實(shí)際寫(xiě)字節(jié)數(shù)(1byte)
如果寫(xiě)失敗(所寫(xiě)地址不在允許范圍內(nèi)容,或長(zhǎng)度超過(guò)設(shè)定),則實(shí)際寫(xiě)字節(jié)數(shù)為 0。

3.3.2串口發(fā)送任務(wù)
在傳統(tǒng)的單片機(jī)系統(tǒng)中,通常會(huì)設(shè)計(jì)顯示屏、至少是LED數(shù)碼管作為信息輸出手段;但目前多數(shù)單片機(jī)系統(tǒng)已不需要這樣設(shè)計(jì),通過(guò)串口輸出信息,使用PC、手機(jī)這類顯示功能完善的設(shè)備作為單片機(jī)系統(tǒng)信息輸出的呈現(xiàn)手段,比LED數(shù)碼管、LCD屏更為直觀、靈活、美觀,而且占用硬件資源極少。
因程序框架是多任務(wù)方式,理論上各個(gè)任務(wù)都有輸出信息的需求,故將串口發(fā)送功能獨(dú)立設(shè)計(jì)為一個(gè)任務(wù),可以服務(wù)于所有任務(wù)。
為減少內(nèi)存消耗,發(fā)送數(shù)據(jù)傳遞消息只傳輸存放指針,發(fā)送任務(wù)根據(jù)數(shù)據(jù)結(jié)構(gòu)定義,取出要發(fā)送的數(shù)據(jù)。串口發(fā)送速度和內(nèi)存操作相比慢很多,要發(fā)送的數(shù)據(jù)放置在各自任務(wù)中,在每次需要發(fā)送前,需要確定上次數(shù)據(jù)是否取走,以避免數(shù)據(jù)覆蓋,導(dǎo)致發(fā)送數(shù)據(jù)錯(cuò)誤。

3.3.3看護(hù)任務(wù)
看護(hù)任務(wù)的設(shè)計(jì)目前只是示意性的,沒(méi)有實(shí)質(zhì)的恢復(fù)處理。因?yàn)榛謴?fù)處理需要根據(jù)具體功能確定,沒(méi)有統(tǒng)一的方法。
但編好一個(gè)處理框架,后續(xù)如果需要增加相應(yīng)的處理會(huì)方便一些。

作為看護(hù)任務(wù),除了通過(guò)和各任務(wù)交互,以確定任務(wù)是否在正常運(yùn)行外,還順帶完成了運(yùn)行指示功能。
多數(shù)單片機(jī)系統(tǒng)雖無(wú)需顯示器,但工作狀態(tài)指示通常都有,可直觀的反映系統(tǒng)是否在正常運(yùn)行,一般是通過(guò)LED的閃爍變化呈現(xiàn)。
此處參考FreeRTOS的異常指示方式設(shè)計(jì)了LED顯示功能,正常時(shí),LED等間隔閃爍,當(dāng)發(fā)現(xiàn)某個(gè)任務(wù)異常時(shí),按任務(wù)順序會(huì)出現(xiàn)間斷閃爍。具體方式為:
將一個(gè)完整的顯示周期定為10次閃爍,正常時(shí)一個(gè)周期閃爍10次。
如果是1號(hào)任務(wù)異常,則一個(gè)周期閃爍1次,其余9次對(duì)應(yīng)暗狀態(tài);如果是2號(hào),一個(gè)周期閃2次、暗8次,以此類推,最多可以支持9個(gè)任務(wù)的異常指示。

3.3.4 主應(yīng)用任務(wù)
此處主應(yīng)用任務(wù)(后面簡(jiǎn)稱:主任務(wù))完成:
1)解析串口接收任務(wù)發(fā)來(lái)的操作命令,根據(jù)命令將參數(shù)發(fā)給電機(jī)驅(qū)動(dòng)和舵機(jī)驅(qū)動(dòng)任務(wù)。
2)定時(shí)讀取電機(jī)和舵機(jī)工作狀態(tài),以便反饋給操作者。

根據(jù)前述設(shè)計(jì)目標(biāo),定義操作命令如下:
A) 命令3:讀工作狀態(tài)命令(Key = 3,Len = 0)
0x03 0x00 0x00
應(yīng)答內(nèi)容:
0x03 0x09 0x00 電機(jī)工作參數(shù)(2字節(jié))電機(jī)運(yùn)行狀態(tài)(2字節(jié))電機(jī)供電電壓(1字節(jié))電機(jī)供電電流(2字節(jié))舵機(jī)操作角度(1字節(jié))舵機(jī)當(dāng)前狀態(tài)(1字節(jié))
電機(jī)工作參數(shù):PWM值或速度值
電機(jī)運(yùn)行狀態(tài):剩余運(yùn)行時(shí)間或距離
舵機(jī)操作角度:-90 ~ +90
舵機(jī)當(dāng)前狀態(tài):運(yùn)行、到位兩個(gè)狀態(tài)

B) 命令4:PWM方式定時(shí)運(yùn)行(Key = 4,Len = 5,Val:2字節(jié)電機(jī) PWM,2字節(jié)運(yùn)行時(shí)間,1字節(jié)舵機(jī)操作角度)
0x04 0x05 0x00 電機(jī)PWM(2字節(jié)) 2字節(jié)運(yùn)行時(shí)間 1字節(jié)舵機(jī)角度
電機(jī)PWM:為 2 字節(jié)有符號(hào)數(shù),-100% ~ 100%,正數(shù)前進(jìn),負(fù)數(shù)倒退,0 - 惰行,127 - 剎車,-128 - 無(wú)效PWM,不操作
運(yùn)行時(shí)間:?jiǎn)挝唬好?br /> 舵機(jī)角度:1字節(jié)有符號(hào)數(shù)。-90 ~ +90
應(yīng)答內(nèi)容:(同讀狀態(tài)命令)

C)命令5:PWM方式定距離運(yùn)行(Key = 5,Len = 5,Val:2字節(jié)電機(jī) PWM, 2字節(jié)運(yùn)行距離,1字節(jié)舵機(jī)角度)
0x05 0x05 0x00 電機(jī)PWM(2字節(jié)) 運(yùn)行距離(2字節(jié)) 舵機(jī)角度(1字節(jié))
電機(jī)PWM: (同上)
運(yùn)行距離:2字節(jié)無(wú)符號(hào)數(shù),單位mm
舵機(jī)角度:同上
應(yīng)答內(nèi)容:(同讀狀態(tài)命令)

D)命令6:速度方式定時(shí)運(yùn)行(Key = 6,Len = 5,Val:2字節(jié)運(yùn)行速度, 2字節(jié)運(yùn)行時(shí)間,1字節(jié)舵機(jī)角度)
0x06 0x05 0x00 運(yùn)行速度(2字節(jié)) 運(yùn)行時(shí)間(2字節(jié)) 舵機(jī)角度(1字節(jié))
電機(jī)速度: 2 字節(jié)有符號(hào)數(shù),單位:mm/s,正數(shù)前進(jìn),負(fù)數(shù)倒退,0 - 惰行,32767 - 剎車,-32768 - 無(wú)效速度,不操作
運(yùn)行時(shí)間:2字節(jié)無(wú)符號(hào)數(shù),單位 秒
舵機(jī)角度:同前
應(yīng)答內(nèi)容:(同讀狀態(tài)命令)

E)命令7:速度方式定距離運(yùn)行(Key = 6,Len = 5,Val:2字節(jié)運(yùn)行速度, 2字節(jié)運(yùn)行距離,1字節(jié)舵機(jī)角度)
0x06 0x05 0x00 運(yùn)行速度(2字節(jié)) 運(yùn)行距離(2字節(jié)) 舵機(jī)角度(1字節(jié))
電機(jī)速度:(同上)
運(yùn)行距離:2字節(jié)無(wú)符號(hào)數(shù),單位 mm
舵機(jī)角度:同前
應(yīng)答內(nèi)容:(同讀狀態(tài)命令)

主任務(wù)從串口接收任務(wù)獲取上述操作命令,解析后,將相應(yīng)的工作參數(shù)轉(zhuǎn)發(fā)給電機(jī)驅(qū)動(dòng)和舵機(jī)驅(qū)動(dòng)任務(wù)。
讀狀態(tài)命令則由主任務(wù)完成,為提高響應(yīng)速度,兩個(gè)驅(qū)動(dòng)任務(wù)定時(shí)將自身的工作狀態(tài)反饋給主任務(wù),主任務(wù)接收并保存,以便隨時(shí)響應(yīng)讀狀態(tài)命令。
主任務(wù)等待的消息為:串口任務(wù)發(fā)來(lái)的命令、電機(jī)驅(qū)動(dòng)及舵機(jī)驅(qū)動(dòng)反饋的狀態(tài)、看護(hù)任務(wù)發(fā)來(lái)的詢問(wèn)。
輸出的信息為:發(fā)給電機(jī)驅(qū)動(dòng)及舵機(jī)驅(qū)動(dòng)的解析后命令參數(shù),發(fā)給串口發(fā)送任務(wù)的應(yīng)答信息。

3.3.5 電機(jī)驅(qū)動(dòng)任務(wù)
任務(wù)需要完成:
1)PWM方式驅(qū)動(dòng)電機(jī)
2)通過(guò)碼盤(pán)反饋實(shí)現(xiàn)測(cè)速
3)通過(guò)PID算法實(shí)現(xiàn)調(diào)速
4)通過(guò)碼盤(pán)反饋實(shí)現(xiàn)行走距離控制
5)通過(guò)計(jì)時(shí)器實(shí)現(xiàn)定時(shí)運(yùn)行控制

輪式驅(qū)動(dòng)單元的電機(jī)驅(qū)動(dòng)設(shè)計(jì)了4種工作狀態(tài):
前進(jìn)、后退、惰行、剎車。

前進(jìn)、后退不難理解,惰行和剎車需要說(shuō)明一下:
惰行 —— 是指在停止PWM信號(hào)后,電機(jī)驅(qū)動(dòng)H橋使電機(jī)線圈處于開(kāi)路狀態(tài),電機(jī)轉(zhuǎn)子會(huì)由于慣性,繼續(xù)轉(zhuǎn)動(dòng)到機(jī)械阻力使其停止。
剎車 —— 是指在停止PWM信號(hào)后,電機(jī)驅(qū)動(dòng)H橋使電機(jī)線圈處于短路狀態(tài),電機(jī)轉(zhuǎn)子由于慣性轉(zhuǎn)動(dòng)產(chǎn)生的感應(yīng)電勢(shì)形成電流,產(chǎn)生阻力,和機(jī)械阻力共同作用使其停止。

在精確控制行走距離時(shí),應(yīng)該運(yùn)用剎車功能,降低慣性產(chǎn)生的誤差。
平時(shí)待命狀態(tài),使其處于惰行狀態(tài),可以輕松的用手轉(zhuǎn)動(dòng)輪子。

為了對(duì)應(yīng)這兩種狀態(tài),在PWM命令參數(shù)中增加了剎車、惰行。

硬件上電機(jī)由3根信號(hào)線控制,2根控制線實(shí)現(xiàn)電機(jī)的四個(gè)狀態(tài),一根PWM線控制電機(jī)功率。需要啟用RTT的PIN組件及PWM組件。

輪式驅(qū)動(dòng)單元設(shè)計(jì)是作為編程學(xué)習(xí)素材,故刻意降低成本,碼盤(pán)是用輪轂上的齒實(shí)現(xiàn),分辨率較低,為達(dá)到測(cè)速所需的精度,在算法上做了優(yōu)化(增加了編程的挑戰(zhàn))。
基于正常轉(zhuǎn)動(dòng)的特征:相鄰兩個(gè)脈沖的周期不會(huì)突變(排除干擾造成的脈沖丟失、抖動(dòng)等異常狀況)。

擬用計(jì)數(shù)和測(cè)周期兩種方式組合,實(shí)現(xiàn)倍頻,以提高分辨率。處理方式為:
在測(cè)速周期內(nèi),一方面對(duì)脈沖計(jì)數(shù),得到完整脈沖的計(jì)數(shù)值。同時(shí)測(cè)量每個(gè)脈沖的周期,保存上一個(gè)脈沖的周期值(也可以保留前幾個(gè)脈沖的平均值,以提高可靠性),為計(jì)算非完整脈沖做準(zhǔn)備。
當(dāng)測(cè)速周期到時(shí),讀取當(dāng)前脈沖周期測(cè)量“已計(jì)量的時(shí)間“,除保存的“前一脈沖周期值”,即可得到非完整脈沖值 0. XX ,從而提高分辨率。
圖示如下:

1.jpg

通過(guò)這種方式,基本滿足了測(cè)速的需要。
測(cè)速和行走距離控制都需要啟用IO中斷。
因?yàn)闇y(cè)速和PID計(jì)算需要定時(shí),但計(jì)時(shí)要求比不高,故直接使用OS的tick計(jì)時(shí)。

電機(jī)驅(qū)動(dòng)任務(wù)等待的消息:主任務(wù)發(fā)來(lái)的參數(shù)、Tick定時(shí)喚醒信號(hào)。通過(guò)Tick定時(shí)喚醒實(shí)現(xiàn)周期性處理,如測(cè)速、PID調(diào)速、定時(shí)運(yùn)行。
輸出為:電機(jī)的物理運(yùn)轉(zhuǎn)、工作狀態(tài)反饋

3.3.6 舵機(jī)驅(qū)動(dòng)任務(wù)
舵機(jī)驅(qū)動(dòng)比較簡(jiǎn)單,輸出周期為20ms的脈沖信號(hào),脈沖寬度從1.5 ~ 2.5ms可調(diào)。
基于PWM組件即可實(shí)現(xiàn)。

舵機(jī)自身有閉環(huán)控制。但為了能反饋舵機(jī)當(dāng)前狀態(tài),主要是為了告知舵機(jī)是否轉(zhuǎn)到指定角度,需要做一些處理。

因舵機(jī)自身無(wú)反饋信號(hào),只能根據(jù)舵機(jī)參數(shù)(響應(yīng)速度),通過(guò)計(jì)算當(dāng)前角度到指定角度轉(zhuǎn)動(dòng)需要多少時(shí)間,適當(dāng)放寬后計(jì)時(shí)處理,計(jì)時(shí)完成則說(shuō)明轉(zhuǎn)到;為連續(xù)控制提供方便。
舵機(jī)任務(wù)等待的消息為:主任務(wù)發(fā)來(lái)的參數(shù)、Tick喚醒消息。
因本身舵機(jī)完成計(jì)時(shí)精度不高,用Tick計(jì)時(shí)即可。
舵機(jī)任務(wù)輸出為:舵機(jī)物理運(yùn)動(dòng)、工作狀態(tài)反饋

3.4 基于RT-Thread 實(shí)現(xiàn)過(guò)程
3.4.1 工程創(chuàng)建
選擇STM32F411CE 芯片創(chuàng)建標(biāo)準(zhǔn) RT-Thread 項(xiàng)目:

1.jpg

系統(tǒng)版本4.1.1;芯片支持包版本0.2.3;工具鏈(編譯器)版本 10.2.1。
對(duì)生成的main函數(shù)略作修改,輸出7次信息后停止輸出。
編譯通過(guò),可以下載執(zhí)行:

1.jpg

說(shuō)明RTT的編程基礎(chǔ)已有,軟、硬件環(huán)境已打通,可以著手根據(jù)上述設(shè)計(jì)編寫(xiě)程序。

因輪式驅(qū)動(dòng)單元當(dāng)初設(shè)計(jì)是模塊化構(gòu)思,即可以用一個(gè)或多個(gè)構(gòu)成不同驅(qū)動(dòng)方式的小車底盤(pán),為后續(xù)用多個(gè)輪子和舵機(jī)做其它驅(qū)動(dòng)方式的小車方便,故此處用C++模式,以便用類的方式簡(jiǎn)化后續(xù)的編程,增加程序的可維護(hù)性、可擴(kuò)展性。
在 RT-Thread Studio 環(huán)境下,用C++編程,除了在RT-Thread Setting中選擇C++外,如果用多文件編程,需將應(yīng)用的C程序后綴改為cpp,否則編譯出錯(cuò)。
之前在兩輪差分小車驅(qū)動(dòng)上嘗試過(guò)使用 RT-Thread,這次以那個(gè)程序?yàn)榛A(chǔ)修改。

3.4.2 硬件資源分配
串口命令端口
USART1(PA9、PA10)默認(rèn)給 Finsh使用。
將USART2(PA2、PA3)作為串口命令及反饋端口。

電機(jī)驅(qū)動(dòng):
PWM控制端(CT1):PB6,使用 PWM4(Timer4)通道1(T4CH1)
工作狀態(tài)控制端(CT2、CT3):PB5(CT2)、PB4(CT3)
脈沖反饋輸入端:PA12,中斷方式處理
電機(jī)電壓采集端:PA0,使用ADC1,通道0
電機(jī)電流采集端:PA1,使用ADC1,通道1
原來(lái)程序是驅(qū)動(dòng)差分小車的,控制兩個(gè)電機(jī),分別對(duì)應(yīng)左、右兩側(cè)。為了便于日后將程序擴(kuò)展應(yīng)用到多輪驅(qū)動(dòng)小車,將電機(jī)變量標(biāo)識(shí)從左右側(cè)改為1、2……。目前只有一個(gè)電機(jī),故定義為“1”。
為了實(shí)現(xiàn)倍頻測(cè)速,啟用Timer3,作為硬件計(jì)時(shí)器,獲取ns級(jí)計(jì)時(shí)。

舵機(jī)驅(qū)動(dòng):
因?yàn)槎鏅C(jī)的控制脈沖周期為20ms,和電機(jī)不同,故需要另用一個(gè)定時(shí)器實(shí)現(xiàn)。
基于STM32F411CE的芯片引腳分配,考慮到后期可能需要驅(qū)動(dòng)三輪全向小車,選擇Timer2作為舵機(jī)驅(qū)動(dòng)用定時(shí)器,仍然使用PWM模式。
目前驅(qū)動(dòng)一個(gè)舵機(jī),使用PA15(T2CH1),即PWM2的通道1。
參考電機(jī)驅(qū)動(dòng)方式,構(gòu)建舵機(jī)驅(qū)動(dòng)類,完成:
1)將角度轉(zhuǎn)換為脈沖寬度
2)進(jìn)行角度非線性修正,彌補(bǔ)舵機(jī)的偏差
3)根據(jù)舵機(jī)操作的運(yùn)行角度,用延時(shí)方式指示舵機(jī)工作狀態(tài)。

3.4.3 編程
之前首次嘗試 RT-Thread 是做了一個(gè)兩輪差分驅(qū)動(dòng)的小車程序,在上面完成了電機(jī)驅(qū)動(dòng)、測(cè)速、調(diào)速,以及一直想實(shí)現(xiàn)的PID自整定;控制效果不錯(cuò),基本達(dá)到了預(yù)期。

這次以兩輪差分驅(qū)動(dòng)的程序?yàn)榛A(chǔ),修改為舵機(jī)轉(zhuǎn)向單輪驅(qū)動(dòng)小車的驅(qū)動(dòng)程序,電機(jī)驅(qū)動(dòng)部分基本照搬,增加了舵機(jī)驅(qū)動(dòng)部分。
因?yàn)楹竺孢€想嘗試使用 RT-Thread 驅(qū)動(dòng)3輪全向小車,所以保留了電機(jī)驅(qū)動(dòng)用類的方式,同時(shí)將舵機(jī)驅(qū)動(dòng)也做成類,這樣后面做三輪小車就很方便了。

1.jpg

同樣,為方便測(cè)試,基于以往的程序,修改為此處所需的PC端測(cè)試程序(基于Processing編寫(xiě)):

1.jpg

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    16398

    瀏覽量

    178544
  • 電機(jī)驅(qū)動(dòng)

    關(guān)注

    60

    文章

    1219

    瀏覽量

    86821
  • TTL電平
    +關(guān)注

    關(guān)注

    1

    文章

    99

    瀏覽量

    12034
  • STM32F103C8
    +關(guān)注

    關(guān)注

    1

    文章

    23

    瀏覽量

    8098
  • RTThread
    +關(guān)注

    關(guān)注

    8

    文章

    132

    瀏覽量

    40907
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于51單片機(jī)的藍(lán)牙遙控小車舵機(jī)轉(zhuǎn)向版)

    N20減速電機(jī),前輪通過(guò)mg995數(shù)字舵機(jī)控制轉(zhuǎn)向(自己修改數(shù)值,程序數(shù)值僅供參考),具體資料看文件。 (轉(zhuǎn)載請(qǐng)注明出處:電子發(fā)燒友網(wǎng))
    發(fā)表于 07-18 11:22

    我畢業(yè)設(shè)計(jì)做小車誰(shuí)能給我點(diǎn)智能車差速轉(zhuǎn)向的資料!

    大神們 幫幫忙!誰(shuí)能給我點(diǎn)智能車差速轉(zhuǎn)向的資料! 我畢業(yè)設(shè)計(jì)做的是一個(gè)智能小車 小車轉(zhuǎn)向機(jī)構(gòu)我想了兩種方案 一種是后輪雙直流電機(jī)驅(qū)動(dòng)差速
    發(fā)表于 10-26 15:27

    如何用舵機(jī)控制前輪轉(zhuǎn)向,機(jī)械結(jié)構(gòu)是怎樣的?

    設(shè)計(jì)了一個(gè)智能小車,后輪驅(qū)動(dòng)。因?yàn)樘厥庖螅仨氂汕拜唽?dǎo)向。我知道要用舵機(jī)控制前輪轉(zhuǎn)向的,想請(qǐng)問(wèn):1、是用一個(gè)舵機(jī)控制兩個(gè)前輪
    發(fā)表于 08-04 21:18

    請(qǐng)問(wèn)小車轉(zhuǎn)向兩種方式有什么優(yōu)缺點(diǎn)?

    我知道的小車轉(zhuǎn)向常見(jiàn)的有兩種方式,一種是通過(guò)舵機(jī)控制轉(zhuǎn)向,另一種是通過(guò)控制兩個(gè)輪子的轉(zhuǎn)速,通過(guò)轉(zhuǎn)速差實(shí)現(xiàn)
    發(fā)表于 05-21 02:37

    請(qǐng)問(wèn)智能車怎么依靠舵機(jī)實(shí)現(xiàn)左右轉(zhuǎn)向

    網(wǎng)上的資料,舵機(jī)好像只能實(shí)現(xiàn)一個(gè)方向轉(zhuǎn),可是某些智能車怎么怎么依靠舵機(jī)實(shí)現(xiàn)左右轉(zhuǎn)向呢???
    發(fā)表于 06-24 00:23

    如何通過(guò)改變兩驅(qū)動(dòng)輪的速度差實(shí)現(xiàn)AGV小車轉(zhuǎn)向及糾偏?

    AGV小車運(yùn)行系統(tǒng)是由哪些部分組成的?AGV小車運(yùn)行系統(tǒng)轉(zhuǎn)向裝置的結(jié)構(gòu)有哪幾種?如何通過(guò)改變兩驅(qū)動(dòng)輪的速度差實(shí)現(xiàn)AGV
    發(fā)表于 07-05 06:24

    舵機(jī)如何控制小車轉(zhuǎn)向

    舵機(jī)如何控制小車轉(zhuǎn)向,在機(jī)器人機(jī)電控制系統(tǒng)中,舵機(jī)控制效果是性能的重要影響因素。舵機(jī)可以在微機(jī)電系統(tǒng)和航模中作為基本的輸出執(zhí)行機(jī)構(gòu),其簡(jiǎn)單的
    發(fā)表于 07-12 09:28

    使用S3010轉(zhuǎn)向舵機(jī)控制小車轉(zhuǎn)向

    基于恩智浦 RT1064芯片的智能小車,以 keil5為開(kāi)發(fā)環(huán)境,利用基于 MT9V03X的總鉆風(fēng)數(shù)字?jǐn)z像頭作為傳感器實(shí)現(xiàn)道路識(shí)別,使用 S3010轉(zhuǎn)向舵機(jī)控制
    發(fā)表于 08-26 13:34

    怎么實(shí)現(xiàn)兩種智能小車的建模與仿真?

    1.兩種智能小車的構(gòu)造簡(jiǎn)介在市面上常見(jiàn)的兩種智能小車都是基于輪式的,在某寶上面賣的最多的,各位在學(xué)生時(shí)代拿來(lái)應(yīng)付課程設(shè)計(jì)和畢業(yè)設(shè)計(jì)用的各種小車分為兩種。1.后輪驅(qū)動(dòng),前輪阿克曼
    發(fā)表于 08-30 06:08

    平衡小車轉(zhuǎn)向環(huán)控制方式分析并實(shí)現(xiàn)

    前言本文將對(duì)平衡小車轉(zhuǎn)向環(huán)控制方式進(jìn)行分析并用代碼實(shí)現(xiàn),平衡小車基于STM32。
    發(fā)表于 09-01 08:12

    如何實(shí)現(xiàn)舵機(jī)+超聲波避障小車藍(lán)牙遙控

    如何實(shí)現(xiàn)舵機(jī)+超聲波避障小車藍(lán)牙遙控
    發(fā)表于 10-13 07:51

    怎么實(shí)現(xiàn)循跡小車舵機(jī)控制板的通信控制?

    怎么實(shí)現(xiàn)循跡小車舵機(jī)控制板的通信控制?
    發(fā)表于 11-01 07:05

    如何去實(shí)現(xiàn)基于STM32的循跡小車功能呢

    無(wú)法現(xiàn)實(shí)太高速度移動(dòng)。4、小車方向打太大的時(shí)候無(wú)法移動(dòng)。5、舵機(jī)通過(guò)周期為20ms不同占空比的方波控制轉(zhuǎn)向二、循跡思路傳感器各種情況舵機(jī)處理方式:![在這里插入圖片描述](...
    發(fā)表于 01-14 09:03

    機(jī)器人伺服馬達(dá)的轉(zhuǎn)向控制原理分析方案

    機(jī)器人基礎(chǔ):伺服馬達(dá)轉(zhuǎn)向控制原理2016-08-09 18:46 舵機(jī)也叫伺服電機(jī),最早用于船舶上實(shí)現(xiàn)轉(zhuǎn)向功能,由于可以通過(guò)程序連續(xù)控制其
    發(fā)表于 09-20 09:14 ?1次下載

    STC12c5a60s2驅(qū)動(dòng)舵機(jī)程序分享

    舵機(jī)也叫伺服電機(jī),最早用于船舶上實(shí)現(xiàn)轉(zhuǎn)向功能,由于可以通過(guò)程序連續(xù)控制其轉(zhuǎn)角,因而被廣泛應(yīng)用智能小車
    發(fā)表于 11-10 09:06 ?6758次閱讀
    STC12c5a60s2<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>舵機(jī)</b>程序分享
    主站蜘蛛池模板: 色爰情人网站| 97公开超碰在线视频| 亚洲国产精品无码中文在线| 亚洲精品无码不卡在线播HE| 中文字幕免费在线视频| 99热热在线精品久久| 鬼灭之刃花街篇免费樱花动漫| 国产专区青青在线视频| 久久影院午夜理论片无码| 全部免费特黄特色大片看片| 亚洲AV久久无码精品九九软件 | 欧美激情视频一区| 婷婷色色狠狠爱| 中文在线观看免费网站| 高H短篇辣肉纯肉| 久久人人爽人人片AV人成| 日韩亚射吧| 在线 自拍 综合 亚洲 欧美| 成人a视频片在线观看免费| 黄瓜视频苹果直接安装| 欧美一级做a爰片免费| 亚洲视频中文字幕| 大屁股国产白浆一二区| 久久伊人影视| 午夜精品久久久久久影视riav | 婷婷综合久久狠狠色| 4438全国免费观看| 国产午夜精品一区二区| 女人张开腿让男人添| 亚洲欧美中文字幕先锋| 草莓视频免费看| 久久99免费视频| 十八禁啪啦啪漫画| 999久久国产精品免费人妻| 国精产品999一区二区三区有限| 青青草偷拍国产亚洲欧洲| 一天不停的插BB十几次| 国产精品嫩草久久久久| 欧美一级做a爰片免费| 中文字幕成人在线观看| 国产中文在线观看|