STM32F429的LTDC和DMA2D ***

  在閱讀了STM32F429的手冊以後,對LTDC與DMA2D有了一點認識。spa

  STM32F429與以前的系列強大之處就在於增長了LTDC個功能,從手冊上看STM32F429的LTDC能夠用於驅動1024x768分辨率的LCD屏幕。code

LTDC其實就是TFT LCD控制器的意思,在arm9/arm11/cortex-A系列CPU當中,這個是必須有的外設,在小型單片機中,有這個功能的很少。orm

LCD控制器的功能就是生成LCD像素時鐘,將GRAM中的數據搬運到LCD屏幕上去顯示。blog

        在通常的小型LCD模塊通常都集成了一個LCD控制器,如經常使用的ili9320/ili9325等型號,這些LCD模塊同時還集成了幾百KB大小的RAM,用於顯示;接口

這種方案,不須要佔用單片機的RAM就能夠穩定地驅動LCD顯示圖像,通常地MCU先經過8080接口或SPI向控制器發送命令,配置LCD參數,ip

而後向集成的RAM中寫入數據就能夠顯示,是低成本項目的首選方案。內存

       而STM32F429自帶的LTDC也是LCD控制器,與ili9320相比,支持的分辨率更高,功能更多,可是LTDC只負責產生LCD須要的時序,並無集成RAM,v8

如640x480x16bpp的屏幕,須要600KB的RAM,在單片機中600KB的內存,已是天文數字了,因此須要外擴一片SDRAM來充當GRAM。同步

      那麼在使用LTDC的時候,首先要配置LCD的時序,而後要設置GRAM的地址(這裏GRAM的地址就是外擴的SDRAM的地址),最後開啓LTDC,能夠在LCD_CLK引腳測量到有穩定的頻率輸出,應該就差很少了;配置好LTDC以後,硬件會自動將GRAM中的內容搬運到LCD屏幕上,只要改變GRAM中的數據就能夠改變顯示內容。it

     另外要說的是這個LTDC支持2個圖層和1個背景圖層,通常狀況下用一個圖層顯示就能夠了;這2個圖層能夠單獨設置顯示區域和GRAM地址,而且同時開啓時,硬件自動將2個圖層的顯示內容進行混合,混合順序是:圖層2 -> 圖層1 -> 背景色,圖層2位於最頂層,至於怎麼利用這兩個圖層實現特殊的功能,就仁者見仁,智者見智了。

 

    DMA2D則是一個生活在GRAM世界中的一個搬運工,往你指定的內存地址中製造一個矩形,或者把一個矩形數據從源RAM複製到目的RAM,而且徹底由硬件實現。

LTDC的初始化參考例程:

#include "stm32f4xx.h"
#include "gpio.h"
#include "ltdc.h"
 
#define HBP        8
#define VBP        4
#define HSW        1
#define VSW        1
#define HFP        30
#define VFP        1
#define WIDTH     240
#define HEIGHT    320
 
#define FRAMEBUFFER    0xD0000000
 
static void ltdc_gpio_init(void)
{
    gpio_open(PA, 3, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PA, 4, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PA, 6, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PA,11, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PA,12, GPIO_MODE_AF, GPIO_AF_LTDC);
    
    gpio_open(PB, 0, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PB, 1, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PB, 8, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PB, 9, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PB,10, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PB,11, GPIO_MODE_AF, GPIO_AF_LTDC);
    
    gpio_open(PC, 6, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PC, 7, GPIO_MODE_AF, GPIO_AF_LTDC);
    
    gpio_open(PD, 3, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PD, 6, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PF,10, GPIO_MODE_AF, GPIO_AF_LTDC);
    
    gpio_open(PG, 6, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PG, 7, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PG,10, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PG,11, GPIO_MODE_AF, GPIO_AF_LTDC);
    gpio_open(PG,12, GPIO_MODE_AF, GPIO_AF_LTDC);
}
 
static void ltdc_clock_init(void)
{
    LTDC_InitTypeDef ltdc;
    ltdc.LTDC_HSPolarity = LTDC_HSPolarity_AL;
    ltdc.LTDC_VSPolarity = LTDC_VSPolarity_AL;
    ltdc.LTDC_DEPolarity = LTDC_DEPolarity_AL;
    ltdc.LTDC_PCPolarity = LTDC_PCPolarity_IPC;
    ltdc.LTDC_HorizontalSync       = HSW-1;
    ltdc.LTDC_VerticalSync         = VSW-1;                //垂直同步寬度
    ltdc.LTDC_AccumulatedHBP       = HSW+HBP-1;            //水平同步後沿寬度
    ltdc.LTDC_AccumulatedVBP       = VSW+VBP-1;            //垂直同步後沿高度
    ltdc.LTDC_AccumulatedActiveW   = HSW+HBP+WIDTH-1;      //有效寬度
    ltdc.LTDC_AccumulatedActiveH   = VSW+VBP+HEIGHT-1;     //有效高度
    ltdc.LTDC_TotalWidth           = HSW+HBP+WIDTH+HFP-1;  //總寬度
    ltdc.LTDC_TotalHeigh           = VSW+VBP+HEIGHT+VFP-1; //總高度
    ltdc.LTDC_BackgroundRedValue   = 0;
    ltdc.LTDC_BackgroundGreenValue = 0;
    ltdc.LTDC_BackgroundBlueValue  = 0;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_LTDC,ENABLE);
    RCC_PLLSAIConfig(256, 2, 4);
    RCC_PLLSAICmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY)==RESET);
    RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div8);
    LTDC_Init(<dc);
    LTDC_Cmd(ENABLE);
}
 
static void ltdc_layer_init(void)
{
    LTDC_Layer_InitTypeDef layer;
    layer.LTDC_HorizontalStart  = HBP+1;
    layer.LTDC_HorizontalStop   = WIDTH+HBP;
    layer.LTDC_VerticalStart    = VBP+1;
    layer.LTDC_VerticalStop     = HEIGHT+VBP;
    layer.LTDC_PixelFormat      = LTDC_Pixelformat_RGB565;
    layer.LTDC_ConstantAlpha    = 255;
    layer.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA;
    layer.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA;
    layer.LTDC_CFBStartAdress   = FRAMEBUFFER;
    layer.LTDC_CFBLineLength    = (WIDTH * 2)+3;
    layer.LTDC_CFBLineNumber    = HEIGHT;
    layer.LTDC_CFBPitch         = WIDTH * 2;
    layer.LTDC_DefaultColorRed  = 0;
    layer.LTDC_DefaultColorGreen= 0;
    layer.LTDC_DefaultColorBlue = 0;
    layer.LTDC_DefaultColorAlpha= 0;
    LTDC_LayerInit(LTDC_Layer1, &layer);
    LTDC_ReloadConfig(LTDC_IMReload);
    LTDC_LayerCmd(LTDC_Layer1, ENABLE);
    LTDC_ReloadConfig(LTDC_IMReload);
}
 
void ltdc_init(void)
{
    ltdc_gpio_init();
    ltdc_clock_init();
    ltdc_layer_init();
}
相關文章
相關標籤/搜索