韦东山嵌入式第一期学习笔记DAY_18——17_3——17_5_LCD编程_框架——思路梳理

作者:GWD 时间:2019.7.22

课程内容:分析LCD与S3C2440lcd控制器的框架,并写出一些结构体
思路:
Lcd.h->controller.h->s3c2440_controller.h->lcd_controller.c
lcd.h:包含了结构体,结构体内容为LCD的一些常用参数名称,分辨率、时序等等;
lcd_controller.h:面向对象的手法创建了lcd_controller,函数结构体,元素是lcd.h中的结构体,方法是controller初始化函数、使能、失能这三个函数,从而实现了面向对象中类的概念;
lcd_controller.c:这个函数要引用上面的头文件,将需要的lcd参数结构体与lcd控制器初始化的面向对象的函数结构体相关联,本章的目的就是将4.3寸LCD与S3C2440_LCD_CONTROLLER想结合;
s3c2440_lcd_controller.c:根据S3C2440的手册与lcd.h中lcd的参数结构体结合完成了2440的lcd控制器初始化。
在这里插入图片描述
第一步:先构建最底层的lcd.h将lcd常用的一些参数写进去,注意结构体一般写在头文件中

#ifndef _LCD_H_
#define _LCD_H_

enum{
	NORMAL = 0,
	INVERT  = 1,
};

typedef struct pins_polarity{
	int vclk;  /* normal: 在下降沿获取数据 */
	int rgb;   /* normal: 高电平表示1 */
	int hsync; /* normal: 高脉冲 */
	int vsync; /* normal: 高脉冲 */	
}pins_polarity,*p_pins_polarity;

typedef struct time_sequence{
	/* 垂直方向 */
	int tvp; /* vysnc脉冲宽度 */
	int tvb; /* 上边黑框, Vertical Back porch */
	int tvf; /* 下边黑框, Vertical Front porch */

	/* 水平方向 */
	int thp; /* hsync脉冲宽度 */
	int thb; /* 左边黑框, Horizontal Back porch */
	int thf; /* 右边黑框, Horizontal Front porch */

	int vclk;
}time_sequence,*p_time_sequence;

typedef struct lcd_params{
/*引脚极性*/
	pins_polarity pins_pol;
/*时序*/
	time_sequence time_seq;
/*分辨率,bpp*/
	int xres;
	int yres;
	int bpp;
/*framebuffer的地址*/
	unsigned int fb_base;
}lcd_params,*p_lcd_params;

#endif


第二步:构建lcd_introller.h文件,在这里实现面向对象,在函数结构体中即有变量(lcd_params结构体),又有方法(void (*init)(p_lcd_params plcdparams);)

#ifndef _LCD_CONTROLLER_H
#define _LCD_CONTROLLER_H

#include "lcd.h"

typedef struct lcd_controller{
	void (*init)(p_lcd_params plcdparams);
	void (*enable)(void);
	void (*disable)(void);
}lcd_controller,*p_lcd_controller;
#endif

第三步:在lcd_controller.c中,实现lcd_controller.h中的几个函数

void lcd_controller_init(p_lcd_controller plcdparams){

}

void lcd_controller_enable(void){

}

void lcd_controller_disable(void){

}

第四步:在s3c2440_lcd_controller.c中调用初始化函数->lcd_params(内容比较多展开叙述)
(一)、完成void s3c2440_lcd_controller_init(p_lcd_params plcdparams),函数功能是根据传入的lcd结构体设置LCD控制器
1、设置第一个寄存器
在这里插入图片描述
其中CLKVAL的确定需要查看LCD手册知道VCLK的值,是9。
在这里插入图片描述

/* [17:8]: clkval, vclk = HCLK / [(CLKVAL+1) x 2]
	 *                   9   = 100M /[(CLKVAL+1) x 2], clkval = 4.5 = 5
	 *                 CLKVAL = 100/vclk/2-1
	 * [6:5]: 0b11, tft lcd
	 * [4:1]: bpp mode
	 * [0]  : LCD video output and the logic enable/disable
	 */	
	int clkval = (double)HCLK/plcdparams->time_seq.vclk/2-1+0.5;
	int bppmode = plcdparams->bpp == 8  ? 0xb :\
				  plcdparams->bpp == 16 ? 0xc :\
				  0xd;  /* 0xd: 24bpp */
	LCDCON1 = (clkval<<8) | (3<<5) | (bppmode<<1) ;	

2、设置第二个寄存器
这个寄存器是用来设置与垂直方向相关及时序频率相关的时序的
在这里插入图片描述
要对照s3c2440与lcd的手册确定时序的值
在这里插入图片描述
在这里插入图片描述
注:时序图一般写的是normal模式

/* [31:24] : VBPD    = tvb - 1
	 * [23:14] : LINEVAL = line - 1
	 * [13:6]  : VFPD    = tvf - 1
	 * [5:0]   : VSPW    = tvp - 1
	 */
	LCDCON2 = 	((plcdparams->time_seq.tvb - 1)<<24) | \
	            ((plcdparams->yres - 1)<<14)         | \
				((plcdparams->time_seq.tvf - 1)<<6)  | \
				((plcdparams->time_seq.tvp - 1)<<0);


3、设置第3个寄存器
与水平方向相关的设置
在这里插入图片描述

/* [25:19] : HBPD	 = thb - 1
	 * [18:8]  : HOZVAL  = 列 - 1
	 * [7:0]   : HFPD	 = thf - 1
	 */
	LCDCON3 =	((plcdparams->time_seq.thb - 1)<<19) | \
				((plcdparams->xres - 1)<<8)		      | \
				((plcdparams->time_seq.thf - 1)<<0);


4、设置第四个寄存器
在这里插入图片描述
/*
* [7:0] : HSPW = thp - 1
*/
LCDCON4 = ((plcdparams->time_seq.thp - 1)<<0);
5、设置第五个寄存器
这个寄存器是决定引脚的性质的。
在这里插入图片描述
在这里插入图片描述

/* 用来设置引脚极性, 设置16bpp, 设置内存中象素存放的格式
     * [12] : BPP24BL
	 * [11] : FRM565, 1-565
	 * [10] : INVVCLK, 0 = The video data is fetched at VCLK falling edge
	 * [9]  : HSYNC是否反转
	 * [8]  : VSYNC是否反转
	 * [7]  : INVVD, rgb是否反转
	 * [6]  : INVVDEN
	 * [5]  : INVPWREN
	 * [4]  : INVLEND
	 * [3]  : PWREN, LCD_PWREN output signal enable/disable
	 * [2]  : ENLEND
	 * [1]  : BSWP
	 * [0]  : HWSWP
	 */

	pixelplace = plcdparams->bpp == 24 ? (0) : |\
	             plcdparams->bpp == 16 ? (1) : |\
	             (1<<1);  /* 8bpp */
	LCDCON5 = (plcdparams->pins_pol.vclk<<10) |\
	          (plcdparams->pins_pol.rgb<<7)   |\
	          (plcdparams->pins_pol.hsync<<9) |\
	          (plcdparams->pins_pol.vsync<<8) |\
 			  (plcdparams->pins_pol.de<<6)    |\
			  (plcdparams->pins_pol.pwren<<5) |\
			  (1<<11) | pixelplace;


6、设置第六、七、八寄存器
这几个寄存器是决定显存的;
在这里插入图片描述
注意:这个寄存器的1-30位是保存数据的,所以在操作的时候就是去掉基地址的第31位然后右移一位。

/* framebuffer地址 */
/*
 * [29:21] : LCDBANK, A[30:22] of fb
 * [20:0]  : LCDBASEU, A[21:1] of fb
 */
addr = plcdparams->fb_base & ~(1<<31);
LCDSADDR1 = (addr >> 1);

在这里插入图片描述
将显存的结束地址放在这歌寄存器的1-21位。

	/* 
	 * [20:0] : LCDBASEL, A[21:1] of end addr
	 */
	addr = plcdparams->fb_base + plcdparams->xres*plcdparams->yres*plcdparams->bpp/8;
	addr >>=1;
	addr &= 0x1fffff;
	LCDSADDR2 = addr;//	



(二)、完成使能和失能函数

void s3c2440_lcd_controller_enalbe(void)
{
	/* 背光引脚 : GPB0 */
	GPBDAT |= (1<<0);
	
	/* pwren    : 给LCD提供AVDD  */
	LCDCON5 |= (1<<3);
	
	/* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
	LCDCON1 |= (1<<0);
}

void s3c2440_lcd_controller_disable(void)
{
	/* 背光引脚 : GPB0 */
	GPBDAT &= ~(1<<0);

	/* pwren	: 给LCD提供AVDD  */
	LCDCON5 &= ~(1<<3);

	/* LCDCON1'BIT 0 : 设置LCD控制器是否输出信号 */
	LCDCON1 &= ~(1<<0);
}

(三)、
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
初始化引脚为LCD控制模式

void jz2440_lcd_pin_init(void)
{
	/* 初始化引脚 : 背光引脚 */
	GPBCON &= ~0x3;
	GPBCON |= 0x01;

	/* LCD专用引脚 */
	GPCCON = 0xaaaaaaaa;
	GPDCON = 0xaaaaaaaa;

	/* PWREN */
	GPGCON |= (3<<8);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值