基于STM32F429的RGB屏使用

使用ST的HAL库进行开发,RGB屏幕是480*272的4.3寸LCD,由于驱动RGB屏幕需要较多的内存,

所以使用了外部SDRAM,内存是32M字节,关于SDRAM的驱动本文不进行讨论。

RGB屏幕常用的像素格式有:ARGB8888、RGB888、RGB565、ARGB1555、ARGB4444等格式,本文讨论RGB565格式的使用。

RGBLCD的信号线如下表:


上表共有24根颜色信号线,RGB565格式只用了其中的16根颜色信号线,分别是:R[3:7],G[2:7],B[3:7],共16位,

这样在表示颜色的时候就可以用16位长度的数据进行表示了,增加了数据的传输速度。

RGBLCD接口的原理图如下:


除了16位数据线之外,还有用到如下几个信号线:

LCD_BL:背光;

LCD_DE:数据使能信号;

LCD_VSYNC:垂直同步信号;

LCD_HSYNC:水平同步信号;

LCD_CLK:时钟信号;

STM32F429有自带的RGBLCD外设接口LTDC,可以用来直接驱动RGBLCD,另外配上专用于图像处理的DMA2D,

使得RGBLCD用起来更加方便快速。

下面开始介绍使用到的单片机引脚对应:

    PI9     ------> LTDC_VSYNC
    PI10     ------> LTDC_HSYNC
    PF10     ------> LTDC_DE
    PG7     ------> LTDC_CLK
    PH9     ------> LTDC_R3
    PH10     ------> LTDC_R4
    PH11     ------> LTDC_R5
    PH12     ------> LTDC_R6
    PG6     ------> LTDC_R7
    PH13     ------> LTDC_G2
    PH14     ------> LTDC_G3
    PH15     ------> LTDC_G4
    PI0     ------> LTDC_G5
    PI1     ------> LTDC_G6
    PI2     ------> LTDC_G7
    PG11  ------> LTDC_B3
    PI4     ------> LTDC_B4
    PI5     ------> LTDC_B5
    PI6     ------> LTDC_B6
    PI7     ------> LTDC_B7 

通过配置STM32CubeMx直接生成的LTDC部分初始化代码如下:

void MX_LTDC_Init(void)
{
    LTDC_LayerCfgTypeDef pLayerCfg;
    
    hltdc.Instance = LTDC;
    hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;	    	//水平同步极性:低有效
    hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;		    //垂直同步极性:低有效
    hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;		    //数据使能极性:低有效
    hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;		//像素时钟极性:输入像素时钟
    hltdc.Init.HorizontalSync = 0;				    	//水平同步宽度,1个时钟信号
    hltdc.Init.VerticalSync = 0;						//垂直同步宽度,1行像素对应的时钟
    hltdc.Init.AccumulatedHBP = 40;				    	//水平后沿宽度:40
    hltdc.Init.AccumulatedVBP = 8;				    	//垂直后沿宽度:8
    hltdc.Init.AccumulatedActiveW = 520;				//显示有效宽度:520-40=480
    hltdc.Init.AccumulatedActiveH = 280;				//显示有效高度:280-8=272
    hltdc.Init.TotalWidth = 525;						//总宽度:525(包含了5个水平前沿宽度)
    hltdc.Init.TotalHeigh = 288;						//总高度:288(包含了8个垂直前沿宽度)
    hltdc.Init.Backcolor.Blue = 0;				    	//屏幕背景层蓝色部分
    hltdc.Init.Backcolor.Green = 0;				    	//屏幕背景层绿色部分
    hltdc.Init.Backcolor.Red = 0;						//屏幕背景层红色部分
    if (HAL_LTDC_Init(&hltdc) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

    pLayerCfg.WindowX0 = 0;								    	//窗口起点x坐标
    pLayerCfg.WindowX1 = 480;									//窗口终点x坐标
    pLayerCfg.WindowY0 = 0;								    	//窗口起点y坐标
    pLayerCfg.WindowY1 = 272;									//窗口终点y坐标
    pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;			//像素格式RGB565格式
    pLayerCfg.Alpha = 255;								    	//恒定alpha值
    pLayerCfg.Alpha0 = 0;										//默认alpha值
    pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;	//混合系数1:像素alpha*恒定alpha
    pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;	//混合洗漱2:像素alpha*恒定alpha
    pLayerCfg.FBStartAdress = 0xC0000000;						//颜色数据所在的内存起始地址
    pLayerCfg.ImageWidth = 480;							    	//图像宽度
    pLayerCfg.ImageHeight = 272;								//图像高度
    pLayerCfg.Backcolor.Blue = 0;								//屏幕背景层蓝色部分
    pLayerCfg.Backcolor.Green = 0;							    //屏幕背景层绿色部分
    pLayerCfg.Backcolor.Red = 0;								//屏幕背景层红色部分
    if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }
}

函数MX_LTDC_Init()将外设LTDC进行了初始化配置,在配置好ltdc之后,我们只需要改变对应的内存的数据,

ltdc就会自动帮我们改变LCD上对应像素点的颜色。

下面通过初始化LCD的函数,将LCD屏幕清屏为全白:

/**
  * @brief : LCD清屏,使用DMA2D将颜色数据传输到内存中
  * @par Full description : 填充范围是坐标(sx,sy),(ex,ey)形成的矩形区域,
  *							区域大小像素点个数是:(ex-sx+1)*(ey-sy+1)
  * @param : 
  *		sx -- x轴起点坐标
  *		sy -- y轴起点坐标
  *		ex -- x轴终点坐标
  *		ey -- y轴终点坐标
  *		Colour -- 填充的颜色
  * @retval : 无
  */
void LcdClear(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t Colour)
{
    __HAL_RCC_DMA2D_CLK_ENABLE();                               //使能DMA2D时钟
	DMA2D->CR &= ~(DMA2D_CR_START);                             //先停止DMA2D
	DMA2D->CR = DMA2D_R2M;                                      //寄存器到存储器模式
	DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_RGB565;                   //设置颜色格式
	DMA2D->OOR = 0;                                             //设置行偏移
	DMA2D->OMAR = uhLtdcFrameBuf;                               //输出存储器地址
	DMA2D->NLR = (ey - sy + 1) | ((ex - sx + 1) << 16);         //设定行数寄存器
	DMA2D->OCOLR = Colour;                                      //设定输出颜色寄存器
	DMA2D->CR |= DMA2D_CR_START;                                //启动DMA2D
	while((DMA2D->ISR & DMA2D_FLAG_TC) == 0);                   //等待传输完成
	DMA2D->IFCR |= DMA2D_FLAG_TC;                               //清除传输完成标志
}

void LcdInit(void)
{
	LCD_BIAS_LIGHT_ENALBE;                                      //使能LCD背光
	LcdClear(0, 0, 479, 271, 0xFFFF);                           //清屏全白,0xFFFF是全白
}
使用DMA2D将大量的数据传输到指定的内存之中,0xFFFF对应的是白色,对应的内存地址是uhLtdcFrameBuf数组的首地址。

至此,我们就完成了将RGBLCD清屏成全白的测试。




下载积分重新调回5个。。 00__LIBRARIES 00_STM32F4xx_HAL_DRIVERS 00_STM32F4xx_STANDARD_PERIPHERAL_DRIVERS 00_STM32_SVD 01_STM32F4xx_Keil_CMSIS_Default_Project 01_STM32F4xx_Keil_CMSIS_USB_Default_Project 02__LED_BUTTON 03__DELAY 03__DELAY_CREATE_TIMER 03__DELAY_TIM 03__DELAY_TIME 04__USART 04__USART_CUSTOM_PINS 04__USART_STRING 05__SPI 05__SPI_CUSTOM_PINS 06__ADC 06__ADC_VBAT 07__DAC 08__ILI9341 09__I2C 09__I2C_CUSTOM_PINS 09__I2C_SEARCH_DEVICES 10__STMPE811 11__ILI9341_BUTTON 12__ONEWIRE 12__ONEWIRE_MULTI 13__DS18B20 14__SDRAM 14__SDRAM_VARIABLES 15__DS1307 16__HD44780 17__nRF24L01P_RECEIVER 17__nRF24L01P_RECEIVER_IRQ 17__nRF24L01P_TRANSMITTER 17__nRF24L01P_TRANSMITTER_IRQ 18__ILI9341_LTDC 18__ILI9341_LTDC_PINS_USED 19__RTC 19__RTC_ALARM 19__RTC_BKP 19__RTC_SETDATETIME_STRING 19__RTC_SUBSECONDS 20__WATCHDOG 20__WATCHDOG_DBGMCU_STOP 21__FATFS 21__FATFS_READ_BENCHMARK 21__FATFS_SDRAM 22__RNG 23__MFRC522 24__USB_VCP 25__AM2301 26__ROTARY_ENCODER 27__GPS 27__GPS_CUSTOM 27__GPS_ILI9341 27__GPS_NUCLEO 28__L3GD20 29__FATFS_USB_MSC_HOST 29__FATFS_USB_MSC_HOST_SD_CARD 30__HCSR04 31__USB_HID_HOST 32__KEYPAD 33__PWM 33__PWM_SERVO 33__PWM_SERVO_KEYPAD 34__USB_HID_DEVICE 35_STM32F4_LIS3DSH_LIS302DL 36__DAC_SIGNAL 37__BMP180 38__EXTI 39__LOW_POWER_MODE_SLEEP 39__LOW_POWER_MODE_STANDBY 39__LOW_POWER_MODE_STOP 40__MCO_OUTPUT 41__STDIO_INPUT_OUTPUT 41__STDIO_OUTPUT 42__SERVO 43__MPU6050 43__MPU6050_2DEVICES 44__IDENTIFICATION 45__BKPSRAM 46__SWO 47__CRC 48__PWMIN 49__OTP 50__EMWIN 50__EMWIN_GRAPH 51__GRAPHIC_DMA2D 52__ETHERNET_CLIENT 52__ETHERNET_CLIENT_COOCOX 52__ETHERNET_DHCP 52__ETHERNET_DHCP_COOCOX 52__ETHERNET_SERVER 52__ETHERNET_SERVER_COOCOX 52__ETHERNET_SERVER_SDCARD 52__ETHERNET_SERVER_SDCARD_COOCOX 53__GPIO 54__GENERAL 55__USART_DMA 56__SPI_DMA 57__BUTTONS 58__STRINGS 59__RCC_PLL 60__CPU_LOAD 61__SSD1306 62__FFT 63__DMA 63__HMC5883L
以下是一个基于STM32F429 Discovery开发板的RGB LCD驱动程序,使用了库函数和C语言编写。 首先,需要在Keil或者其他编译器中创建一个新工程,并添加STM32F429 Discovery开发板的库文件。 接着,在程序中引入库文件,并定义LCD控制器芯片的参数: ``` #include "stm32f4xx.h" #include "stm32f429i_discovery.h" #define LCD_CMD *((volatile unsigned short*)0x60000000) #define LCD_DATA *((volatile unsigned short*)0x60020000) #define LCD_RST_PIN GPIO_Pin_13 #define LCD_RST_PORT GPIOD #define LCD_RS_PIN GPIO_Pin_14 #define LCD_RS_PORT GPIOD #define LCD_CS_PIN GPIO_Pin_15 #define LCD_CS_PORT GPIOD ``` 然后,需要定义一些基本的函数,如初始化LCD、设置显示区域等: ``` void LCD_init(void) { /* 复位LCD */ GPIO_ResetBits(LCD_RST_PORT, LCD_RST_PIN); delay_ms(10); GPIO_SetBits(LCD_RST_PORT, LCD_RST_PIN); delay_ms(10); /* 初始化LCD */ LCD_CMD = 0xCF; LCD_DATA = 0x00; LCD_DATA = 0xC9; LCD_DATA = 0X30; LCD_CMD = 0xED; LCD_DATA = 0x64; LCD_DATA = 0x03; LCD_DATA = 0X12; LCD_DATA = 0X81; LCD_CMD = 0xE8; LCD_DATA = 0x85; LCD_DATA = 0x00; LCD_DATA = 0x78; LCD_CMD = 0xCB; LCD_DATA = 0x39; LCD_DATA = 0x2C; LCD_DATA = 0x00; LCD_DATA = 0x34; LCD_DATA = 0x02; LCD_CMD = 0xF7; LCD_DATA = 0x20; LCD_CMD = 0xEA; LCD_DATA = 0x00; LCD_DATA = 0x00; /* 设置显示区域 */ LCD_CMD = 0x36; LCD_DATA = 0x48; /* 开启显示 */ LCD_CMD = 0x29; } ``` 最后,需要定义一些绘图函数,如绘制像素点、线段、矩形、圆等: ``` void LCD_drawPixel(int x, int y, unsigned short color) { LCD_setWindow(x, y, x, y); LCD_CMD = 0x2C; LCD_DATA = color; } void LCD_drawLine(int x0, int y0, int x1, int y1, unsigned short color) { int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1; int err = (dx > dy ? dx : -dy) / 2, e2; while (1) { LCD_drawPixel(x0, y0, color); if (x0 == x1 && y0 == y1) break; e2 = err; if (e2 > -dx) { err -= dy; x0 += sx; } if (e2 < dy) { err += dx; y0 += sy; } } } void LCD_drawRect(int x0, int y0, int x1, int y1, unsigned short color) { LCD_drawLine(x0, y0, x1, y0, color); LCD_drawLine(x0, y1, x1, y1, color); LCD_drawLine(x0, y0, x0, y1, color); LCD_drawLine(x1, y0, x1, y1, color); } void LCD_drawCircle(int x0, int y0, int r, unsigned short color) { int x = -r, y = 0, err = 2 - 2 * r; do { LCD_drawPixel(x0 - x, y0 + y, color); LCD_drawPixel(x0 - y, y0 - x, color); LCD_drawPixel(x0 + x, y0 - y, color); LCD_drawPixel(x0 + y, y0 + x, color); r = err; if (r <= y) err += ++y * 2 + 1; if (r > x || err > y) err += ++x * 2 + 1; } while (x < 0); } ``` 这样,一个基于STM32F429 Discovery开发板的RGB LCD驱动程序就完成了。开发者可以在此基础上进行修改和优化,以满足自己的需求。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值