注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
sjtitr的个人空间 https://home.eeworld.com.cn/space-uid-426701.html [收藏] [复制] [分享] [RSS]
日志

【试用心得】第二集——屏幕驱动之提升效率

热度 1已有 1540 次阅读2013-10-10 20:53

前天太慌乱了,昨天回来晚了,上不去论坛了,今天稍微补充点。
今天的主题是针对自己的程序进行有目的的改良,和库函数关系为0。
结果是修改了屏幕显示的有关设定,以下请看修改过程。

首先温习一下昨天的内容,见帖子:
https://bbs.eeworld.com.cn/thread-415357-1-1.html
最终的结果就是:



这样的帧速也是太矬了,无论如何也还有上升的空间,所以不妨考虑优化一下
在许多嵌入式开放当中,效率是十分重要的因素,往往可能是只要我们努努力想想办法,效率就能成倍提升。

如果要优化模拟器代码,那就实在是麻烦了,当然必须承认模拟器代码实际上还有很大的优化空间。
所以来个四两拨千斤……
之后就发现所带例程的液晶屏驱动,每次描点都要重新定位X,Y,使用的通信时序如下图
PS:原以为附赠光盘中带所有相关手册了,这一查才发现基本上呢是没有除M4F232之外的手册了。
那我本篇最后来分享一下吧。



从手册的通信时序上可以看到,描点是可以连续进行的,即只定位一次,之后就可以顺次发送之后的点的数据啦。
背景:了解NES的童鞋会知道,NES是逐行扫描,256点/扫描线,240条扫描线(就一般情况下而言吧)。
在需要提高效率的情况下,可以制定专用的有针对性的接口,以此减少冗余操作,以提高必要操作的效率。
本板子的屏幕是240*320,恰好可以用于显示NES画面,所以只要连续的描点就好了,不需要每次都定位坐标,这样就在每个点上省掉大量操作。
而因为屏幕略大而造成每行最后的少许剩余,就需要如下的设定:窗口区间描画



好了,那么有这些信息就可以开始动手了,以下是重点内容。
1.根据时序图,调整描点函数
原有的描点函数最终调用到:
static void lcd_ili932x_pixel_draw(void *pvDisplayData, long lX, long lY, unsigned long ulValue)
{
    // Set the X address of the display cursor.
    lcd_write_command(0x20);
#ifdef PORTRAIT
    lcd_write_data(lX);
#endif
#ifdef LANDSCAPE
    lcd_write_data(LCD_VERTICAL_MAX - 1 - lY);
#endif
#ifdef PORTRAIT_FLIP
    lcd_write_data(LCD_VERTICAL_MAX - 1 - lX);
#endif
#ifdef LANDSCAPE_FLIP
    lcd_write_data(lY);
#endif
    // Set the Y address of the display cursor.
    lcd_write_command(0x21);
#ifdef PORTRAIT
    lcd_write_data(lY);
#endif
#ifdef LANDSCAPE
    lcd_write_data(lX);
#endif
#ifdef PORTRAIT_FLIP
    lcd_write_data(LCD_HORIZONTAL_MAX - 1 - lY);
#endif
#ifdef LANDSCAPE_FLIP
    lcd_write_data(LCD_HORIZONTAL_MAX - 1 - lX);
#endif
    // Write the pixel value.
    lcd_write_command(0x22);
    lcd_write_data(ulValue);
}
我也没太仔细看这些东西,只看到了其中:
static void lcd_write_data(unsigned short usData)
{
LCD_SET_RS(LCD_RS_PIN);
    // Write the data to the data bus.
    //LCD_WRITE_DATA_16BIT(usData);
    HWREG(LCD_DATAH_BASE + GPIO_O_DATA + (LCD_DATAH_PINS << 2)) = (usData >> 8);   
    HWREG(LCD_DATAL_BASE + GPIO_O_DATA + (LCD_DATAL_PINS << 2)) = (usData);   
    // Assert the write enable signal.
LCD_SET_WR(0);

    // Deassert the write enable signal.
    LCD_SET_WR(LCD_WR_PIN);
}
其实很容易可以和时序图对应起来。
根据NES描画的特点,将描点函数拆成两个函数:定位和传送点数据(懒了,就直接起名为lcd_ili932x_pixel_draw_step1和lcd_ili932x_pixel_draw_step2,大家不要学我)
void lcd_ili932x_pixel_draw_step1(long lX, long lY)
{
    // Set the X address of the display cursor.
    lcd_write_command(0x20);
#ifdef PORTRAIT
    lcd_write_data(lX);
#endif
#ifdef LANDSCAPE
    lcd_write_data(LCD_VERTICAL_MAX - 1 - lY);
#endif
#ifdef PORTRAIT_FLIP
    lcd_write_data(LCD_VERTICAL_MAX - 1 - lX);
#endif
#ifdef LANDSCAPE_FLIP
    lcd_write_data(lY);
#endif
    // Set the Y address of the display cursor.
    lcd_write_command(0x21);
#ifdef PORTRAIT
    lcd_write_data(lY);
#endif
#ifdef LANDSCAPE
    lcd_write_data(lX);
#endif
#ifdef PORTRAIT_FLIP
    lcd_write_data(LCD_HORIZONTAL_MAX - 1 - lY);
#endif
#ifdef LANDSCAPE_FLIP
    lcd_write_data(LCD_HORIZONTAL_MAX - 1 - lX);
#endif
    // Write the pixel value.
    lcd_write_command(0x22);
    LCD_SET_RS(LCD_RS_PIN);
}
void lcd_ili932x_pixel_draw_step2(int ulValue)
{
    // Write the data to the data bus.
    //LCD_WRITE_DATA_16BIT(usData);
    HWREG(LCD_DATAH_BASE + GPIO_O_DATA + (LCD_DATAH_PINS << 2)) = (ulValue >> 8);   
    HWREG(LCD_DATAL_BASE + GPIO_O_DATA + (LCD_DATAL_PINS << 2)) = (ulValue);   
    // Assert the write enable signal.
    LCD_SET_WR(0);
    // Deassert the write enable signal.
    LCD_SET_WR(LCD_WR_PIN);
}
于是呢,最开始调用lcd_ili932x_pixel_draw_step1定位在(0,0),之后就由NES模拟器来逐行描点就OK了。
另一方面,为了控制每行只扫描256个点位,需要设定描画窗口范围,同样地根据手册,范围应当设定在
0000H ---- 00EFH
FF00H ---- FFEFH
这么简单,所以只要设置成
LCD_WriteRegister(0x50, 0x0000); // Horizontal GRAM Start Address
LCD_WriteRegister(0x51, 0x00EF); // Horizontal GRAM End Address
LCD_WriteRegister(0x52, 0x0000); // Vertical GRAM Start Address
LCD_WriteRegister(0x53, 0x00FF); // Vertical GRAM Start Address
不就行了嘛。额……怎么看起来有点怪怪的



好吧,经过调试,确定范围想的有点不一样,是因为屏幕的方向不是原始的方向,因此需要综合计算一下,最后应该是
LCD_WriteRegister(0x50, 0x0000); // Horizontal GRAM Start Address
LCD_WriteRegister(0x51, 0x00EF); // Horizontal GRAM End Address
LCD_WriteRegister(0x52, 0x0040); // Vertical GRAM Start Address
LCD_WriteRegister(0x53, 0x013F); // Vertical GRAM Start Address
之后效果就对了



经过调整以后就成了4fps,帧率翻倍了,可喜可贺。这次暂时搞到这里吧。
最后献上我的屏幕驱动手册。

ILI9320芯片手册.pdf

本文含有来自论坛的附件或图片点击查看原帖附件。

本文来自论坛,点击查看完整帖子内容。

发表评论 评论 (1 个评论)
回复 Bingqi23 2014-5-11 07:52
不明觉厉

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章