1. 項目緣起為什么是2.8寸SPI屏如果你玩過樹莓派大概率會和我一樣在某個時刻對那塊小小的、分辨率有限的官方屏幕感到不滿足。想顯示更多信息想有更靈活的交互但又不希望外設過于臃腫、接線復雜或者成本太高。這時候一塊2.8英寸、通過SPI接口驅動的LCD觸摸屏就成了一個非常“甜點”的選擇。我手頭這塊標著“2.8inch RPi LCD (A)”的屏幕就是這類產品的典型代表。它尺寸適中既能顯示比命令行豐富得多的圖形界面又不會像7寸屏那樣占用過多空間和GPIO資源。其核心賣點就是“簡單”一根排線直接插在樹莓派的GPIO排針上利用SPI和幾個GPIO引腳就能完成顯示和觸摸控制無需額外的USB轉接板或復雜的驅動板供電也直接從樹莓派取真正做到即插即用。但“簡單”的背后其實藏著不少值得深究的細節。為什么是SPI而不是DPI或HDMI2.8寸這個尺寸和常見的320x240分辨率搭配起來體驗如何所謂的“驅動”到底包含了哪些層次的工作在實際項目中除了點亮屏幕我們還會遇到哪些坑又能玩出哪些花樣這篇文章我就結合自己多次使用這類屏幕的經驗從硬件拆解、驅動原理、軟件配置到實戰應用為你完整梳理一遍目標是讓你不僅能點亮它更能用好它。2. 硬件深潛拆解“2.8inch RPi LCD (A)”的物理構成拿到一塊屏幕第一步不是急著上電而是先把它看明白。這塊2.8寸屏的硬件可以看作是由三個核心部分疊加而成的顯示面板、觸摸面板和驅動板。2.1 顯示核心ILI9341驅動IC與SPI接口掀開屏幕背面的屏蔽罩如果有的話或者查閱產品資料你會發現它的顯示驅動芯片大概率是ILI9341。這是一顆非常經典且廉價的TFT LCD控制器支持262K色18位RGB最大分辨率就是320x240。它之所以在開源硬件和DIY領域如此流行根本原因在于其接口的靈活性。ILI9341支持多種接口模式包括8位/16位并行8080系列接口以及我們這里用到的SPI串行外設接口。選擇SPI模式意味著數據傳輸從并行的十幾根線減少到3-4根線MOSI, MISO, SCK 外加一根可選的片選CS這極大地節省了寶貴的GPIO資源尤其對于GPIO數量并不算特別寬裕的樹莓派Zero/W系列來說是至關重要的。代價則是速度SPI的速率遠低于并行接口但對于320x240這種分辨率刷新一些UI界面、圖表數據是完全可以接受的全屏刷動畫則會比較吃力。注意有些屏幕為了在SPI下獲得稍好的刷新率會使用“8線SPI”模式即利用兩個SPI數據線MOSI1, MISO1, MOSI2, MISO2來同時傳輸數據但這需要主控支持雙路SPI且接線和驅動會更復雜。我們這塊屏大概率是標準的4線SPI。除了SPI數據線驅動屏幕還需要幾個重要的控制引腳DC (Data/Command) 這是一根關鍵引腳。它告訴ILI9341當前通過SPI發送的數據是命令如設置顯示區域、旋轉方向還是實際的像素數據。沒有它芯片無法正確解析數據流。RST (Reset) 復位引腳。用于對ILI9341進行硬件復位在初始化或出現異常時非常有用。BL (Backlight) 背光控制。通常連接到一個GPIO通過PWM脈沖寬度調制可以調節屏幕亮度。有些簡化版設計可能直接接VCC亮度就不可調了。2.2 觸摸層XPT2046電阻屏控制器這塊屏標注了“(A)”通常意味著它附帶了觸摸功能。對于這個尺寸和價位的屏幕搭載的幾乎肯定是電阻式觸摸屏而非電容屏。電阻屏的優勢是成本低且可以用任何物體包括手套、觸筆按壓操作缺點則是透光性稍差、不耐刮以及需要一定的按壓力度。觸摸功能的實現依賴于另一顆芯片——XPT2046。這是一款兼容ADS7843的4線電阻式觸摸屏控制器。它的工作邏輯是通過SPI接口注意它和ILI9341共享同一組SPI總線但使用不同的片選CS引腳與樹莓派通信。當你觸摸屏幕時XPT2046會測量按壓點的X軸和Y軸坐標對應的電壓值并將其轉換為數字信號通過SPI讀出。這里就引出了一個關鍵點SPI總線復用。樹莓派的同一組SPI如SPI0的MOSI、MISO、SCK引腳被同時連接到了ILI9341和XPT2046。樹莓派通過控制不同的片選CS引腳來“選中”當前要通信的設備。對ILI9341的CS拉低時與之通信對XPT2046的CS拉低時則讀取觸摸坐標。這種設計最大限度地節約了引腳。2.3 “驅動板”關鍵的引腳轉換與電平匹配嚴格來說這塊屏模塊自帶的那個小PCB不能算完整的“驅動板”更像是一個引腳轉換與電平適配板。它的核心作用有兩個物理接口轉換將屏幕柔性排線FPC上密集的引腳轉換到適合插在樹莓派GPIO排針上的2.54mm間距排母。電平匹配樹莓派的GPIO是3.3V邏輯電平而ILI9341和XPT2046通常也工作在3.3V。這個板子確保電源和信號電平一致有時還會集成一個簡單的背光驅動電路可能就是一個三極管。板上通常還會有幾個跳線帽用于選擇屏幕旋轉方向通過交換X/Y坐標映射或者配置其他硬件選項。務必根據你希望的物理安裝方向來設置這些跳線。3. 軟件驅動全景從內核到應用的四層架構硬件連接妥當后要讓屏幕工作起來就需要軟件驅動。這個過程并非一個“萬能驅動”就能搞定而是一個從底層到上層的完整棧。理解這個棧是解決一切驅動問題的鑰匙。3.1 第一層Linux內核中的SPI與FB設備驅動這是最底層的一環。樹莓派OSRaspbian / Raspberry Pi OS內核已經內置了BCM2835 SPI控制器驅動例如spi-bcm2835。當你啟用SPI接口后通過raspi-config或修改/boot/config.txt這個驅動負責管理SPI總線的時序、時鐘、中斷等硬件資源。在此之上我們需要一個幀緩沖Framebuffer設備驅動來管理顯示。對于ILI9341內核中并沒有直接可用的標準驅動。因此社區通常采用兩種方式fbtft項目這是一個開源的內核模塊集合為眾多SPI TFT屏幕提供Framebuffer驅動。你需要為ILI9341編譯并加載對應的模塊如fb_ili9341。加載后系統會出現一個/dev/fb1這樣的設備文件/dev/fb0是HDMI主顯示應用程序向這個設備寫入RGB數據驅動會通過SPI將數據發送給屏幕。廠商提供的預編譯內核/驅動很多屏幕賣家會提供定制化的內核鏡像或驅動安裝腳本。這些腳本的本質也是幫你編譯、配置和加載fbtft或類似的內核模塊。這一層驅動只負責最基礎的“點亮屏幕”和“顯示內存位圖”不涉及圖形加速、2D/3D繪制等高級功能。3.2 第二層觸摸屏輸入驅動evdev觸摸屏需要被系統識別為一個輸入設備。XPT2046的驅動通常以內核模塊形式提供如ads7846因為XPT2046兼容它。這個驅動會通過SPI讀取坐標并經過校準后將觸摸事件轉換為標準的Linux輸入事件。加載成功后你會在/dev/input/下看到類似event0的設備。更直觀的方法是使用evtest命令來測試sudo evtest選擇對應的設備觸摸屏幕你會看到實時輸出的坐標和按壓事件。這一步驗證了觸摸硬件和底層驅動是正常的。3.3 第三層顯示服務器與坐標變換X11/Wayland如果你的樹莓派運行著帶有桌面環境如Pixel的系統那么它一定運行著一個顯示服務器傳統的是X11Xorg較新的可能是Wayland。我們需要做兩件事將Framebuffer設備納入顯示服務器對于X11這通常通過在/usr/share/X11/xorg.conf.d/目錄下創建一個配置文件如99-fbdev.conf來實現告訴Xorg除了HDMIfb0之外還有另一個顯示設備fb1并為其指定位置如HDMI的右側RightOf。映射觸摸事件到正確的顯示區域觸摸驅動上報的坐標是物理屏幕的原始坐標。如果我們在X11中將fb1屏幕設置為鏡像模式或擴展模式的某個位置就需要通過工具如xinput來設置觸摸設備的坐標變換矩陣Coordinate Transformation Matrix讓觸摸位置和顯示位置對齊。這一步是觸摸屏“點不準”問題的根源所在。3.4 第四層應用層圖形庫SDL2, PyGame, GTK, Qt對于開發者而言直接操作Framebuffer或X11 API是繁瑣的。我們通常使用高級圖形庫。這些庫會自己處理與顯示服務器或Framebuffer的交互。SDL2 非常適合游戲和多媒體應用。它可以被配置為直接輸出到指定的Framebuffer設備SDL_VIDEODRIVERfbcon SDL_FBDEV/dev/fb1從而完全繞過X11獲得更低延遲和更直接的控制非常適合專用信息展示或嵌入式儀表盤。PyGame 基于SDL2的Python庫用法類似。GTK / Qt 大型的桌面應用框架。它們通常依賴于X11或Wayland。你需要確保顯示服務器正確配置了多屏幕然后應用程序窗口就可以被移動到副屏我們的LCD上顯示了。4. 實戰配置一步步點亮屏幕并校準觸摸理論說再多不如動手做一遍。以下是我在最新版Raspberry Pi OSBookworm上針對這類SPI LCD的通用配置流程其中包含了許多腳本不會告訴你的細節。4.1 硬件連接與系統準備首先確保屏幕排線牢固地插在樹莓派的GPIO排針上注意方向通常屏幕的排線插座和樹莓派GPIO的“PIN 1”標識要對齊。然后啟動樹莓派并通過SSH或HDMI主屏進行操作。第一步是啟用SPI接口。你可以使用sudo raspi-config進入Interface Options-SPI選擇Yes啟用。或者直接編輯/boot/config.txt文件確保包含以下行dtparamspion保存并重啟。4.2 安裝與配置Framebuffer驅動FBTFT這里我們使用最通用的fbtft方法。首先安裝必要的編譯工具和內核頭文件sudo apt update sudo apt install git raspberrypi-kernel-headers build-essential dkms然后克隆并安裝fbtft的DKMS版本這樣內核更新后驅動會自動重新編譯git clone https://github.com/notro/fbtft.git cd fbtft sudo ./install安裝腳本會編譯模塊并將其加入DKMS管理。接下來我們需要在/boot/config.txt中添加設備樹覆蓋Device Tree Overlay來具體描述我們的屏幕。這是最關鍵的一步參數不對屏幕就不亮。添加如下內容注釋很重要# 啟用SPI dtparamspion # 加載ILI9341的設備樹覆蓋并指定關鍵參數 dtoverlayfb-ili9341 # 旋轉方向0度根據你的安裝方式調整090180270 dtoverlayfb-ili9341:rotate0 # 指定SPI總線速率單位MHz。30是一個比較穩定的值太高可能花屏 dtoverlayfb-ili9341:speed30000000 # 關鍵指定樹莓派GPIO引腳與屏幕引腳的對應關系。 # 格式gpiodc,reset,cs,led # 你需要根據屏幕PCB的接線圖來確定。以下是一個常見接法對應BCM編碼 # dc25, reset24, cs8, led18 (背光控制) dtoverlayfb-ili9341:gpio25,24,8,18保存文件執行sudo reboot重啟。重啟后檢查驅動是否加載成功lsmod | grep fb_ili9341 # 應看到fb_ili9341模塊 ls /dev/fb* # 應看到除了fb0還有fb1如果看到/dev/fb1恭喜顯示部分的基礎驅動已經就緒。你可以用一個簡單命令測試sudo apt install fbi sudo fbi -d /dev/fb1 -T 1 -noverbose -a some_image.jpg這條命令使用fbi幀緩沖圖像查看器在/dev/fb1上全屏顯示一張圖片。如果圖片能正常顯示說明從SPI到ILI9341的整個通路是暢通的。4.3 配置觸摸屏驅動與校準接下來處理觸摸。XPT2046的驅動模塊通常是ads7846。我們需要通過設備樹覆蓋來加載并配置它。在/boot/config.txt中繼續添加# 加載ads7846設備樹覆蓋用于XPT2046觸摸芯片 dtoverlayads7846 # 關鍵參數指定觸摸芯片連接的GPIO # cs7 # 觸摸芯片的片選引腳BCM編碼根據你的接線修改 # penirq17 # 觸摸中斷引腳用于通知有觸摸動作根據接線修改 # penirq_pull2 # 中斷引腳上拉模式2表示上拉 # swapxy1 # 是否交換X/Y坐標根據屏幕物理方向調整 # xmin200 # 原始坐標最小值校準后調整 # xmax3900 # 原始坐標最大值校準后調整 # ymin200 # ymax3900 # xohms150 # 觸摸屏的X軸電阻通常150單位歐姆 # 一個完整的示例參數需根據實際測量調整 dtoverlayads7846,cs7,penirq17,penirq_pull2,swapxy0,xmin200,xmax3900,ymin200,ymax3900,xohms150保存并重啟。重啟后檢查觸摸設備ls /dev/input/by-path/ # 應該能看到一個以“spi”開頭的事件設備 sudo evtest # 運行后選擇對應的spi設備觸摸屏幕看是否有坐標輸出如果evtest有反應說明底層觸摸驅動正常。但此時的坐標是原始的、未校準的且可能不對應屏幕的顯示區域。進行觸摸校準對于X11環境最常用的校準工具是xinput_calibrator。sudo apt install xinput-calibrator首先你需要確保圖形界面X11正在使用這個觸摸設備。你可以通過xinput list查看所有輸入設備找到名字里帶“ADS7846”或“touch”的設備記下其id。然后運行校準程序。一個更直接的方法是暫時將顯示輸出切換到我們的LCD屏fb1上進行校準。這可以通過在命令行指定DISPLAY來實現但過程稍復雜。一個更穩妥的“土辦法”是暫時注釋掉HDMI的顯示讓系統只使用我們的SPI LCD作為唯一顯示。在/boot/config.txt中臨時添加hdmi_blanking1或hdmi_ignore_edid0xa5000080并重啟這樣HDMI可能無輸出桌面會顯示在fb1上。在SPI LCD顯示的桌面上打開終端直接運行xinput_calibrator。程序會提示你依次點擊屏幕四個角出現的十字標志。校準完成后程序會輸出一段Section InputClass的配置文本。你需要將其保存到/etc/X11/xorg.conf.d/99-calibration.conf文件中。這個文件包含了校正矩陣能永久修正觸摸坐標。校準完成后記得恢復HDMI的配置。此后在X11桌面環境下觸摸就應該基本準確了。4.4 配置雙屏顯示擴展/鏡像如果你希望SPI LCD作為HDMI主屏的擴展或鏡像需要在X11中配置。創建文件/etc/X11/xorg.conf.d/99-fbdev.confSection Device Identifier HDMI Driver modesetting Option Primary true EndSection Section Device Identifier SPILCD Driver fbdev Option fbdev /dev/fb1 EndSection Section Monitor Identifier HDMI-Monitor EndSection Section Monitor Identifier SPILCD-Monitor EndSection Section Screen Identifier HDMI-Screen Device HDMI Monitor HDMI-Monitor EndSection Section Screen Identifier SPILCD-Screen Device SPILCD Monitor SPILCD-Monitor EndSection Section ServerLayout Identifier MultiDisplay Screen 0 HDMI-Screen Screen 1 SPILCD-Screen RightOf HDMI-Screen # 擴展模式SPI屏在HDMI右側 # 如果要鏡像模式使用 Option Clone true InputClass Touchscreen calibration MatchProduct ADS7846 Touchscreen # 與你的觸摸設備名匹配 # 下面這行是xinput_calibrator輸出的校準數據必須填寫 Option CalibrationMatrix 1.02 0. -0.02 0. 1.03 -0.01 0. 0. 1. Option SwapAxes 0 EndSection EndSection這個配置定義了雙屏并將觸摸校準矩陣應用到了觸摸設備上。重啟圖形界面sudo systemctl restart lightdm或直接重啟系統生效。5. 性能調優與常見問題排查配置成功只是第一步要讓體驗流暢還需要一些調優。5.1 SPI速率與刷新率的權衡在/boot/config.txt中設置的speed參數單位是Hz30MHz即30000000直接影響刷屏速度。提高它可以增加刷新率但過高的速率可能導致SPI信號不穩定屏幕出現雪花、花屏或根本點不亮。ILI9341的SPI時鐘極限通常在30-40MHz左右但樹莓派的GPIO和布線質量也會影響穩定性。建議從20MHz開始測試逐步增加直到出現不穩定現象然后退回一檔。穩定的30MHz通常是安全值。你可以通過一個簡單的測試程序來估算實際刷新率。例如寫一個循環用SDL2全屏填充不同顏色計算每秒能完成多少次。對于320x24030MHz SPI下全屏刷新3202402字節150KB的理論幀率可能在30-60fps但受CPU處理、SPI傳輸協議開銷等影響實際應用幀率會低很多。5.2 內存與CPU占用優化直接操作Framebuffer進行全屏刷新是CPU密集型的。優化方法包括局部更新只刷新屏幕上發生變化的部分區域而不是整個屏幕。這需要應用層邏輯支持。使用雙緩沖在內存中完成一幀畫面的繪制然后一次性通過SPI發送到屏幕。這可以避免屏幕撕裂但需要額外內存。降低顏色深度ILI9341支持18位色262K但通過SPI傳輸時你可以選擇傳輸16位色RGB565這樣每像素數據量從3字節減少到2字節能顯著提升傳輸速度。很多圖形庫如SDL2都支持設置RGB565模式。5.3 典型問題與解決方案問題1屏幕點亮但花屏、錯位或顏色異常。檢查首先確認/boot/config.txt中的rotate參數是否與屏幕物理安裝方向匹配。0°、90°、180°、270°都試試。檢查確認gpio參數dc, reset, cs, led的引腳編號是否正確。務必使用BCM編碼即GPIO編號而不是物理引腳編號。最可靠的依據是屏幕供應商提供的原理圖或接線表。檢查SPI速率speed是否過高。嘗試降低到20MHz或10MHz測試。問題2觸摸完全無反應。檢查ads7846設備樹覆蓋是否加載。dmesg | grep ads7846查看內核信息。檢查cs和penirq引腳定義是否正確。中斷引腳penirq必須正確連接否則驅動無法感知觸摸事件。檢查使用evtest直接測試底層事件。如果evtest都沒輸出問題在硬件連接或驅動加載層面。問題3觸摸有反應但點不準坐標錯亂。首要任務運行xinput_calibrator進行校準并正確保存校準矩陣到X11配置中。檢查swapxy,xmin/xmax/ymin/ymax這些參數。如果校準后仍不準可以手動調整這些原始坐標范圍。使用evtest記錄下觸摸屏幕四個角時輸出的原始坐標值填入設備樹覆蓋參數中能提供一個更準確的初始映射。檢查在雙屏模式下觸摸區域是否映射到了正確的屏幕。使用xinput map-to-output [觸摸設備id] [屏幕名稱]命令可以將觸摸設備綁定到指定的X屏幕。問題4系統啟動后屏幕不亮但用fbi命令可以顯示圖片。原因這通常是因為圖形桌面環境X11或Wayland沒有正確配置使用/dev/fb1。你需要按照第4.4節配置雙屏或者配置為單屏輸出。問題5SPI LCD顯示內容但HDMI無輸出或反之。檢查/etc/X11/xorg.conf.d/下的配置文件確保ServerLayout中兩個Screen的排列和克隆設置符合你的預期。嘗試使用命令行工具xrandr來動態調整屏幕布局這比修改配置文件重啟更快捷。6. 超越基礎高級應用與項目思路當屏幕能穩定工作后就可以用它來做一些有趣的項目了。6.1 打造專屬信息儀表盤這是最經典的應用。你可以編寫一個Python腳本使用psutil庫獲取樹莓派的CPU溫度、負載、內存使用、網絡流量等信息然后使用PILPython Imaging Library或pygame繪制成圖表和數字最后通過SDL2輸出到SPI LCD上。讓這塊小屏幕成為你樹莓派主機的實時監控面板。關鍵技巧為了避免頻繁全屏刷新可以只更新數據變化的區域。例如將屏幕劃分為幾個固定的“窗口”分別顯示不同信息每個窗口獨立更新。6.2 構建輕量級圖形界面GUI對于需要簡單交互的項目你可以使用tkinterPython自帶或更輕量的guizero庫來創建窗口。雖然這些庫默認針對X11但通過一些配置可以將窗口直接顯示在Framebuffer上需要設置DISPLAY環境變量或使用特定的后端。更直接的方法是使用PyGame它原生支持Framebuffer非常適合制作全屏的、帶觸摸交互的嵌入式應用界面比如智能家居中控、實驗室設備控制面板等。6.3 結合傳感器與物理按鈕SPI LCD的GPIO引腳并沒有被全部占用。你可以利用樹莓派上剩余的GPIO連接各種傳感器溫濕度、光照、運動或物理按鈕。在屏幕上實時顯示傳感器數據并通過觸摸屏或物理按鈕進行控制形成一個完整的嵌入式人機交互系統。例如制作一個帶有觸摸屏的溫濕度環境監測站屏幕同時顯示實時曲線和歷史數據。6.4 無頭模式下的控制與調試終端對于運行在無頭模式無HDMI顯示器的樹莓派服務器這塊SPI LCD可以作為一個本地的“應急”控制臺。通過修改系統配置可以將一個虛擬終端如tty1的輸出重定向到/dev/fb1并配合USB鍵盤實現一個獨立的控制終端。這在網絡出現故障時進行本地調試非常有用。實現這個功能需要用到fbcon幀緩沖控制臺和fbcp幀緩沖拷貝等工具配置較為復雜但可行性很高。這塊小小的2.8寸SPI LCD其價值遠不止于“點亮”。從理解SPI總線復用、內核驅動棧到調試觸摸校準、優化顯示性能整個過程是對嵌入式Linux系統軟硬件結合的一次絕佳實踐。它成本低廉但涉及的知識點卻非常全面。我最開始用它只是為了顯示IP地址后來卻因為它把Linux的輸入子系統、X11配置、設備樹覆蓋都摸了一遍。現在它已經是我很多樹莓派項目中不可或缺的交互窗口。希望這篇超詳細的指南能幫你繞過我踩過的那些坑順利地把這塊屏幕的潛力都發揮出來。