找了很久都没有cubmx来配置原子RGB屏幕的,于是自己写一个, 我的分辨率是7寸1024x600
使用RGB屏幕前提是配置好SDRAM,因为需要缓冲区是建立在SDRAM上面, 如何配置请看我这个文章https://blog.csdn.net/a2267542848/article/details/110944197
如果是其他RGB分辨率,需要改的地方有
1 时序
2 宏定义 分辨率
3 LCD时钟
硬件接口
一定要注意引脚对应,不然会点不亮屏幕
cubmex配置
1 打开DMA2D
2 打开LTDC
宏定义, 因为在配置时序和缓冲区都要分辨率, 所以直接配置为宏定义
1 配置时序,这个PIXEL_W是宏定义, 在user constants里面我定义为1024 , 其他时序自己看原子的, 我的是1024分辨率就配置这
2 配置缓冲区
注意Alpha这个是255
3 配置宏定义(可选)
4 修改IO
因为默认的LTDC IO口不是原子屏幕的接口,所以需要调整IO口, 另外注意要把PB5这个引脚设置为输出, 这个是液晶背光控制
原子屏幕是没有DISP这个引脚的, 只有野火才有
IO口速度要设置为High, 有一次我设置为LOW, 结果跑不起
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /**LTDC GPIO Configuration PI9 ------> LTDC_VSYNC PI10 ------> LTDC_HSYNC PF10 ------> LTDC_DE PH9 ------> LTDC_R3 PH10 ------> LTDC_R4 PH11 ------> LTDC_R5 PH12 ------> LTDC_R6 PG6 ------> LTDC_R7 PG7 ------> LTDC_CLK 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 */ |
5 修改LCD_TFT时钟
我这个1024x600的时钟为45M, 其他分辨率请看原子文档
3 代码修改
ltdc.c 头部
1 2 3 4 5 6 7 | /* USER CODE BEGIN 0 */ #include "dma2d.h" //LCD帧缓冲区首地址,这里定义在SDRAM里面. #define LCD_FRAME_BUF_ADDR 0XC0000000 //定义最大屏分辨率时,LCD所需的帧缓存数组大小 uint16_t g_ltdc_framebuf[PIXELS_W][PIXELS_H] __attribute__((at(LCD_FRAME_BUF_ADDR))); /* USER CODE END 0 */ |
自定义函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /* USER CODE BEGIN 1 */ //LTDC填充矩形,DMA2D填充 //(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1) //color:要填充的颜色 //有时候需要频繁的调用填充函数,所以为了速度,填充函数采用寄存器版本, //不过下面有对应的库函数版本的代码。 void LTDC_Fill(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint32_t color) { uint32_t psx,psy,pex,pey; //以LCD面板为基准的坐标系,不随横竖屏变化而变化 uint32_t timeout=0; uint16_t offline; uint32_t addr; //坐标系转换 if(PIXELS_DIR) //横屏 { psx=sx;psy=sy; pex=ex;pey=ey; }else //竖屏 { psx=sy;psy=PIXELS_H-ex-1; pex=ey;pey=PIXELS_H-sx-1; } offline=PIXELS_W-(pex-psx+1); addr=(LCD_FRAME_BUF_ADDR+2*(PIXELS_W*psy+psx)); __HAL_RCC_DMA2D_CLK_ENABLE(); //使能DM2D时钟 DMA2D->CR&=~(DMA2D_CR_START); //先停止DMA2D DMA2D->CR=DMA2D_R2M; //寄存器到存储器模式 DMA2D->OPFCCR=LTDC_PIXEL_FORMAT_RGB565; //设置颜色格式 DMA2D->OOR=offline; //设置行偏移 DMA2D->OMAR=addr; //输出存储器地址 DMA2D->NLR=(pey-psy+1)|((pex-psx+1)<<16); //设定行数寄存器 DMA2D->OCOLR=color; //设定输出颜色寄存器 DMA2D->CR|=DMA2D_CR_START; //启动DMA2D while((DMA2D->ISR&(DMA2D_FLAG_TC))==0) //等待传输完成 { timeout++; if(timeout>0X1FFFFF)break; //超时退出 } DMA2D->IFCR|=DMA2D_FLAG_TC; //清除传输完成标志 } // 清屏 void LTDC_Clear(uint32_t color) { LTDC_Fill(0,0,PIXELS_H-1,PIXELS_W-1,color); } // 电源打开 void LTDC_ON(void) { HAL_GPIO_WritePin(LCD_BK_GPIO_Port,LCD_BK_Pin,1); } // 电源关闭 void LTDC_OFF(void) { HAL_GPIO_WritePin(LCD_BK_GPIO_Port,LCD_BK_Pin,0); } // 初始化 void LTDC_Init(void) { HAL_LTDC_SetWindowPosition(&hltdc,0,0,0); //设置窗口的位置 HAL_LTDC_SetWindowSize(&hltdc,PIXELS_W,PIXELS_H,0);//设置窗口大小 LTDC_ON(); LTDC_Clear(0XFFFFFFFF); //清屏 return; } /* USER CODE END 1 */ |
ltdc.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* USER CODE BEGIN Private defines */ //画笔颜色 #define WHITE 0xFFFF #define BLACK 0x0000 #define BLUE 0x001F #define BRED 0XF81F #define GRED 0XFFE0 #define GBLUE 0X07FF #define RED 0xF800 #define MAGENTA 0xF81F #define GREEN 0x07E0 #define CYAN 0x7FFF #define YELLOW 0xFFE0 #define BROWN 0XBC40 //棕色 #define BRRED 0XFC07 //棕红色 #define GRAY 0X8430 //灰色 /* USER CODE END Private defines */ void MX_LTDC_Init(void); /* USER CODE BEGIN Prototypes */ void LTDC_Init(void); void LTDC_Fill(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint32_t color); void LTDC_Clear(uint32_t color); /* USER CODE END Prototypes */ |
主函数调用
1 2 3 4 5 6 7 8 9 10 11 | /* USER CODE BEGIN 2 */ MX_SDRAM_InitEx(); LTDC_Init(); HAL_Delay(1000); LTDC_Clear(YELLOW); HAL_Delay(1000); LTDC_Clear(BLUE); HAL_Delay(1000); LTDC_Clear(RED); /* USER CODE END 2 */ |
效果
下载地址:
git:
csdn: https://download.csdn.net/download/a2267542848/13626887