完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
本章节为大家讲解DMA2D,实际项目中显示屏的加速全靠它了,而且性能也比较给力。
目录
第55章 STM32H7的图形加速器DMA2D的基础知识和HAL库API
55.1 初学者重要提示
55.2 DMA2D基础知识
55.2.1 DMA2D硬件框图
55.2.2 DMA2D工作模式
55.2.3 前景层和背景层的输入以及颜色格式转换
55.2.4 前景层和背景层混合
55.2.5 DMA2D输出颜色格式
55.3 DMA2D的HAL库用法
55.3.1 DMA2D寄存器结构体DMA2D_TypeDef
55.3.2 DMA2D参数初始化结构体DMA2D_InitTypeDef
55.3.3 DMA2D的图层结构体DMA2D_LayerCfgTypeDef
55.3.4 DMA2D句柄结构体DMA2D_HandleTypeDef
55.3.5 DMA2D初始化流程总结
55.4 源文件stm32h7xx_hal_dma2d.c
55.4.1 函数HAL_DMA2D_Init
55.4.2 函数HAL_DMA2D_ConfigLayer
55.4.3 函数HAL_DMA2D_Start_IT
55.4.4 函数HAL_DMA2D_BlendingStart_IT
55.5 总结
DMA2D主要实现了两个功能,一个是DMA数据传输功能,另一个是2D图形加速功能。
主要是两种方式,一个是寄存器到存储器,另一个是存储器到存储器。通过DMA可以大大降低CPU的利用率。
支持硬件的颜色格式转换和Alpha混合效果。
认识一个外设,最好的方式就是看它的框图,方便我们快速地了解DMA2D的基本功能,然后再看手册了解细节。框图如下所示:
通过这个框图,我们可以得到如下信息:
AXI 总线时钟输入。
DMA2D全局中断输出。
CLUT传输完成信号输出,可以触发MDMA。
传输完成信号输出,可以触发MDMA。
传输watermark信号输出,可以触发MDMA。
将这个硬件框图简化一下,就是下面这样:
下面按照简化的硬件框图,对每个部分做个说明。
DMA2D支持的工作模式如下:
这个模式主要用于清屏,也即是将显示屏清为单色效果。
这个模式用于从一个存储器复制一块数据到另一个存储器,比如将摄像头OV7670的输出图像复制到LCD显存就可以采用这种方式。
这个模式比模式2多了一个颜色格式转换,比如我们要显示一幅RGB888颜色格式的位图到RGB565颜色格式的显示屏,就需要用到这个模式,只需输入端配置为RGB888,输出端配置RGB565即可。位图颜色格式转换后会显示到显示屏上。
这个模式比模式3多了一个混合操作,通过混合,可以将两种效果进行混合显示。
同模式4,只是前景色的颜色值是固定的。
前景层和背景层是指的用户绘制图形时的前景色和背景色,比如我们显示汉字,字体会有一个颜色,也就是前景色,还有一个背景色。又比如我们绘制两幅图片,想将两幅图片混合,那就可以将一幅图片作为前景层,另一个幅图片作为背景层。
DMA2D支持的输入颜色格式如下,前景层和背景层一样:
前8种颜色格式在第50章的第2小节开头有介绍,这里把后四种做个说明:
4位颜色格式,实际上仅仅是4位索引值,范围0–15,而每个索引值的具体颜色值在查色表CLUT里面存储。
A4和A8用于特定的Alpha模式,既不存储颜色信息,也没有索引值。
这个是H7的硬件JPEG输出的颜色格式,后面JPEG章节为大家专门做讲解。
这里特别注意一点,输入颜色格式的Alpha值是可以设置的,而且颜色格式里面的R通道和B通道可以交换位置。
DMA2D混合器用于混合前景色和背景色,这个功能不需要任何配置,仅需要通过DMA2D_CR寄存器使能即可。混合公式如下:
DMA2D支持的输出颜色格式如下:
这里特别注意一点,输出颜色格式的Alpha值是可以设置的,而且颜色格式里面的R通道和B通道可以交换位置。
DMA2D的HAL库用法其实就是几个结构体变量成员的配置和使用,然后配置时钟,并根据需要配置NVIC、中断。下面我们逐一展开为大家做个说明。
DMA2D相关的寄存器是通过HAL库中的结构体DMA2D_TypeDef定义的,在stm32h743xx.h中可以找到它们的具体定义:
typedef struct
{
__IO uint32_t CR; /*!< DMA2D Control Register, Address offset: 0x00 */
__IO uint32_t ISR; /*!< DMA2D Interrupt Status Register, Address offset: 0x04 */
__IO uint32_t IFCR; /*!< DMA2D Interrupt Flag Clear Register, Address offset: 0x08 */
__IO uint32_t FGMAR; /*!< DMA2D Foreground Memory Address Register, Address offset: 0x0C */
__IO uint32_t FGOR; /*!< DMA2D Foreground Offset Register, Address offset: 0x10 */
__IO uint32_t BGMAR; /*!< DMA2D Background Memory Address Register, Address offset: 0x14 */
__IO uint32_t BGOR; /*!< DMA2D Background Offset Register, Address offset: 0x18 */
__IO uint32_t FGPFCCR; /*!< DMA2D Foreground PFC Control Register, Address offset: 0x1C */
__IO uint32_t FGCOLR; /*!< DMA2D Foreground Color Register, Address offset: 0x20 */
__IO uint32_t BGPFCCR; /*!< DMA2D Background PFC Control Register, Address offset: 0x24 */
__IO uint32_t BGCOLR; /*!< DMA2D Background Color Register, Address offset: 0x28 */
__IO uint32_t FGCMAR; /*!< DMA2D Foreground CLUT Memory Address Register, Address offset: 0x2C */
__IO uint32_t BGCMAR; /*!< DMA2D Background CLUT Memory Address Register, Address offset: 0x30 */
__IO uint32_t OPFCCR; /*!< DMA2D Output PFC Control Register, Address offset: 0x34 */
__IO uint32_t OCOLR; /*!< DMA2D Output Color Register, Address offset: 0x38 */
__IO uint32_t OMAR; /*!< DMA2D Output Memory Address Register, Address offset: 0x3C */
__IO uint32_t OOR; /*!< DMA2D Output Offset Register, Address offset: 0x40 */
__IO uint32_t NLR; /*!< DMA2D Number of Line Register, Address offset: 0x44 */
__IO uint32_t LWR; /*!< DMA2D Line Watermark Register, Address offset: 0x48 */
__IO uint32_t AMTCR; /*!< DMA2D AHB Master Timer Configuration Register, Address offset: 0x4C */
uint32_t RESERVED[236]; /*!< Reserved, 0x50-0x3FF */
__IO uint32_t FGCLUT[256]; /*!< DMA2D Foreground CLUT, Address offset:400-7FF */
__IO uint32_t BGCLUT[256]; /*!< DMA2D Background CLUT, Address offset:800-BFF */
} DMA2D_TypeDef;
__IO表示volatile, 这是标准C语言中的一个修饰字,表示这个变量是非易失性的,编译器不要将其优化掉。core_m7.h 文件定义了这个宏:
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
下面我们再看DMA2D的定义,在stm32h743xx.h文件。
#define PERIPH_BASE ((uint32_t)0x40000000)
#define D1_AHB1PERIPH_BASE (PERIPH_BASE + 0x12000000)
#define DMA2D_BASE (D1_AHB1PERIPH_BASE + 0x1000)
#define DMA2D ((DMA2D_TypeDef *) DMA2D_BASE) <----- 展开这个宏,(DMA2D_TypeDef *) 0x52001000
我们访问DMA2D的ISR寄存器可以采用这种形式:DMA2D->ISR = 0。
此结构体用于配置DMA2D的基本参数,具体定义如下:
typedef struct
{
uint32_t Mode;
uint32_t ColorMode;
uint32_t OutputOffset;
uint32_t AlphaInverted;
uint32_t RedBlueSwap;
} DMA2D_InitTypeDef;
下面将这几个参数逐一为大家做个说明:
此参数用于设置DMA2D的传输模式,具体支持的参数如下:
#define DMA2D_M2M ((uint32_t)0x00000000U) /*存储器到存储传输模式 */
#define DMA2D_M2M_PFC DMA2D_CR_MODE_0 /*存储器到存储器传输模式,并执行FPC像素格式转 */
#define DMA2D_M2M_BLEND DMA2D_CR_MODE_1 /* 存储器到存储器模式,并执行像素格式转换和混合 */
#define DMA2D_R2M DMA2D_CR_MODE /* 寄存器到存储器传输模式 */
此参数用于设置DMA2D的输出颜色格式,具体支持的参数如下:
#define DMA2D_OUTPUT_ARGB8888 ((uint32_t)0x00000000U) /* ARGB8888 */
#define DMA2D_OUTPUT_RGB888 DMA2D_OPFCCR_CM_0 /* RGB888 */
#define DMA2D_OUTPUT_RGB565 DMA2D_OPFCCR_CM_1 /* RGB565 */
#define DMA2D_OUTPUT_ARGB1555 (DMA2D_OPFCCR_CM_0|DMA2D_OPFCCR_CM_1) /* ARGB1555 */
#define DMA2D_OUTPUT_ARGB4444 DMA2D_OPFCCR_CM_2 /* ARGB4444 */
此参数用于设置输出位置的偏移值,参数范围0x0000到0x3FFF。
此参数用于设置DMA2D的输出颜色格式Alpha值反转(即255-原来数值),具体支持的参数如下:
#define DMA2D_REGULAR_ALPHA ((uint32_t)0x00000000U) /* 正常输出 */
#define DMA2D_INVERTED_ALPHA ((uint32_t)0x00000001U) /* 反转输出 */
此参数用于设置DMA2D的输出颜色格式中R通道和B通道的交换,具体支持的参数如下:
#define DMA2D_RB_REGULAR ((uint32_t)0x00000000U) /* 不交换(RGB or ARGB) */
#define DMA2D_RB_SWAP ((uint32_t)0x00000001U) /* 交换(BGR or ABGR) */
此结构体用于配置前景色和背景色。
typedef struct
{
uint32_t InputOffset;
uint32_t InputColorMode;
uint32_t AlphaMode;
uint32_t InputAlpha;
uint32_t AlphaInverted;
uint32_t RedBlueSwap;
uint32_t ChromaSubSampling;
} DMA2D_LayerCfgTypeDef;
下面将这几个参数逐一为大家做个说明。
设置前景色或者背景色的输入偏移,范围0x000到0x3FFF。
设置前景色或者背景色的输入颜色格式,具体支持的参数如下:
#define DMA2D_INPUT_ARGB8888 ((uint32_t)0x00000000U) /* ARGB8888 */
#define DMA2D_INPUT_RGB888 ((uint32_t)0x00000001U) /* RGB888 */
#define DMA2D_INPUT_RGB565 ((uint32_t)0x00000002U) /* RGB565 */
#define DMA2D_INPUT_ARGB1555 ((uint32_t)0x00000003U) /* ARGB1555 */
#define DMA2D_INPUT_ARGB4444 ((uint32_t)0x00000004U) /* ARGB4444 */
#define DMA2D_INPUT_L8 ((uint32_t)0x00000005U) /* L8 */
#define DMA2D_INPUT_AL44 ((uint32_t)0x00000006U) /* AL44 */
#define DMA2D_INPUT_AL88 ((uint32_t)0x00000007U) /* AL88 */
#define DMA2D_INPUT_L4 ((uint32_t)0x00000008U) /* L4 */
#define DMA2D_INPUT_A8 ((uint32_t)0x00000009U) /* A8 */
#define DMA2D_INPUT_A4 ((uint32_t)0x0000000AU) /* A4 */
#define DMA2D_INPUT_YCBCR ((uint32_t)0x0000000BU) /* YCbCr */
设置前景色或者背景色的Alpha模式,具体支持的参数如下:
#define DMA2D_NO_MODIF_ALPHA ((uint32_t)0x00000000U) /* 不修改Alpha通道值 */
#define DMA2D_REPLACE_ALPHA ((uint32_t)0x00000001U) /* 用新设置的Alpha值替换原始Alpha值 */
#define DMA2D_COMBINE_ALPHA ((uint32_t)0x00000002U) /* 用新设置的Alpha值与原始Alpha值的乘积替换原始Alaha值*/
设置前景色或者背景色的Alpha值,范围0x00到0xFF,如果颜色格式是A4或者A8,那么此参数的范围是0x00000000到0xFFFFFFFF,标准的ARGB8888格式。
设置前景色或者背景色的输入颜色格式Alpha值反转(即255-原来数值),具体支持的参数如下:
#define DMA2D_REGULAR_ALPHA ((uint32_t)0x00000000U) /* 正常输出 */
#define DMA2D_INVERTED_ALPHA ((uint32_t)0x00000001U) /* 反转输出 */
设置前景色或者背景色颜色格式中R通道和B通道的交换,具体支持的参数如下:
#define DMA2D_RB_REGULAR ((uint32_t)0x00000000U) /* 不交换(RGB or ARGB) */
#define DMA2D_RB_SWAP ((uint32_t)0x00000001U) /* 交换(BGR or ABGR) */
设置前景色或者背景色中YCbCr 颜色模式的采样格式,具体支持的参数如下:
#define DMA2D_NO_CSS ((uint32_t)0x00000000) /* 4:4:4 */
#define DMA2D_CSS_422 ((uint32_t)0x00000001) /* 4:2:2 */
#define DMA2D_CSS_420 ((uint32_t)0x00000002) /* 4:2:0 */
HAL库在DMA2D_TypeDef, DMA2D_InitTypeDef和DMA2D_LayerCfgTypeDef的基础上封装了一个结构体DMA2D_HandleTypeDef,定义如下:
typedef struct __DMA2D_HandleTypeDef
{
DMA2D_TypeDef *Instance;
DMA2D_InitTypeDef Init;
void (* XferCpltCallback)(struct __DMA2D_HandleTypeDef * hdma2d);
void (* XferErrorCallback)(struct __DMA2D_HandleTypeDef * hdma2d);
DMA2D_LayerCfgTypeDef LayerCfg[MAX_DMA2D_LAYER];
HAL_LockTypeDef Lock;
__IO HAL_DMA2D_StateTypeDef State;
__IO uint32_t ErrorCode; } DMA2D_HandleTypeDef;
下面将这几个参数逐一做个说明。
这个参数是寄存器的例化,方便操作寄存器,详见本章3.1小节。
这个参数是用户接触较多的,用于配置DMA2D的基本参数,详见本章3.2小节。
DMA2D中断服务程序里面执行的回调函数,一个是传输完成回调,另一个是传输错误回调。
这个参数用于前景色和背景色的设置,MAX_DMA2D_LAYER=2,详见本章3.3小节。
__IO uint32_t State;
__IO uint32_t ErrorCode
这三个变量主要供函数内部使用。Lock用于设置锁状态,State用于设置DMA2D通信状态,而ErrorCode用于配置代码错误。
对于DMA2D来说,其实不需要初始化流程,每个功能都可以直接封装出一个函数来,下个章节会为大家专门讲解,也是实际项目比较推荐的方式。
这里把我们把如下几个常用到的函数做个说明:
函数原型:
HAL_StatusTypeDef HAL_DMA2D_Init(DMA2D_HandleTypeDef *hdma2d)
{
/* 检测参数是否有效 */
if(hdma2d == NULL)
{
return HAL_ERROR;
}
/* 检测函数形参 */
assert_param(IS_DMA2D_ALL_INSTANCE(hdma2d->Instance));
assert_param(IS_DMA2D_MODE(hdma2d->Init.Mode));
assert_param(IS_DMA2D_CMODE(hdma2d->Init.ColorMode));
assert_param(IS_DMA2D_OFFSET(hdma2d->Init.OutputOffset));
if(hdma2d->State == HAL_DMA2D_STATE_RESET)
{
hdma2d->Lock = HAL_UNLOCKED;
/* 初始化GPIO,NVIC等 */
HAL_DMA2D_MspInit(hdma2d);
}
/* 设置DAM2D外设状态 */
hdma2d->State = HAL_DMA2D_STATE_BUSY;
/* 设置DAM2D工作模式 -------------------------------------------*/
MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_MODE, hdma2d->Init.Mode);
/* 设置输出颜色格式 ---------------------------------------*/
MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_CM, hdma2d->Init.ColorMode);
/* 设置输出偏移 ------------------------------------------*/
MODIFY_REG(hdma2d->Instance->OOR, DMA2D_OOR_LO, hdma2d->Init.OutputOffset);
/* 设置输出颜色格式中的Alpah值反转 */
MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_AI, (hdma2d->Init.AlphaInverted << DMA2D_POSITION_OPFCCR_AI));
MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_RBS,(hdma2d->Init.RedBlueSwap << DMA2D_POSITION_OPFCCR_RBS));
/* 无错误 */
hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE;
/* DAM2D就绪 */
hdma2d->State = HAL_DMA2D_STATE_READY;
return HAL_OK;
}
函数描述:
此函数用于初始化DMA2D的工作模式和输出颜色格式。
函数参数:
注意事项:
对于局部变量来说,这个参数就是一个随机值,如果是全局变量还好,一般MDK和IAR都会将全部变量初始化为0,而恰好这个 HAL_DMA2D_STATE_RESET = 0x00U。
解决办法有三
方法1:用户自己初始DMA2D底层。
方法2:定义DMA2D_HandleTypeDef LtdcHandle为全局变量。
方法3:下面的方法
if(HAL_DMA2D_DeInit(&Dma2dHandle) != HAL_OK)
{
Error_Handler();
}
if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
{
Error_Handler();
}
使用举例:
DMA2D_HandleTypeDef Dma2dHandle;
/*##-1- 配置DMA工作模式,输出颜色格式和输出偏移 #############*/
Dma2dHandle.Instance = DMA2D;
Dma2dHandle.Init.Mode = DMA2D_M2M; /* 存储器到存储器模式 */
Dma2dHandle.Init.ColorMode = DMA2D_OUTPUT_ARGB4444; /* 输出颜色格式 */
Dma2dHandle.Init.OutputOffset = 0x0; /* 无输出偏移 */
Dma2dHandle.Init.RedBlueSwap = DMA2D_RB_REGULAR; /* 输出颜色的R/B通过不切换 */
Dma2dHandle.Init.AlphaInverted = DMA2D_REGULAR_ALPHA; /* 输出颜色的Alpha通道数值不翻转 */
/*##-2- DMA2D 回调函数配置 ######################################*/
Dma2dHandle.XferCpltCallback = TransferComplete;
Dma2dHandle.XferErrorCallback = TransferError;
/*##-3- 前景层配置 ###########################################*/
Dma2dHandle.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; /* 保持输入颜色格式中的Alpha值 */
Dma2dHandle.LayerCfg[1].InputAlpha = 0xFF; /* 完全不透明 */
Dma2dHandle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB4444; /* 输入颜色格式 */
Dma2dHandle.LayerCfg[1].InputOffset = 0x0; /* 输入无偏移 */
Dma2dHandle.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR; /* 输入颜色的R/B通过不切换*/
Dma2dHandle.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* 输入颜色的Alpha通道数值不翻转*/
/*##-4- DMA2D 初始化 ###############################################*/
if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
{
Error_Handler();
}
函数原型:
HAL_StatusTypeDef HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
{
DMA2D_LayerCfgTypeDef *pLayerCfg = &hdma2d->LayerCfg[LayerIdx];
uint32_t regMask = 0, regValue = 0;
/* 检查参数 */
assert_param(IS_DMA2D_LAYER(LayerIdx));
assert_param(IS_DMA2D_OFFSET(pLayerCfg->InputOffset));
if(hdma2d->Init.Mode != DMA2D_R2M)
{
assert_param(IS_DMA2D_INPUT_COLOR_MODE(pLayerCfg->InputColorMode));
if(hdma2d->Init.Mode != DMA2D_M2M)
{
assert_param(IS_DMA2D_ALPHA_MODE(pLayerCfg->AlphaMode));
}
}
/* 上锁 */
__HAL_LOCK(hdma2d);
/* 设置DMA2D外设状态 */
hdma2d->State = HAL_DMA2D_STATE_BUSY;
/* 准备好背景层或者前景层FPC寄存器配置参数*/
regValue = pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << DMA2D_POSITION_BGPFCCR_AM) | \
(pLayerCfg->AlphaInverted << DMA2D_POSITION_BGPFCCR_AI) | \
(pLayerCfg->RedBlueSwap << DMA2D_POSITION_BGPFCCR_RBS);
regMask = DMA2D_BGPFCCR_CM | DMA2D_BGPFCCR_AM | DMA2D_BGPFCCR_ALPHA | DMA2D_BGPFCCR_AI | DMA2D_BGPFCCR_RBS;
if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
{
regValue |= (pLayerCfg->InputAlpha & DMA2D_BGPFCCR_ALPHA);
}
else
{
regValue |= (pLayerCfg->InputAlpha << DMA2D_POSITION_BGPFCCR_ALPHA);
}
/* 配置背景层 */
if(LayerIdx == 0)
{
/* DMA2D BGPFCCR 寄存器 */
MODIFY_REG(hdma2d->Instance->BGPFCCR, regMask, regValue);
/* DMA2D BGOR 寄存器 */
WRITE_REG(hdma2d->Instance->BGOR, pLayerCfg->InputOffset);
/* DMA2D BGCOLR 寄存器 */
if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
{
WRITE_REG(hdma2d->Instance->BGCOLR, pLayerCfg->InputAlpha &
(DMA2D_BGCOLR_BLUE|DMA2D_BGCOLR_GREEN|DMA2D_BGCOLR_RED));
}
}
/* 配置前景层 */
else
{
if(pLayerCfg->InputColorMode == DMA2D_INPUT_YCBCR)
{
regValue |= (pLayerCfg->ChromaSubSampling << DMA2D_POSITION_FGPFCCR_CSS);
regMask |= DMA2D_FGPFCCR_CSS;
}
/* DMA2D FGPFCCR 寄存器 */
MODIFY_REG(hdma2d->Instance->FGPFCCR, regMask, regValue);
/* DMA2D FGOR 寄存器 */
WRITE_REG(hdma2d->Instance->FGOR, pLayerCfg->InputOffset);
/* DMA2D FGCOLR 寄存器 */
if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
{
WRITE_REG(hdma2d->Instance->FGCOLR, pLayerCfg->InputAlpha &
(DMA2D_FGCOLR_BLUE|DMA2D_FGCOLR_GREEN|DMA2D_FGCOLR_RED));
}
}
/* DMA2D就绪 */
hdma2d->State = HAL_DMA2D_STATE_READY;
/* 解锁 */
__HAL_UNLOCK(hdma2d);
return HAL_OK;
}
函数描述:
此函数主要用于配置DMA2D要转换的前景层和背景层,即输入颜色配置。而前面的函数HAL_DMA2D_Init配置的输出颜色。
函数参数:
使用举例:
DMA2D_HandleTypeDef Dma2dHandle;
/*##-1- 配置DMA工作模式,输出颜色格式和输出偏移 #############*/
Dma2dHandle.Instance = DMA2D;
Dma2dHandle.Init.Mode = DMA2D_M2M; /* 存储器到存储器模式 */
Dma2dHandle.Init.ColorMode = DMA2D_OUTPUT_ARGB4444; /* 输出颜色格式 */
Dma2dHandle.Init.OutputOffset = 0x0; /* 无输出偏移 */
Dma2dHandle.Init.RedBlueSwap = DMA2D_RB_REGULAR; /* 输出颜色的R/B通过不切换 */
Dma2dHandle.Init.AlphaInverted = DMA2D_REGULAR_ALPHA; /* 输出颜色的Alpha通道数值不翻转 */
/*##-2- DMA2D 回调函数配置 ######################################*/
Dma2dHandle.XferCpltCallback = TransferComplete;
Dma2dHandle.XferErrorCallback = TransferError;
/*##-3- 前景层配置 ###########################################*/
Dma2dHandle.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; /* 保持输入颜色格式中的Alpha值 */
Dma2dHandle.LayerCfg[1].InputAlpha = 0xFF; /* 完全不透明 */
Dma2dHandle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB4444; /* 输入颜色格式 */
Dma2dHandle.LayerCfg[1].InputOffset = 0x0; /* 输入无偏移 */
Dma2dHandle.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR; /* 输入颜色的R/B通过不切换*/
Dma2dHandle.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* 输入颜色的Alpha通道数值不翻转*/
/*##-4- DMA2D 初始化 ###############################################*/
if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
{
Error_Handler();
}
/* 配置前景层 */
if(HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1) != HAL_OK)
{
Error_Handler();
}
函数原型:
HAL_StatusTypeDef HAL_DMA2D_Start_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height)
{
/* 检测函数形参 */
assert_param(IS_DMA2D_LINE(Height));
assert_param(IS_DMA2D_PIXEL(Width));
/* 上锁 */
__HAL_LOCK(hdma2d);
/* 设置DMA2D外设状态 */
hdma2d->State = HAL_DMA2D_STATE_BUSY;
/* 设置源地址,目的地址和数据大小 */
DMA2D_SetConfig(hdma2d, pdata, DstAddress, Width, Height);
/* 使能DMA2D的传输完成中断,传输错误中断和配置错误中断 */
__HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC|DMA2D_IT_TE|DMA2D_IT_CE);
/* 使能DMA2D */
__HAL_DMA2D_ENABLE(hdma2d);
return HAL_OK;
}
函数描述:
此函数用于启动DMA2D数据传输。由于采用的中断方式,此函数使能了多个DMA2D中断,不要忘记DMA2D中断服务程序的处理。
函数参数:
使用举例:
DMA2D_HandleTypeDef Dma2dHandle;
if(HAL_DMA2D_Start_IT(&Dma2dHandle, /* DMA2D句柄 */
(uint32_t)&BufferInput, /* 源地址 */
(uint32_t)&BufferResult, /* 目的地址 */
SIZE_X, /* 源数据长度,单位像素个数*/
SIZE_Y) /* 源数据行数 */
!= HAL_OK)
{
Error_Handler();
}
函数原型:
HAL_StatusTypeDef HAL_DMA2D_BlendingStart_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, uint32_t DstAddress, uint32_t Width, uint32_t Height)
{
/* 检测参数 */
assert_param(IS_DMA2D_LINE(Height));
assert_param(IS_DMA2D_PIXEL(Width));
/* 上锁 */
__HAL_LOCK(hdma2d);
/* 设置DMA2D外设状态 */
hdma2d->State = HAL_DMA2D_STATE_BUSY;
/* 配置DMA2D源地址2 */
WRITE_REG(hdma2d->Instance->BGMAR, SrcAddress2);
/* 配置源地址1,目的地址和数据大小 */
DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height);
/* 使能DMA2D传输完成中断,传输错误中断和配置错误中断 */
__HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC|DMA2D_IT_TE|DMA2D_IT_CE);
/* 使能DMA2D */
__HAL_DMA2D_ENABLE(hdma2d);
return HAL_OK;
}
函数描述:
此函数用于启动DMA2D传输,除了数据传输以外,还支持颜色格式转换和颜色混合。由于采用的中断方式,此函数使能了多个DMA2D中断,不要忘记DMA2D中断服务程序的处理。
函数参数:
使用举例:
DMA2D_HandleTypeDef Dma2dHandle;
if(HAL_DMA2D_BlendingStart_IT(&Dma2dHandle, /* DMA2D句柄 */
(uint32_t)&BufferInput1, /* 源地址1,前景色 */
(uint32_t)&BufferInput2, /* 源地址2,背景色 */
(uint32_t)&BufferResult, /* 目的地址 */
SIZE_X, /* 源数据长度,单位像素个数*/
SIZE_Y) /* 源数据行数 */
!= HAL_OK)
{
Error_Handler();
}
本章节就为大家讲解这么多,DMA2D功能比较重要,一定要做到熟练使用。