
簡介本資源是面向嵌入式Linux開發(fā)者與Qt初學(xué)者的IMX6ULL平臺SPI LCD圖形界面實戰(zhàn)項目聚焦解決ARM Cortex-A7平臺下ILI9341驅(qū)動TFT屏顯示Qt GUI的核心適配問題。壓縮包共含多個關(guān)鍵文件包括適配MSP2402ILI9341的設(shè)備樹源碼.dts、交叉編譯后的Qt應(yīng)用程序源碼.cpp/.h、構(gòu)建腳本及啟動配置整體大小為9.57MB文件類型以C源碼、設(shè)備樹描述和Shell初始化腳本為主支撐從內(nèi)核驅(qū)動到應(yīng)用層渲染的完整鏈路。已有278人學(xué)習(xí)下載適合具備基本Linux驅(qū)動與Qt開發(fā)基礎(chǔ)的學(xué)習(xí)者開展實操驗證。讀者可直接部署運行掌握SPI總線配置、設(shè)備樹修改、Qt嵌入式渲染后端如linuxfb適配、以及無窗口管理器環(huán)境下GUI啟動流程等關(guān)鍵技術(shù)點是理解IMX6ULLSPI LCDQt協(xié)同工作的典型工程范例。 最近在做IMX6ULL相關(guān)的東西需要在板子上加一塊SPI接口的TFT小屏來跑QT界面。屏的型號是MSP2402驅(qū)動IC是經(jīng)典的ILI9341接口是6針SPISCLK、MOSI、CS、DC、RST、BL項目源碼打包下來是一個rar名字就叫“IMX6ULL開發(fā)板 SPI LCD MSP2402 顯示簡單的QT界面源碼”。這個項目看著簡單但真要把QT、SPI、內(nèi)核fbtft、LCD初始化全家桶湊到一起坑真不少。我干脆把整個過程中的方案思路、硬件接線、設(shè)備樹配置、QT端處理和排障記錄整理出來給準(zhǔn)備在IMX6ULL這類開發(fā)板上接SPI小屏跑QT的朋友做個參考。1. 項目整體設(shè)計與方案選型1.1 為什么在IMX6ULL上接SPI小屏IMX6ULL跑QT本身毫無壓力Cortex-A7單核800MHz在240x320這么小的分辨率下QPainter畫簡單界面綽綽有余。問題在于很多項目并不需要大屏比如儀表盤選項菜單、設(shè)備配置面板、狀態(tài)指示燈界面一塊2.4寸或者2.8寸的小屏就夠了。SPI接口的屏走線少、占用引腳少在嵌入式產(chǎn)品里很常見。和RGB并口屏相比SPI屏最大的優(yōu)勢是省引腳。一塊RGB565接口的4.3寸屏需要約20根數(shù)據(jù)線加時鐘同步線而SPI屏只需要4根數(shù)據(jù)線SCLK、MOSI、CS、DC加上復(fù)位和背光也就6根線對于IMX6ULL這種引腳不算特別富余的板子非常友好。缺點是刷新率低因為SPI是串行傳輸跑滿10MHz時鐘一幀240x320x2字節(jié)的數(shù)據(jù)大約需要15ms實際加上指令開銷和等待時間QT局部刷新可以接受但全屏動畫會有點吃力。在這個項目里屏是MSP2402驅(qū)動IC是ILI9341。ILI9341是市面上最常見的SPI/并口TFT驅(qū)動IC之一支持240x320分辨率內(nèi)置GRAM像素格式支持RGB565和RGB666幾乎所有做嵌入式顯示的朋友都見過這塊IC。MSP2402應(yīng)該是屏模組廠商的型號通用性沒問題直接按ILI9341處理。1.2 兩條驅(qū)動路線fbtft還是用戶態(tài)SPI打點顯示屏驅(qū)動有幾種常見做法我簡單梳理一下。第一種是內(nèi)核fbtft框架。fbtft是內(nèi)核staging目錄下的一套小屏framebuffer驅(qū)動框架專門用來支持各種SPI/并口TFT屏。它在內(nèi)核里注冊一個獨立的fb設(shè)備掛上后系統(tǒng)會多出/dev/fb0或者/dev/fb1用戶態(tài)程序包括QT只需要往framebuffer里寫像素數(shù)據(jù)不用關(guān)心底層SPI時序。優(yōu)點是QT可以直接以linuxfb的方式工作代碼改動最小兼容性好。第二種是用戶態(tài)直接通過SPI設(shè)備節(jié)點打點。應(yīng)用層打開/dev/spidevX.0通過ioctl自己發(fā)初始化命令和像素數(shù)據(jù)還要自己維護(hù)一塊顯存。這樣做的缺點是QT沒辦法直接往spidev里畫圖除非你自己實現(xiàn)一個QPA插件或者自己寫一個繪圖引擎開發(fā)量大維護(hù)成本高不推薦做QT界面。第三種是走DRM/KMS這是現(xiàn)代Linux主推的顯示框架但對SPI小屏的支持很弱而且IMX6ULL的GPU也不強用mipi或者RGB屏才會考慮走DRM。這個項目我選fbtft。原因很直接IMX6ULL內(nèi)核自帶fbtft支持ILI9341有現(xiàn)成的fb_ili9341驅(qū)動設(shè)備樹里配好spi節(jié)點注冊后就能得到一個240x320的真彩framebufferQT用linuxfb插件直接對接代碼量最小踩坑最少。1.3 整條顯示鏈路長什么樣搞清楚數(shù)據(jù)流向后面調(diào)試才不會懵。IMX6ULL跑Linux內(nèi)核系統(tǒng)起來后SPI控制器驅(qū)動注冊了SPI總線。fbtft掛在SPI總線上初始化時通過SPI向ILI9341發(fā)送初始化序列設(shè)置顯示方向、顏色格式、背光。之后fbtft在內(nèi)核里申請一塊fb內(nèi)存注冊為fb設(shè)備。QT應(yīng)用通過linuxfb的QPA插件打開/dev/fb0把界面內(nèi)容渲染到fb內(nèi)存fbtft定時或者按刷新機制把fb內(nèi)存里的數(shù)據(jù)轉(zhuǎn)換成RGB565像素流通過SPI逐行發(fā)送給ILI9341ILI9341把數(shù)據(jù)寫進(jìn)自己的GRAM完成屏幕顯示。簡單說就是QT繪制 - fbtft的fb內(nèi)存 - SPI - ILI9341 GRAM - 液晶面板。理解了這條鏈路后面遇到白屏、花屏、閃屏就能快速定位是哪個環(huán)節(jié)出了問題。2. 硬件接線與SPI通信細(xì)節(jié)2.1 MSP2402引腳與IMX6ULL接線MSP2402模組上常見的引腳有SCLK、MOSI、CS、DC、RST、BL有些還帶MISO讀GRAM用大多數(shù)場景用不上。IMX6ULL有多個ECSPI控制器我用ECSPI3引腳分配如下MSP2402引腳功能說明IMX6ULL引腳復(fù)用功能SCLKSPI時鐘UART2_TXD / GPIO1_IO20ECSPI3_SCLKMOSISPI主機輸出UART2_RXD / GPIO1_IO21ECSPI3_MOSIMISOSPI主機輸入可空UART2_CTS / GPIO1_IO22ECSPI3_MISOCS片選GPIO1_IO20對應(yīng)替換實際用GPIO5_IO11做軟件片選GPIODC數(shù)據(jù)/命令選擇GPIO5_IO14GPIORST復(fù)位GPIO5_IO15GPIOBL背光控制GPIO5_IO13GPIOVCC/GND電源3.3V / GND-這里有個細(xì)節(jié)要注意CS片選我特意沒用ECSPI3的硬件片選而是用GPIO模擬。原因是硬件片選在每個SPI word傳輸時可能拉高拉低產(chǎn)生毛刺某些屏模組對CS要求比較嚴(yán)軟件片選更可控。IMX6ULL設(shè)備樹里cs-gpios屬性可以直接指定GPIO很方便。MISO這根線在純寫屏場景下可以不接ILI9341的讀回功能用不到。但建議還是留一根線方便調(diào)試時讀ID、讀狀態(tài)寄存器特別是排查初始化失敗問題時很管用。2.2 SPI模式、速率和線序的選擇ILI9341支持SPI Mode 0CPOL0CPHA0和Mode 3CPOL1CPHA1兩種模式下時鐘空閑電平不同。絕大多數(shù)初始化代碼和現(xiàn)成驅(qū)動默認(rèn)用Mode 0我在設(shè)備樹里沒有額外配spi-cpha和spi-cpol默認(rèn)就是Mode 0。傳輸格式上要注意ILI9341的SPI接口是按字節(jié)傳輸?shù)牟皇前次?。fbtft通過spi_transfer發(fā)數(shù)據(jù)時每8個bit組成一個字節(jié)DC引腳的電平?jīng)Q定這個字節(jié)是命令還是數(shù)據(jù)。DC為低發(fā)送命令DC為高發(fā)送數(shù)據(jù)。這個時序要求DC信號先于SCLK建立fbtft驅(qū)動內(nèi)部會在發(fā)送前把DC置好問題不大。速率方面ILI9341芯片手冊上SPI時鐘上限一般是10MHz但實際和布線關(guān)系很大。杜邦線連接時超過10MHz線間串?dāng)_會很嚴(yán)重容易花屏我自己實測5MHz最穩(wěn)10MHz在短距離飛線下也能跑。設(shè)備樹里spi-max-frequency我配的是10000000如果出現(xiàn)花屏再降到5000000或者再低。2.3 ILI9341初始化序列的關(guān)鍵點ILI9341剛上電時處于未知狀態(tài)必須發(fā)初始化序列。fbtft的fb_ili9341驅(qū)動里寫好了常規(guī)初始化序列包括軟件復(fù)位、退出睡眠、像素格式設(shè)置、顯示開關(guān)等不需要自己寫全但有幾個命令值得理解。命令參數(shù)作用備注0x01無軟件復(fù)位復(fù)位后要延時120ms0x11無退出睡眠模式必須延時120ms0x360xXX存儲訪問控制MADCTL控制掃描方向和RGB/BGR0x3A0x55像素格式0x55即16位RGB5650x20/0x21無反轉(zhuǎn)顯示開關(guān)根據(jù)屏模組選擇部分屏要開反轉(zhuǎn)0x29無打開顯示不發(fā)這個屏幕不亮MADCTL命令0x36很關(guān)鍵它的低3位分別控制顏色格式和掃描方向。BGR位設(shè)為1表示像素數(shù)據(jù)按BGR順序解釋這個設(shè)錯屏上顏色會明顯偏色比如紅色變成藍(lán)色。項目里MSP2402我實測需要設(shè)置BGR0但每個屏模組可能不一樣如果顏色不對就改這個bit。上電時序上RST引腳要先拉低10ms以上再拉高等待120ms后再發(fā)初始化命令。如果RST懸空或者復(fù)位時序不對屏大概率白屏。這個坑我踩過后面排障部分細(xì)說。3. 內(nèi)核設(shè)備樹與FBTFT配置3.1 設(shè)備樹節(jié)點配置示例IMX6ULL的設(shè)備樹需要配置兩個大塊一是ECSPI控制器本身的引腳復(fù)用和片選二是掛在SPI總線上的LCD子節(jié)點。我貼出可以直接用的設(shè)備樹片段iomuxc { pinctrl_ecspi3: ecspi3grp { fsl,pins MX6UL_PAD_UART2_TXD__ECSPI3_SCLK 0x10b0 MX6UL_PAD_UART2_RXD__ECSPI3_MOSI 0x10b0 MX6UL_PAD_UART2_CTS__ECSPI3_MISO 0x10b0 MX6UL_PAD_CSI_DATA05__GPIO5_IO11 0x80000000 /* CS */ MX6UL_PAD_CSI_DATA08__GPIO5_IO14 0x80000000 /* DC */ MX6UL_PAD_CSI_DATA09__GPIO5_IO15 0x80000000 /* RST */ MX6UL_PAD_CSI_DATA07__GPIO5_IO13 0x80000000 /* BL */ ; }; }; ecspi3 { pinctrl-0 pinctrl_ecspi3; fsl,spi-num-chipselects 1; cs-gpios gpio5 11 GPIO_ACTIVE_LOW; status okay; lcd_panel: msp24020 { compatible ilitek,ili9341; reg 0; spi-max-frequency 10000000; rotate 90; fps 30; buswidth 8; dc-gpios gpio5 14 GPIO_ACTIVE_HIGH; reset-gpios gpio5 15 GPIO_ACTIVE_HIGH; led-gpios gpio5 13 GPIO_ACTIVE_HIGH; status okay; }; };這里把CS、DC、RST、BL全部通過GPIO控制。其中l(wèi)ed-gpios是fbtft的背光控制字段設(shè)置后驅(qū)動會在初始化時自動把背光引腳拉高。如果設(shè)備樹里不寫這個屏能顯示但背光不亮?xí)屓苏`以為是白屏。3.2 把LCD注冊成/dev/fb0編譯內(nèi)核時確認(rèn)開啟fbtft和ILI9341驅(qū)動。配置路徑在Device Drivers - Staging drivers - Support for small TFT LCD display modules - FB driver for the ILI9341 LCD controller注意fbtft位于staging目錄有些內(nèi)核版本默認(rèn)沒開需要在menuconfig里手動勾選。編譯完成后啟動系統(tǒng)dmesg里應(yīng)該能看到類似內(nèi)容fbtft: module is from the staging directory, the quality is unknown, you have been warned. fb_ili9341: SPI display 240x320 registered as fb0 fbtft: 240x320, SPI, RGB565, 8bit如果看到“registered as fb0”說明注冊成功。沒有fb0先查設(shè)備樹有沒有掛對再看內(nèi)核日志。啟動后可以用cat /sys/class/graphics/fb0/name確認(rèn)設(shè)備節(jié)點名字也可以直接往/dev/fb0里填充數(shù)據(jù)測試cat /dev/urandom /dev/fb0屏幕出現(xiàn)雪花噪點說明顯示鏈路已經(jīng)通了再用QT接管。3.3 調(diào)試顯示參數(shù)的小工具fbtft有一個很有用的特性很多顯示參數(shù)可以在運行時動態(tài)修改不用反復(fù)編譯內(nèi)核和重啟。比如分辨率、虛擬分辨率、旋轉(zhuǎn)方向、灰度gamma在用戶態(tài)通過/sys/class/graphics/fb0/目錄下的屬性節(jié)點查看和修改。旋轉(zhuǎn)方向可以通過fb0的rotate屬性調(diào)整echo 180 /sys/class/graphics/fb0/rotate這個很實用。實際裝屏?xí)r物理方向可能和設(shè)計方向差90度或者180度一行命令就能轉(zhuǎn)過來不用重新編譯。RGB/BGR順序、gamma值也可以在部分fbtft版本里直接調(diào)。調(diào)試顏色順序的快捷方法是在QT里畫一張純紅、純綠、純藍(lán)的色塊圖看屏上三個顏色是否對應(yīng)。如果紅藍(lán)互換就把設(shè)備樹bgr字段改一下或者調(diào)整MADCTL位。4. QT界面應(yīng)用開發(fā)4.1 編譯帶linuxfb插件的QTIMX6ULL上跑QT交叉編譯時QPA插件至少得有l(wèi)inuxfb。這個插件是QT基礎(chǔ)平臺插件在configure時加上-linuxfb即可。我用的配置命令大致如下./configure -prefix /opt/qt5 \ -xplatform linux-arm-gnueabi-g \ -opensource -confirm-license \ -no-opengl -no-xcb -no-vulkan \ -no-eglfs -no-gtk \ -linuxfb \ -nomake tests -nomake examples \ -no-pch如果希望QT直接全屏鋪滿屏幕不需要桌面系統(tǒng)linuxfb是首選。編譯完成后把QT庫拷貝到開發(fā)板設(shè)置環(huán)境變量export QT_ROOT/opt/qt5 export LD_LIBRARY_PATH$QT_ROOT/lib:$LD_LIBRARY_PATH export QT_QPA_PLATFORMlinuxfb:fb/dev/fb0:size240x320:mmSize90x67 export QT_QPA_FB_FORCE_FULLSCREEN1mmSize這個參數(shù)建議設(shè)置成接近實際屏幕物理尺寸的值否則字體縮放可能不對。如果沒設(shè)置也沒關(guān)系QT會用默認(rèn)值對界面布局影響不大。有一點要注意QT的linuxfb后端默認(rèn)只做局部刷新它有一個臟矩形機制界面變動區(qū)域才上報給framebuffer。這意味著QT不是每幀全屏刷新畫簡單靜態(tài)界面時SPI壓力很小但動畫效果多了刷新率會明顯下降。4.2 畫一個旋轉(zhuǎn)正方體的棱項目源碼里的QT界面包含一個旋轉(zhuǎn)的正方體這個效果其實只用了QPainter沒有用到OpenGL。IMX6ULL不帶GPUOpenGL只能走軟渲染很吃力所以手動做三維投影反而是更靠譜的方案。實現(xiàn)思路分為幾步。定義8個頂點坐標(biāo)三維坐標(biāo)范圍在-1到1之間。通過旋轉(zhuǎn)矩陣?yán)@Y軸或Z軸旋轉(zhuǎn)。最后做正交投影到二維坐標(biāo)再通過QPainter的drawLine把12條棱畫出來。核心代碼思路如下void CubeWidget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.fillRect(rect(), Qt::black); painter.setPen(QPen(Qt::green, 2)); const float angle m_angle; // 由QTimer定時遞增 float box[8][3] { {-1,-1,-1},{ 1,-1,-1},{ 1, 1,-1},{-1, 1,-1}, {-1,-1, 1},{ 1,-1, 1},{ 1, 1, 1},{-1, 1, 1} }; QPoint pts[8]; for (int i 0; i 8; i) { float x box[i][0]; float y box[i][1] * cosf(angle) - box[i][2] * sinf(angle); float z box[i][1] * sinf(angle) box[i][2] * cosf(angle); int sx (int)(x * 80 width() / 2); int sy (int)(y * 80 height() / 2); pts[i] QPoint(sx, sy); } static const int edges[12][2] { {0,1},{1,2},{2,3},{3,0}, {4,5},{5,6},{6,7},{7,4}, {0,4},{1,5},{2,6},{3,7} }; for (int i 0; i 12; i) { painter.drawLine(pts[edges[i][0]], pts[edges[i][1]]); } }這個demo跑在320x240屏上很流暢30fps左右沒問題。關(guān)鍵技巧是QTimer定時器設(shè)為16ms或者33ms配合update()觸發(fā)重繪視覺上就是平滑旋轉(zhuǎn)。4.3 中文字體與資源打包SPI小屏跑QT中文字體是個容易忽略的細(xì)節(jié)。標(biāo)準(zhǔn)QT交叉編譯不帶中文字體直接顯示中文會變成方框。解決方法是把字體文件拷貝到開發(fā)板并在應(yīng)用啟動時加載。常見的做法是把文泉驛微米黑wqy-microhei.ttc或者思源黑體SourceHanSansCN-Regular.otf放到/usr/share/fonts目錄然后代碼里注冊#include QFontDatabase QFontDatabase::addApplicationFont(/usr/share/fonts/wqy-microhei.ttc); QFont font(WenQuanYi Micro Hei); font.setPointSize(12); app.setFont(font);字體文件比較大幾MB到十幾MB對于IMX6ULL的eMMC來說完全沒壓力。如果實在想省空間可以用Fontmin之類的工具裁剪出用到的幾個漢字幾百KB就搞定。不過對大部分項目來說直接放下整個字體文件最省事調(diào)試也方便。QSS資源文件、圖片資源正常用qrc打進(jìn)二進(jìn)制就行運行時不依賴額外文件這樣交付方便。唯一要注意的是尺寸大的圖片在SPI刷新下會有明顯拖影盡量少用大面積漸變和背景圖。4.4 觸摸輸入的接入如果MSP2402模組帶觸摸層QT輸入還需要單獨配置。電阻觸摸屏在IMX6ULL上通常接SPI或者ADC驅(qū)動用ads7846設(shè)備樹里注冊觸摸節(jié)點后會生成一個輸入設(shè)備事件節(jié)點一般是/dev/input/event0。這時候QT需要設(shè)置觸摸參數(shù)export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS/dev/input/event0如果是電容觸摸屏芯片常見的有GT9147、GT911、FT5x06等通過I2C接口連接設(shè)備樹里掛好驅(qū)動后同樣走evdev輸入事件。電容屏不需要校準(zhǔn)電阻屏必須先跑ts_calibrate生成校準(zhǔn)參數(shù)否則觸摸和顯示坐標(biāo)對不上。沒有觸摸時鼠標(biāo)可以用QT自帶的鼠標(biāo)插件或者通過tslib模擬。項目源碼里如果只顯示界面不需要交互可以完全不管輸入直接跑純顯示程序。5. 調(diào)試中常見的問題與排障實錄5.1 白屏、暗屏的常見原因白屏是SPI LCD遇到最多的問題我的經(jīng)驗是先從最簡單的可能查起。背光不亮導(dǎo)致的“黑屏”很多人誤以為白屏。先看背光GPIO是否被正確拉高最簡單的方法是用萬用表量背光引腳電壓。如果設(shè)備樹led-gpios沒寫fbtft不會管背光需要手動GPIO控制或者硬件上拉。真正白屏通常意味著ILI9341沒有執(zhí)行顯示命令。檢查幾點RST引腳是否有正常復(fù)位脈沖復(fù)位后有沒有延時足夠久SCLK和MOSI是否接線正確有沒有接反初始化序列是否完整0x29顯示命令有沒有發(fā)出去SPI速率是否過高導(dǎo)致命令傳輸錯誤可以先降到1MHz試那次調(diào)MSP2402白屏最后定位到就是設(shè)備樹里reg屬性沒寫對導(dǎo)致SPI子設(shè)備匹配不上系統(tǒng)在spidev下創(chuàng)建了/dev/spidev3.0但fbtft沒有任何反應(yīng)。改好reg后再啟動一切正常。5.2 花屏和閃屏排查花屏比白屏好定位至少說明屏在工作問題基本出在數(shù)據(jù)鏈路。最常見的花屏原因是SPI時鐘太高。杜邦線連接時線路電感電容會把波形拉得很難看10MHz時鐘下信號振鈴嚴(yán)重跳變沿不穩(wěn)定花屏非常普遍。解決辦法是把spi-max-frequency降到5MHz或更低或者換成短而粗的飛線有條件的話直接畫PCB走線會好很多。還有一種花屏是數(shù)據(jù)命令切換時序不對。DC引腳在傳輸?shù)谝粋€數(shù)據(jù)bit之前必須已經(jīng)穩(wěn)定如果DC由GPIO控制且切換太慢ILI9341會把命令當(dāng)數(shù)據(jù)解釋。fbtft內(nèi)部已經(jīng)處理了這個問題如果是自己寫用戶態(tài)驅(qū)動這里要注意。閃屏則多半和刷新策略有關(guān)。QT在linuxfb下做部分刷新但如果界面全是大面積變化SPI全屏刷新幀率只有20-30fps視覺上就會閃爍。可以試試把fps參數(shù)調(diào)低一點減少刷屏頻率或者減少Q(mào)T動畫幅度。5.3 顏色錯亂與鏡像顯示顏色不對大多數(shù)是BGR和RGB順序問題。ILI9341的MADCTL命令里有一個BGR位針對不同屏模組0x36設(shè)置的參數(shù)不同。fbtft設(shè)備樹里可以設(shè)置bgr字段或者在用戶態(tài)直接改顏色空間配置。我調(diào)試時先在QT里畫一幅紅綠藍(lán)三色條看到紅藍(lán)互換就改bgr改完重啟確認(rèn)。鏡像問題也是MADCTL的MX、MY位控制的。設(shè)備樹rotate 90可以整體旋轉(zhuǎn)但個別方向會有鏡像。比如rotate 90后左右反了可以再給MADCTL加一個鏡像位。fbtft里通??梢酝ㄟ^fb_var_screeninfo的rotate字段或者屏模組廠家的默認(rèn)初始化參數(shù)來調(diào)和。5.4 SPI信號質(zhì)量與布線經(jīng)驗最后講一點硬件層面的心得。SPI_CLK線上串一個小電阻是嵌入式里常見的做法一般22Ω左右。這個電阻能抑制信號振鈴減少過沖尤其對杜邦線連接場景效果明顯。靠近屏端放也可以靠近主控放也可以我習(xí)慣放在主控側(cè)。CS片選線上拉一個10k電阻到VCC防止控制器復(fù)位時CS電平不定導(dǎo)致屏幕誤觸發(fā)。如果CS懸空上電瞬間屏可能收到隨機數(shù)據(jù)進(jìn)入奇怪狀態(tài)。地線一定不要省。MOSI、SCLK、DC、CS全部高速切換參考地回路阻抗高的畫噪聲會耦合到信號線上。我試過只接一根細(xì)地線花屏概率直線上升接兩根粗地線后問題消失。最后再分享一個實用小經(jīng)驗調(diào)試初期不要直接用QT先在內(nèi)核起來后用命令行工具測屏。往/dev/fb0填充純色、畫幾條對角線確認(rèn)SPI鏈路完全穩(wěn)定后再啟動QT應(yīng)用。這樣一旦出問題你能快速知道是QT層的問題還是底層驅(qū)動的問題不會被一堆報錯帶偏方向。SPI小屏調(diào)試本身不難難的是把各個環(huán)節(jié)拆開獨立驗證這一步做好了后面任何界面問題都好解決。本文還有配套的精品資源點擊獲取