使用STM32CubeMX配置正点原子RGB屏

目录

简介

硬件平台及软件版本

CubeMX设置

调试I/O配置

SDRAM配置

LTDC配置

CubeMX生成文件参数配置

程序移植

文件下载百度链接


简介

在正点原子例程中缺少RGBLCD的CubeMX配置,主要提供讲解RGBLCD的CubeMX配置,达到在阿波罗上运行的效果。

硬件平台及软件版本

阿波罗F7(STM32F767IGT)开发板,4342的480*272像素RGB显示屏。

Keil5、STM32CubeMX5.4。

CubeMX设置

调试I/O配置

在将Debug使能后,先对一些可能用到的GPIO进行设置。如下图所示。需要注意的是,仅仅只有PB5在显示屏中作为背光使用,其他I/O作为调试使用。

使用STM32CubeMX配置正点原子RGB屏_第1张图片

SDRAM配置

在使用显示屏时,用到了SRAM,SDRAM通过FMC接口,与STM32相连。关于FMC与SDRAM不做过多解释,在这仅仅讲解如何通过STM32CubeMX进行配置。SDRAM的配置如下图所示。需要特别注意的是Write recovery time选项,在正点原子中的数值是2。

使用STM32CubeMX配置正点原子RGB屏_第2张图片

在对SDRAM的参数选项配置完成后需要改变默认的I/O从而与阿波罗的开发板相对应。更改后的I/O如下图。

使用STM32CubeMX配置正点原子RGB屏_第3张图片

使用STM32CubeMX配置正点原子RGB屏_第4张图片

LTDC配置

RGBLCD用的是LTDC,LTDC除了自身外,还需要使能后对时钟进行配置。LTDC的参数配置如下(参数配置跟显示屏有关,可以在正点原子例程中找到对应参数)。

使用STM32CubeMX配置正点原子RGB屏_第5张图片

使用STM32CubeMX配置正点原子RGB屏_第6张图片

使用STM32CubeMX配置正点原子RGB屏_第7张图片

同样的LTDC的IO口也需要改变。

使用STM32CubeMX配置正点原子RGB屏_第8张图片

配置完成后对DMA2D使能,设置时钟。

使用STM32CubeMX配置正点原子RGB屏_第9张图片

使用STM32CubeMX配置正点原子RGB屏_第10张图片

CubeMX生成文件参数配置

Project Manger中,Project里面设置工程名,保存路径,编译器。并在与Project并列的Code Generator中勾选生成对应的.c和.h文件。之后生成工程。

程序移植

注意:正点原子的数据类型名与CubeMX生成文件数据类型名不一致,以CubeMX的为准。

           关于正点原子变量如无必要建立不在特殊点出。

首先需要将正点原子已经写好的字库文件(font.h),与画笔函数(lcd.c和lcd.h)移植过来。对lcd.c进行更改。主要是初始化函数。其他关于显示屏函数无非就是添加变量,声明定义,不在图书指出。

//初始化lcd
//该初始化函数可以初始化各种型号的LCD(详见本.c文件最前面的描述)
void LCD_Init(void)
{ 	   	
	lcdltdc.pwidth=480;			    //面板宽度,单位:像素
	lcdltdc.pheight=272;		    //面板高度,单位:像素
	lcdltdc.hsw=1;				    //水平同步宽度
	lcdltdc.vsw=1;				    //垂直同步宽度
	lcdltdc.hbp=40;				    //水平后廊
	lcdltdc.vbp=8;				    //垂直后廊
	lcdltdc.hfp=5;				    //水平前廊
	lcdltdc.vfp=8;				    //垂直前廊
	lcdltdc.pixsize=2;				//每个像素占2个字节
	lcddev.width=lcdltdc.pwidth;
	lcddev.height=lcdltdc.pheight;

	ltdc_framebuf[0] = (uint32_t *)<dc_lcd_framebuf;		//把SDRAM的首地址赋给第一层的地址指针,作为RGBLCD的显存

	LTDC_Layer_Parameter_Config(0,(uint32_t)ltdc_framebuf[0],LCD_PIXFORMAT,255,0,6,7,0X000000);//层参数配置
	HAL_LTDC_SetWindowPosition(<DC_Handler,0,0,0);  //设置窗口的位置
    HAL_LTDC_SetWindowSize(<DC_Handler,lcdltdc.pwidth,lcdltdc.pheight,0);//设置窗口大小 
	
	LCD_Display_Dir(0);		//默认为竖屏
	LTDC_Select_Layer(0); 			//选择第1层
	LCD_LED(1);				//点亮背光
	LCD_Clear(WHITE);
}  

特别注意的是需要对SDRAM的部分初始化函数进行移植,主要是需要添加 SDRAM_Initialization_Sequence 函数。关于此方面更改后的代码如下。此段代码来自于正点原子F7的HAL库版本。放在CubeMX生成的fmc.c中。在移植此部分程序时,需要将原来的SDRAM_HandleTypeDef类型的变量替换为hsdram1。

/* USER CODE BEGIN 0 */


//向SDRAM发送命令
//bankx:0,向BANK5上面的SDRAM发送指令
//      1,向BANK6上面的SDRAM发送指令
//cmd:指令(0,正常模式/1,时钟配置使能/2,预充电所有存储区/3,自动刷新/4,加载模式寄存器/5,自刷新/6,掉电)
//refresh:自刷新次数
//regval:模式寄存器的定义
//返回值:0,正常;1,失败.
uint8_t SDRAM_Send_Cmd(uint8_t bankx,uint8_t cmd,uint8_t refresh,uint16_t regval)
{
    uint32_t target_bank=0;
    FMC_SDRAM_CommandTypeDef Command;
    
    if(bankx==0) target_bank=FMC_SDRAM_CMD_TARGET_BANK1;       
    else if(bankx==1) target_bank=FMC_SDRAM_CMD_TARGET_BANK2;   
    Command.CommandMode=cmd;                //命令
    Command.CommandTarget=target_bank;      //目标SDRAM存储区域
    Command.AutoRefreshNumber=refresh;      //自刷新次数
    Command.ModeRegisterDefinition=regval;  //要写入模式寄存器的值
    if(HAL_SDRAM_SendCommand(&hsdram1,&Command,0X1000)==HAL_OK) //向SDRAM发送命令
    {
        return 0;  
    }
    else return 1;    
}

//在指定地址(WriteAddr+Bank5_SDRAM_ADDR)开始,连续写入n个字节.
//pBuffer:字节指针
//WriteAddr:要写入的地址
//n:要写入的字节数
void FMC_SDRAM_WriteBuffer(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t n)
{
	for(;n!=0;n--)
	{
		*(vuint8_t*)(Bank5_SDRAM_ADDR+WriteAddr)=*pBuffer;
		WriteAddr++;
		pBuffer++;
	}
}

//在指定地址((WriteAddr+Bank5_SDRAM_ADDR))开始,连续读出n个字节.
//pBuffer:字节指针
//ReadAddr:要读出的起始地址
//n:要写入的字节数
void FMC_SDRAM_ReadBuffer(uint8_t *pBuffer,uint32_t ReadAddr,uint32_t n)
{
	for(;n!=0;n--)
	{
		*pBuffer++=*(vuint8_t*)(Bank5_SDRAM_ADDR+ReadAddr);
		ReadAddr++;
	}
}

//发送SDRAM初始化序列
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram)
{
	uint32_t temp=0;
    //SDRAM控制器初始化完成以后还需要按照如下顺序初始化SDRAM
    SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_CLK_ENABLE,1,0); //时钟配置使能
    //delay_us(500);                                  //至少延时200us
	HAL_Delay(1);
    SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_PALL,1,0);       //对所有存储区预充电
    SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_AUTOREFRESH_MODE,8,0);//设置自刷新次数 
    //配置模式寄存器,SDRAM的bit0~bit2为指定突发访问的长度,
	//bit3为指定突发访问的类型,bit4~bit6为CAS值,bit7和bit8为运行模式
	//bit9为指定的写突发模式,bit10和bit11位保留位
	temp=(uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |	//设置突发长度:1(可以是1/2/4/8)
              SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |	//设置突发类型:连续(可以是连续/交错)
              SDRAM_MODEREG_CAS_LATENCY_3           |	//设置CAS值:3(可以是2/3)
              SDRAM_MODEREG_OPERATING_MODE_STANDARD |   //设置操作模式:0,标准模式
              SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;     //设置突发写模式:1,单点访问
    SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_LOAD_MODE,1,temp);   //设置SDRAM的模式寄存器
    
    //刷新频率计数器(以SDCLK频率计数),计算方法:
	//COUNT=SDRAM刷新周期/行数-20=SDRAM刷新周期(us)*SDCLK频率(Mhz)/行数
    //我们使用的SDRAM刷新周期为64ms,SDCLK=216/2=108Mhz,行数为8192(2^13).
	//所以,COUNT=64*1000*108/8192-20=823
	HAL_SDRAM_ProgramRefreshRate(&hsdram1,823);	

}	
/* USER CODE END 0 */

到此处基本已经完成大多数移植,接下来是对主函数的修改。主函数初始化部分需要进行修改,以及添加测试函数。测试函数与主函数如下。

/* USER CODE BEGIN 0 */
void LTDC_Test(void)
{
	static uint32_t i = 0;
	HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
	HAL_Delay(1000);
	switch(i)
	{
		case 0:LTDC_Clear(WHITE);break;
		case 1:LTDC_Clear(BLACK);break;
		case 2:LTDC_Clear(BLUE);break;
		case 3:LTDC_Clear(RED);break;
		case 4:LTDC_Clear(MAGENTA);break;
		case 5:LTDC_Clear(GREEN);break;
		case 6:LTDC_Clear(CYAN);break; 
		case 7:LTDC_Clear(YELLOW);break;
		case 8:LTDC_Clear(BRRED);break;
		case 9:LTDC_Clear(GRAY);break;
		case 10:LTDC_Clear(LGRAY);break;
		case 11:LTDC_Clear(BROWN);break;
	}
	i++;
	if(i == 12)
		i=0; 
	
	POINT_COLOR=RED;	  
	LCD_ShowString(10,40,260,32,32,	(uint8_t*)"Apollo STM32F4/F7"); 	
	LCD_ShowString(10,80,240,24,24,	(uint8_t*)"LTDC TEST");
	LCD_ShowString(10,110,240,16,16,	(uint8_t*)"ATOM@ALIENTEK");
	LCD_ShowString(10,130,240,16,16,	(uint8_t*)"1024*800");		//显示LCD ID	      					 
	LCD_ShowString(10,150,240,12,12,	(uint8_t*)"2016/1/6");
}

/* USER CODE END 0 */

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
	
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA2D_Init();


  /* USER CODE BEGIN 2 */
	MX_FMC_Init();
	SDRAM_Initialization_Sequence(&hsdram1);//发送SDRAM初始化序列
	MX_LTDC_Init();
	LCD_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  LTDC_Test();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

文件下载百度链接

https://pan.baidu.com/s/1AV2ogX98cGV1TmnOE1ILSg

你可能感兴趣的:(使用STM32CubeMX配置正点原子RGB屏)