MCUXpresso开发RT1060(1)——使用RGB接口LCD

一、开发环境

1.TencentOS物联网开发套件,MCU为RT1060

2.IDE:MCUXpresso v11.4.1

3.屏幕为微雪4.3寸IPS屏幕,RGB888接口

二、使用MCUXpreso的配置工具

1.利用IDE的功能,从SDK中导入例程hello_world,作为程序基本框架。

2.打开IDE配置工具中的外设页面。

3.在左侧外设中添加LCDIF,打开外设LCDIF的设置。

RGB mode initialization部分根据屏幕的参数来由用户配置,包括屏幕像素帧率等参数。

在途中可以看到IDE报了一个warning。因为根据像素点和帧率等参数计算出来的LCD控制器时钟与实际时钟有差别,实际时钟是由硬件决定的,无法配置得和用户设计的参数一模一样,因此IDE会产生一个警告信息。该警告信息不影响屏幕正常工作。图中也可以看到我们设计的帧率是60Hz,但按照目前的时钟配置,实际帧率应为64Hz。

下部分Signals polarity是LCD控制信号的极性,根据屏幕的接口来设置。

 值得注意的是,LCD data bus即LCD数据总线的格式中,RGB888格式有两种,一种是未经过打包的,占用32bits的格式,另一种是舍弃了最高8位的24bits格式。这个格式一定要和自己编写的程序对应起来,否则屏幕显示会出错。

LCDIF_Buffer是显存变量,工具会以此为名称开辟一个内存空间。用户可以修改LCDIF_Buffer中的值来显示自己想要的内容。

 记得勾选上那个start RGB mode,否则需要在用户程序中加上开启RGB模式的代码。

最下面的配置内容与LCD控制器的中断有关。在该程序中,我开启了帧传输完成的中断。LCDIF_IRQn是我们需要重写的中断函数。

按照以上配置后,点击更新代码,会在工程目录中增加peripheral.c和.h文件,在其中完成了LCD的初始化工作。

三、程序代码

打开peripheral源文件和头文件,看下官方配置工具为我们完成了哪些工作。(文章中只展现出部分代码)

//peripheral.c

const elcdif_rgb_mode_config_t LCDIF_rgbConfig = {
  .panelWidth = LCDIF_PANEL_WIDTH,
  .panelHeight = LCDIF_PANEL_HEIGHT,
  .hsw = 30U,
  .hfp = 210U,
  .hbp = 30U,
  .vsw = 4U,
  .vfp = 4U,
  .vbp = 4U,
  .polarityFlags = (kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DataEnableActiveHigh | kELCDIF_DriveDataOnRisingClkEdge),
  .bufferAddr = (uint32_t) LCDIF_Buffer[0],
  .pixelFormat = kELCDIF_PixelFormatXRGB8888,
  .dataBus = kELCDIF_DataBus24Bit
};
/* RGB buffer */
AT_NONCACHEABLE_SECTION_ALIGN(uint32_t LCDIF_Buffer[2][LCDIF_PANEL_HEIGHT][LCDIF_PANEL_WIDTH], LCDIF_RGB_BUFFER_ALIGN);

这部分是构建LCD控制器的设置参数,就是我们之前在配置工具中填写的像素、帧率等设置。

最下面一行代码是申请了一段内存空间LCDIF_Buffer,用作显存。具体实现方法请看本文参考资料中的野火的RT1052开发板教程。 

//peripheral.c


static void LCDIF_init(void) {
  /* RGB mode initialization */
  ELCDIF_RgbModeInit(LCDIF_PERIPHERAL, &LCDIF_rgbConfig);
  /* Enable interrupts */
  ELCDIF_EnableInterrupts(LCDIF_PERIPHERAL, (kELCDIF_CurFrameDoneInterruptEnable));
  /* Enable interrupt LCDIF_IRQn request in the NVIC. */
  EnableIRQ(LCDIF_LCDIF_IRQN);
  /* RGB mode start */
  ELCDIF_RgbModeStart(LCDIF_PERIPHERAL);
}

/***********************************************************************************************************************
 * Initialization functions
 **********************************************************************************************************************/
void BOARD_InitPeripherals(void)
{
  /* Initialize components */
  LCDIF_init();
}

/***********************************************************************************************************************
 * BOARD_InitBootPeripherals function
 **********************************************************************************************************************/
void BOARD_InitBootPeripherals(void)
{
  BOARD_InitPeripherals();
}

 看这些函数的名字就知道,这段代码是对外设LCD控制器的初始化和中断配置,并进行了层层包装。我们在main函数中调用最后的BOARD_InitBootPeripheraals函数即可完成对外设的初始化。

从上述代码分析中可知,配置工具已经帮我们把LCD控制器设置好了,用户只需要调用一个函数即可,降低了代码开发量。之后用户根据自己需求,设计应用层面的代码即可。

我写了一段代码,让屏幕交替显示蓝色和白色。主要还是参考了野火的RT1052教程中的程序。

//mylcd.c

#include "my_rd_lcd.h"
#include "fsl_common.h"
#include "stdint.h"
#include "fsl_debug_console.h"
#define MY_RD_LCD_TEST 1
//创建显存空间
//同样已通过IDE自带的设计工具设置好
//AT_NONCACHEABLE_SECTION_ALIGN(pixel_t
//s_psBufferLcd[2][LCD_PIXEL_HEIGHT][LCD_PIXEL_WIDTH], FRAME_BUFFER_ALIGN);

static uint32_t current_frame_buff = (uint32_t)LCDIF_Buffer[0];

static pixel_t current_text_color = CL_WHITE;
static pixel_t current_back_color = CL_BLUE;

static uint8_t s_frameDone = 1;
static uint8_t frameBufferIndex = 0;
/* 帧计数器 */
static volatile uint32_t s_frame_count = 0;
static void put_pixel(uint16_t x, uint16_t y, pixel_t color)
{
	if((x < LCDIF_PANEL_WIDTH) && (y < LCDIF_PANEL_HEIGHT))
	{
		//LCDIF_Buffer[0][y][x] = color;
		*(pixel_t*)(current_frame_buff + LCD_BPP*(x + (LCDIF_PANEL_WIDTH * y))) = color;
	}
}

void LCDIF_LCDIF_IRQHANDLER(void)
{
	volatile uint32_t intStatus;
	intStatus = ELCDIF_GetInterruptStatus(LCDIF);
	ELCDIF_ClearInterruptStatus(LCDIF, intStatus);
	if (intStatus & kELCDIF_CurFrameDone)
	{
		s_frameDone = 1;
		s_frame_count++;
	}
}

四、运行结果

本程序让屏幕显示完一帧数据后,立刻显示下一帧,并通过systick中断计时,计算出屏幕的刷新帧率,可以达到80的帧率。

在此还遇到了个问题,LCDIF的时钟源默认是选用PLL3产生的,实测中发现LCD的时钟频率不对,改为PLL2后,才是正确的时钟频率,尚待探究。

利用MCUXpresso用户可以非常方便地开发NXP的单片机程序,尤其是使用RT1060这种跨界MCU中比较复杂的外设。用户使用官方的配置工具更有助于理解外设的功能,不必对着官方例程一行一行地改代码了,加快开发进度,减少出错的概率。

用惯了KEIL开发ARM后,使用这种基于eclipse的IDE还是感觉有些不习惯。但是因为是NXP官方设计的,更加适合开发NXP的单片机,而且提供了许多KEIL没有的更便于开发的工具。而且这种IDE还是完全免费的,对于个人爱好者而言,还是很有必要学习并使用MCUXpresso来开发单片机项目的。

更新:

该问题已解决。原因是IDE生成clock.c中把PLL3的时钟分频代码注释掉了。

 

五、参考

i.MX RT1060 | Crossover MCU with ARM Cortex-M7, 1 MB SRAM | NXP Semiconductorshttps://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/i-mx-rt-crossover-mcus/i-mx-rt1060-crossover-mcu-with-arm-cortex-m7-core:i.MX-RT1060

Embedfire-rt1052: 野火imx-rt1052开发板项目组https://gitee.com/Embedfire-rt10524.3inch Capacitive Touch LCD - Waveshare Wikihttps://www.waveshare.net/wiki/4.3inch_Capacitive_Touch_LCD2021 TencentOS Tiny AIoT应用创新大赛TencentOS Tiny  AIoT 应用创新大赛是腾讯TencentOS团队联合恩智浦半导体、ARM中国发起的线上开发者活动,主要面向中小企业嵌入式工程师、广大嵌入式开发者、物联网爱好者、创客团队等,期待广大开发者能参与到国内开源项目中,通过开源协同,基于TencentOS Tiny打造更多新颖、实用、有价值和创造力的AIoT应用及解决方案。https://cloud.tencent.com/developer/competition/introduction/10032

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值