14 - VDMA彩條顯示實驗

文章目錄

  • 1 實驗任務
  • 2 系統框圖
  • 3 硬件設計
  • 4 軟件設計

1 實驗任務

本實驗任務是PS端寫彩條數據至DDR3內存中,然后通過PL端的VDMA IP核將彩條數據通過HDMI接口輸出顯示。

2 系統框圖

本實驗是用HDMI接口固定輸出1080P的彩條圖,所以:

  1. rgb2lcd模塊實際是rgb2dvi模塊
  2. AXI GPIO不存在,因為不需要讀取LCD屏幕的ID
  3. 動態時鐘配置改為PLL,輸出固定頻率,與AXI-Interconnect不連
  4. VTC輸出固定時序,與AXI-Interconnect不連
    在這里插入圖片描述

3 硬件設計

注意事項:

  1. VTC的clken引腳
    • 該引腳不連接,VTC也能正常工作
    • pg016中描述該引腳是"Video Core active-High Clock Enable",即高有效
    • 在Block Design中添加VTC后,clken引腳前邊有個小圓圈,且雙擊該引腳,Polarity參數顯示為ACTIVE_LOW,即低有效
    • 將該引腳接常量1,視頻輸出正常
    • 將該引腳接常量0,視頻無法輸出,VTC未工作
    • 結論:以文檔為準,clken高電平有效
  2. rgb2dvi模塊
    • 使用正點原子的rgb2dvi模塊,數據的3個字節是G在中間,R和B在兩頭
    • 使用Digilent的rgb2dvi模塊,數據的3個字節是B在中間,R和G在兩頭(調試時一臉懵逼)
      在這里插入圖片描述

4 軟件設計

注意事項:

  1. PS往DDR3寫入數據后,要使用Xil_DCacheFlushRange刷新;
  2. run_triple_frame_buffer函數并非只能用于三幀緩存的情況,實際1-32幀緩存均可使用該函數(取名triple可能和VDMA模式使用三幀緩存有關);ReadSetup函數和WriteSetup函數會根據VDMA配置時選擇的Frame Buffers數量設置相應數量的幀緩沖區起始地址;本實驗選擇Frame Buffers數量=1,PS端只往DDR3中寫入一幀彩條圖;
  3. XAxiVdma_DmaStop函數往VDMACR寄存器的bit0寫0(Run / Stop controls the running and stopping of the VDMA channel. ),當前VDMA操作完成后停止(0 = Stop – VDMA stops when current (if any) VDMA operations are complete)
/***************************** Include Files *********************************/
#include "stdio.h"
#include "xparameters.h"
#include "xstatus.h"
#include "xaxivdma.h"
#include "vdma_api.h"
#include "xil_cache.h"
#include "xuartps.h"
#include "sleep.h"
/************************** Constant Definitions *****************************/
#define VDMA_DEVICE_ID		XPAR_AXIVDMA_0_DEVICE_ID
#define IMAGE_WIDTH			1920
#define IMAGE_HEIGHT		1080
#define MEMORY_BASEADDR		XPAR_PS7_DDR_0_S_AXI_BASEADDR#define UART_DEVICE_ID		XPAR_XUARTPS_0_DEVICE_ID
#define UART_BASEADDR    	XPAR_XUARTPS_0_BASEADDR
/**************************** Type Definitions *******************************//***************** Macros (Inline Functions) Definitions *********************//************************** Function Prototypes ******************************/
s32  UartPsInit(XUartPs *UartPsInstPtr, XUartPsFormat* UartFormatPtr);void GenPureColor(u8* DestAddr, u32 ImageWidth, u32 ImageHeight);
void GenColorBar(u8* DestAddr, u32 ImageWidth, u32 ImageHeight);
/************************** Variable Definitions *****************************/
XAxiVdma VdmaInst;
XUartPs UartInst;int FrameBufferAddr = (MEMORY_BASEADDR + 0x02000000);XUartPsFormat UartFormat = {XUARTPS_DFT_BAUDRATE,     // 115200XUARTPS_FORMAT_8_BITS,XUARTPS_FORMAT_NO_PARITY,XUARTPS_FORMAT_1_STOP_BIT
};
/*****************************************************************************/int main()
{//int Status;u8* VdmaBufferAddr = (u8*)FrameBufferAddr;char cmd;// 串口初始化Status = UartPsInit(&UartInst, &UartFormat);if (Status != XST_SUCCESS) {printf("UART Initialization Failed.\n");return XST_FAILURE;}// 寫入純色圖(用于確定RGB的字節位置)
//	GenPureColor(VdmaBufferAddr, (u32)IMAGE_WIDTH, (u32)IMAGE_HEIGHT);// 寫入彩條圖GenColorBar(VdmaBufferAddr, (u32)IMAGE_WIDTH, (u32)IMAGE_HEIGHT);//Status = run_triple_frame_buffer(&VdmaInst, VDMA_DEVICE_ID, IMAGE_WIDTH, IMAGE_HEIGHT, FrameBufferAddr, 0, 0);if (Status == XST_FAILURE) {printf("VDMA Run Failed.\n");}//printf("VDMA Control Ready (s=start, q=stop):\n");while (1) {if (XUartPs_IsReceiveData(UART_BASEADDR)) {cmd = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET);if (cmd == 's') {  // 啟動VDMAif (XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_READ) == XST_SUCCESS) {printf("VDMA Start Succeeded.\n");} else {printf("VDMA Start Failed.\n");}}else if (cmd == 'q') {  // 停止VDMAXAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_READ);printf("VDMA Stop Succeeded.\n");}}usleep(10000); // 降低CPU占用}//return 0;
}
/*****************************************************************************/
s32 UartPsInit(XUartPs *UartInstPtr, XUartPsFormat* UartFormatPtr)
{//s32 Status;XUartPs_Config *UartConfigPtr;// 查找UART配置UartConfigPtr = XUartPs_LookupConfig(UART_DEVICE_ID);if(NULL == UartConfigPtr){return XST_FAILURE;}// 初始化UARTStatus = XUartPs_CfgInitialize(UartInstPtr, UartConfigPtr, UartConfigPtr->BaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}// 設置UART數據格式XUartPs_SetDataFormat(UartInstPtr, UartFormatPtr);// 設置UART操作模式XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_NORMAL);//return XST_SUCCESS;
}
/*****************************************************************************/
void GenPureColor(u8* DestAddr, u32 ImageWidth, u32 ImageHeight)
{// 禁用緩存(如果目標內存是非緩存區域)Xil_DCacheDisable();for (u32 y = 0; y < ImageHeight; y++) {for (u32 x = 0; x < ImageWidth; x++) {// 計算當前像素的內存位置(3字節/像素)u32 PixelOffset = (y * ImageWidth + x) * 3;u8* PixelAddr = DestAddr + PixelOffset;// 寫入RGB三個字節PixelAddr[0] = 0x00;PixelAddr[1] = 0x00;PixelAddr[2] = 0xff;}}// 如果需要,刷新緩存Xil_DCacheFlushRange((INTPTR)DestAddr, ImageWidth * ImageHeight * 3);//return;
}/*****************************************************************************/
void GenColorBar(u8* DestAddr, u32 ImageWidth, u32 ImageHeight)
{// 定義8種顏色(R, G, B順序)const u8 color_bars[8][3] = {{0x00, 0x00, 0x00}, // 黑{0xff, 0xff, 0xff}, // 白{0xff, 0x00, 0x00}, // 藍{0x00, 0xff, 0x00}, // 綠{0x00, 0x00, 0xff}, // 紅{0xff, 0xff, 0x00}, // 青{0xff, 0x00, 0xff}, // 紫{0x00, 0xff, 0xff}  // 黃};// 計算每個色條的寬度u32 BarWidth = ImageWidth / 8;// 禁用緩存(如果目標內存是非緩存區域)Xil_DCacheDisable();for (u32 y = 0; y < ImageHeight; y++) {for (u32 x = 0; x < ImageWidth; x++) {// 計算當前色條索引u32 BarIndex = x / BarWidth;// 計算當前像素的內存位置(3字節/像素)u32 PixelOffset = (y * ImageWidth + x) * 3;u8* PixelAddr = DestAddr + PixelOffset;// 寫入RGB三個字節PixelAddr[0] = color_bars[BarIndex][0];PixelAddr[1] = color_bars[BarIndex][1];PixelAddr[2] = color_bars[BarIndex][2];}}// 如果需要,刷新緩存Xil_DCacheFlushRange((INTPTR)DestAddr, ImageWidth * ImageHeight * 3);//return;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901099.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901099.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901099.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HarmonyOS-ArkUIV2裝飾器-@Param:組件外部輸入

上文我們了解了@Local裝飾器 ,講明了Local裝飾器不允許外部傳入值對其進行初始化。詳見: HarmonyOS-ArkUI V2裝飾器@Local裝飾器:組件內部狀態-CSDN博客。 但總有場景是需要外部組件傳值過來,然后本組件接收這個值這種場景的。而且很多情況下,一個狀態變量的作用范圍會是…

Java從入門到“放棄”(精通)之旅——運算符③

&#x1f31f;Java從入門到“放棄”&#xff08;精通&#xff09;之旅&#x1f680;&#xff1a;運算符深度解析 引言&#xff1a;運算符的本質與價值 作為Java語言的核心組成部分&#xff0c;運算符是構建程序邏輯的基礎元素。它們不僅僅是簡單的數學符號&#xff0c;更是程…

【sgSpliter】自定義組件:可調整寬度、高度、折疊的分割線

sgSpliter.vue <template><!-- 注意&#xff1a;父組件position必須是relative、absolute或fixed&#xff0c;不建議直接在綁定:data后面用"{屬性}"&#xff0c;建議單獨在script中聲明data&#xff0c;避免拖拽過程重復調用 --><div :class"$…

Ningx負載均衡

Ningx負載均衡 upstream(上游)配置負載均衡1、weight&#xff08;加權輪詢&#xff09;2、ip_hash&#xff08;負載均衡&#xff09;3、url hash負載均衡4、least_conn&#xff08;最小連接負載均衡&#xff09; upstream(上游)配置負載均衡 Nginx負載均衡 參考: nginx從安裝…

一個插件,免費使用所有頂級大模型(Deepseek,Gpt,Grok,Gemini)

DeepSider是一款集成于瀏覽器側邊欄的AI對話工具&#xff0c;可免費使用所有頂級大模型 包括GPT-4o&#xff0c;Grok3,Claude 3.5 Sonnet,Claude 3.7,Gemini 2.0&#xff0c;Deepseek R1滿血版等 以極簡交互與超快的響應速度&#xff0c;完成AI搜索、實時問答、內容創作、翻譯、…

眾趣科技丨數字孿生技術,賦能交通公共設施管理數字化升級

春節假期期間&#xff08;1 月 21 日至 2 月 4 日&#xff09;&#xff0c;作為中國春節申遺成功后的首個春運&#xff0c;交通出行格外火熱&#xff0c;全社會跨區域流動量超 23 億人次&#xff0c;這一數據創下了歷史新高。 面對如此龐大的客流量&#xff0c;傳統的交通管理方…

Linux 入門五:Makefile—— 從手動編譯到工程自動化的蛻變

一、概述&#xff1a;Makefile—— 工程編譯的 “智能指揮官” 1. 為什么需要 Makefile&#xff1f; 手動編譯的痛點&#xff1a;當工程包含數十個源文件時&#xff0c;每次修改都需重復輸入冗長的編譯命令&#xff08;如gcc file1.c file2.c -o app&#xff09;&#xff0c;…

Python-Django+vue二手電子設備交易平臺功能說明

?(^_-) 上千個精美定制模板,各類成品Java、Python、PHP、Android畢設項目,歡迎咨詢。 ?(^_-) 程序開發、技術解答、代碼講解、文檔,??文末獲取源碼+數據庫+文檔?? ??軟件下載 | 實戰案例 ??文章底部二維碼,可以聯系獲取軟件下載鏈接,及項目演示視頻。 本項目…

數據庫管理工具實戰:IDEA 與 DBeaver 連接 TDengine(二)

五、DBeaver 連接 TDengine 實戰 5.1 安裝 DBeaver 下載安裝包&#xff1a;訪問 DBeaver 官方網站&#xff08;https://dbeaver.io/download/ &#xff09;&#xff0c;根據你的操作系統選擇合適的安裝包。如果是 Windows 系統&#xff0c;下載.exe 格式的安裝文件&#xff1…

Spring Boot接口返回Long類型的數據時丟失精度的全局處理

1、問題 當實體類中的字段為Long類型時&#xff0c;通過Ajax請求返回給前段&#xff0c;在js中數據會丟失精度 直接通過postman請求或通過瀏覽器請求&#xff0c;看下響應則不會丟失精度 2、處理方式 1、使用JsonSerialize注解 JsonSerialize(using ToStringSerializer.…

英偉達Llama-3.1-Nemotron-Ultra-253B-v1語言模型論文快讀:FFN Fusion

FFN Fusion: Rethinking Sequential Computation in Large Language Models 代表模型&#xff1a;Llama-3.1-Nemotron-Ultra-253B-v1 1. 摘要 本文介紹了一種名為 FFN Fusion 的架構優化技術&#xff0c;旨在通過識別和利用自然并行化機會來減少大型語言模型&#xff08;LLM…

Django學習記錄-1

Django學習記錄-1 雖然網上教程都很多&#xff0c;但是感覺自己記錄一下才屬于自己&#xff0c;之后想找也方面一點&#xff0c;文采不佳看的不爽可繞道。 參考貼 從零開始的Django框架入門到實戰教程(內含實戰實例) - 01 創建項目與app、加入靜態文件、模板語法介紹&#xff…

Python爬蟲第7節-requests庫的高級用法

目錄 前言 一、文件上傳 二、Cookies 三、會話維持 四、SSL證書驗證 五、代理設置 六、超時設置 七、身份認證 八、Prepared Request 前言 上一節&#xff0c;我們認識了requests庫的基本用法&#xff0c;像發起GET、POST請求&#xff0c;以及了解Response對象是什么。…

Python 要致富先修路

今天準備在原有基礎上重新深入學習并記錄python學習進程。 # 整體思路 不廢話&#xff1a; 階段1&#xff1a;精選入門電子教程堅持學習&#xff1b; 階段2&#xff1a;跟著教程學習代碼思維&#xff0c;做好學習筆記并構建知識庫方便以后速查&#xff1b; 階段3&#xff…

微服務無感發布實踐:基于Nacos的客戶端緩存與故障轉移機制

微服務無感發布實踐&#xff1a;基于Nacos的客戶端緩存與故障轉移機制 背景與問題場景 在微服務架構中&#xff0c;服務的動態擴縮容、滾動升級是常態&#xff0c;而服務實例的上下線需通過注冊中心&#xff08;如Nacos&#xff09;實現服務發現的實時同步。但在實際生產環境…

2025年的Android NDK 快速開發入門

十年前寫過一篇介紹NDK開發的文章《Android實戰技巧之二十三&#xff1a;Android Studio的NDK開發》&#xff0c;今天看來已經發生了很多變化&#xff0c;NDK開發變得更加容易了。下面就寫一篇當下NDK開發快速入門。 **原生開發套件 (NDK) **是一套工具&#xff0c;使開發者能…

Shell 編程之條件語句

目錄 條件測試操作 文件測試 整數值比較 字符串比較 邏輯測試 if 條件語句 if語句的結構 1、單分支 if 語句 2、雙分支 if 語句 3、多分支 if 語句 if語句應用實例 1、單分支 if 語句應用 2、雙分支 if 語句應用 3、多分支 if 語句應用 case 分支語句 case語句的結構 case語…

【模板】縮點

洛谷p3387 思路: 算法:tarjan算法 根據題意,我們只要找到一個路徑,使得最終權重最大即可,首先,根據題目可知,如果一個點在一個環上,那么我們就將這整個環都選上,題目上允許我們能夠重復走,因此,我們可以將環縮成點,將環所稱點后,就可以轉換成樹,從沒有父節點的結點開始,我們向…

js觸發隱式類型轉換的場景

JavaScript 的隱式類型轉換&#xff08;Implicit Type Coercion&#xff09;會在某些操作或上下文中自動觸發&#xff0c;將值從一種類型轉換為另一種類型。以下是常見的觸發場景&#xff1a; 1. 使用 &#xff08;寬松相等&#xff09;比較時 會嘗試將兩邊的值轉換為相同類型后…

c++將jpg轉換為灰度圖

c將jpg轉換為灰度圖 step1:添加依賴 下載這兩個文件&#xff0c;放在cpp同一目錄下&#xff0c;編譯生成 https://github.com/nothings/stb/blob/master/stb_image_write.h https://github.com/nothings/stb/blob/master/stb_image.hstep2:C:\Users\wangrusheng\source\repos…