How to use DMA2D on STM32H7
前言
近期因為需要,所以需要幫客戶弄thermal camera顯示在MCU STM32H7顯示面板,使用STM32H750-DK,而這個開發版使用的顯示面板不是SPI驅動,所以只好開始學習LTDC+DMA2D,這個章節將會先介紹DMA2D使用方式與介紹
DMA2D的簡介
在實際使用LTDC控制器控制液晶屏時,使LTDC正常工作後,往配置好的顯存地址寫入要顯示的像素數據,LTDC就會把這些數據從顯存搬運到液晶面板進行顯示, 而顯示數據的容量非常大,所以我們希望能用DMA來操作,針對這個需求,STM32專門定制了DMA2D外設,它可用於快速繪製矩形、直線、分層數據混合、 數據複製以及進行圖像數據格式轉換,可以把它理解為圖形專用的DMA
DMA2D工作模式
- 寄存器到存储器
- 存储器到存储器
- 存储器到存储器并执行像素颜色格式转换
- 存储器到存储器且支持像素颜色格式转换和透明度混合
DMA2D操作
DMA2D的常用API要熟練掌握,後面的GUI的底層驅動加速,JPEG硬解,攝像頭等部分都要用到。這里為大家介紹如下幾個常用API:
- _DMA2D_Fill–>此函數主要用於LCD的顏色填充
- _DMA2D_Copy–>此函數用於從前景層複製指定區域的顏色數據到目標區域
- _DMA2D_MixColorsBulk–>此函數用於前景層和目標區域的顏色混合,並將混合後的圖像輸出到目標區域。
- _DMA2D_AlphaBlendingBulk–>此函數用於前景層和背景層的顏色混合,並將混合後的圖像輸出到目標區域。
- _DMA2D_DrawAlphaBitmap–>此函數用於在指定位置顯示ARGB8888格式位圖。
framebuffer的這種特性使得我們不能簡單使用memset這類高效的操作來實現矩形區域的填充。這邊下面展示2種方式作為比較
for(int y = ys; y < ys + height; y++){
for(int x = xs; x < xs + width; x++){
framebuffer[y][x] = color;
}
}
通常情況下,我們會使用以下方式的雙重循環來填充任意矩形,其中xs和ys是矩形左上角在屏幕上的坐標,width和height表示矩形的寬和高,color表示需要填充的顏色:
static inline void DMA2D_Fill( void * pDst, uint32_t width, uint32_t height, uint32_t lineOff, uint32_t pixelFormat, uint32_t color) {
/* DMA2D配置 */
DMA2D->CR = 0x00030000UL; // 配置为寄存器到储存器模式
DMA2D->OCOLR = color; // 设置填充使用的颜色,格式应该与设置的颜色格式相同
DMA2D->OMAR = (uint32_t)pDst; // 填充区域的起始内存地址
DMA2D->OOR = lineOff; // 行偏移,即跳过的像素,注意是以像素为单位
DMA2D->OPFCCR = pixelFormat; // 设置颜色格式
DMA2D->NLR = (uint32_t)(width << 16) | (uint16_t)height; // 设置填充区域的宽和高,单位是像素
/* 启动传输 */
DMA2D->CR |= DMA2D_CR_START;
/* 等待DMA2D传输完成 */
while (DMA2D->CR & DMA2D_CR_START) {}
}