隊內主打的robomaster系列比賽用的遙控器都是大疆生產的dt7,相對應的,有遙控器訊號接受器dr16與板子連線,接收你操縱遙控器傳送的訊號,這樣就能實現遙控器資料的接收。
而對於遙控器資料的傳輸我們一般採用dma傳輸,簡單來說就是跳過cpu,將資料直接由外設通過串列埠傳輸到儲存器
dma,全稱direct memory access,即直接儲存器訪問。全面了解dma是非常複雜的,這裡不作具體闡述,只解釋在程式中dma的呼叫,如下所示,在這裡dma的運用其實還是依靠uart串列埠接收,我們只需呼叫dma初始化函式以及呼叫串列埠中處理函式再編寫remote_rxcallback函式,作乙個遙控接收中斷的**,剩下的配置都會在你cube裡開啟dma後自動配置好。dma傳輸將資料從乙個位址空間複製到另乙個位址空間,提供在外設和儲存器之間或者儲存器和儲存器之間的高速資料傳輸。
void remote_rxcallback(uart_handletypedef* huart)
但是,由接收器dr16傳送的資料是有他自己的一套編碼規則的,如果想要使資料變得直觀以方便我們後續處理(電機的解算),這就需要進行解碼,如圖所示遙控器能簡化為如下操作端:
如圖所示,分為0、1、2、3四個搖桿通道和兩個撥桿s1、s2,接下來我們以0123四個搖桿通道的資料解碼為例,其詳細資訊如表所示:
意思就是四個搖桿從左到右(或從下到上)的位置分別線性對映到364~1684,中間值為1024(這些都是解碼後的資料而不是原始資料),不妨將所有解碼後的資料都減去1024,就會得到 -660 ~ +660的資料,會方便很多(簡單理解為正值電機正轉,負值電機反轉,也方便debug時肉眼觀察),也就是說如果你將左搖桿撥到正左端,右搖桿撥到正上端,那麼解碼後的資料就一次應當是0,+660,-660,0;
接下來就是重頭戲了,通過查閱dr16資料手冊(上圖)可知通道資料是11位的二進位制,但是在keil5裡dr16的接收函式裡存放資料的陣列是8位二進位制的,這就需要我們對陣列buff作剪下拼接成11位二進位制,如果想要獲取通道0的資料就需要將buff[0]的8bit資料和buff[1]的後三bit資料拼接,如果想要獲取通道1的資料就將buff[1]的前5bit和buff[2]的後6bit資料進行拼接,不斷通過拼接就可以獲得所有的通道資料,這個將8位資料轉化為11位資料操作就稱為解碼,其運用的知識其實就是c語言中的位運算,在此建議先簡單複習左移、右移、取或、取反等位運算操作,示意圖如下所示:
不難理解在左移右移的剪下操作後將兩段資料作或運算可實現拼接,最後和十六進製制數0x07ff(二進位制的0000 0111 1111 1111)作與運算,就能得到正確的十一位資料,這樣依次操作就能得到完整的四個通道的資料。
具體**如下(為鍛鍊自己能力不妨先在草稿紙上演算一下,再嘗試自行寫出解碼**):
void remote_decoderemotedata(remote_remotedatatypedef* rc, uint8_t* buff, int rxdatalen)
}
在解碼後我們得到的四個 -660~+660的 資料就可以非常簡單直觀地用於控制電機轉動,例如通過查詢3508電機資料手冊可知其最大轉速為480rpm,那麼我們只需將-660+660簡單做個乘法對映到-480+480,再通過can匯流排將資料輸出給電機,即可推動搖桿,控制電機旋轉。
本篇部落格到此結束,解碼知識相對較為簡單,建議實操debug體驗一下,相信會對遙控器資料解碼操作有更清晰的認識。
第一講 遞迴
遞迴 recursion 程式呼叫自身的程式設計技巧。遞迴滿足2個條件 1 有反覆執行的過程 呼叫自身 2 有跳出反覆執行過程的條件 遞迴出口 一 階乘 include using namespace std int recursive int i int main main 三 斐波那契數 inc...
矩陣第一講
特殊矩陣1.零矩陣 所有矩陣的所有元素全都為0 2.對角矩陣 乙個n階方陣除對角線上的所有元素都為0 2.數量矩陣 對角矩陣中對角線上元素為常數,3.單位矩陣 數量矩陣中對角線上上常數為1.4.行階梯矩陣 乙個矩陣的每個非零行 元素不全為零 的非零首元 第乙個非零元素 所在列的下標隨著行標的增大,並...
第一講 遞迴
遞迴 recursion 程式呼叫自身的程式設計技巧。遞迴滿足2個條件 1 有重複執行的過程 呼叫自身 2 有跳出重複執行過程的條件 遞迴出口 一 階乘 include using namespace std int recursive int i int main main 三 斐波那契數 inc...