历史上的今天
今天是:2024年09月29日(星期日)
2018年09月29日 | STM32f4---TFTLCD显示实验代码(02)
2018-09-29 来源:eefocus
第七个要介绍的函数是坐标设置函数,该函数代码如下:
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{
if(lcddev.id==0X9341||lcddev.id==0X5310)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_DATA(Ypos&0XFF);
}else if(lcddev.id==0X6804)
{
if(lcddev.dir==1)Xpos=lcddev.width-1-Xpos;//横屏时处理
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_DATA(Ypos&0XFF);
}else if(lcddev.id==0X5510)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_REG(lcddev.setxcmd+1);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_REG(lcddev.setycmd+1);
LCD_WR_DATA(Ypos&0XFF);
}else
{
if(lcddev.dir==1)Xpos=lcddev.width-1-Xpos;//横屏其实就是调转x,y坐标
LCD_WriteReg(lcddev.setxcmd, Xpos);
LCD_WriteReg(lcddev.setycmd, Ypos);
}
}
该函数实现将 LCD 的当前操作点设置到指定坐标(x,y)。因为 9341/5310/6804/5510 等的设置同其他屏有些不太一样,所以进行了区别对待。
接下来我们介绍第八个函数:画点函数。该函数实现代码如下:
//画点
//x,y:坐标
//POINT_COLOR:此点的颜色
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
LCD->LCD_RAM=POINT_COLOR;
}
该函数实现比较简单,就是先设置坐标,然后往坐标写颜色。其中POINT_COLOR 是我们定义的一个全局变量,用于存放画笔颜色,顺带介绍一下另外一个全局变量:BACK_COLOR,该变量代表 LCD 的背景色。LCD_DrawPoint 函数虽然简单,但是至关重要,其他几乎所有上层函数,都是通过调用这个函数实现的。
有了画点,当然还需要有读点的函数,第九个介绍的函数就是读点函数,用于读取 LCD的 GRAM,这里说明一下,为什么OLED模块没做读GRAM的函数,而这里做了。因为OLED模块是单色的,所需要全部GRAM也就1K个字节,而TFTLCD 模块为彩色的,点数也比OLED模块多很多,以16位色计算, 一款320×240的液晶,需要320×240×2个字节来存储颜色值,也就是也需要 150K 字节,这对任何一款单片机来说,都不是一个小数目了。而且我们在图形叠加的时候,可以先读回原来的值,然后写入新的值,在完成叠加后,我们又恢复原来的值。这样在做一些简单菜单的时候,是很有用的。这里我们读取 TFTLCD 模块数据的函数为LCD_ReadPoint,该函数直接返回读到的 GRAM 值。该函数使用之前要先设置读取的 GRAM地址,通过LCD_SetCursor函数来实现。LCD_ReadPoint的代码如下:
//读取个某点的颜色值
//x,y:坐标
//返回值:此点的颜色
u16 LCD_ReadPoint(u16 x,u16 y)
{
vu16 r=0,g=0,b=0;
if(x>=lcddev.width||y>=lcddev.height)return 0; //超过了范围,直接返回
LCD_SetCursor(x,y);
if(lcddev.id==0X9341||lcddev.id==0X6804||lcddev.id==0X5310)LCD_WR_REG(0X2E);
//9341/6804/3510 发送读GRAM指令
else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00); //5510 发送读GRAM指令
else LCD_WR_REG(R34); //其他 IC 发送读GRAM指令
if(lcddev.id==0X9320)opt_delay(2); //FOR 9320,延时2us
LCD_RD_DATA(); //dummy Read
opt_delay(2);
r=LCD_RD_DATA(); //实际坐标颜色
if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)
{ //9341/NT35310/NT35510要分 2次读出
opt_delay(2);
b=LCD_RD_DATA();
g=r&0XFF;//9341/5310/5510等,第一次读取的是RG的值,R 在前,G 在后,各占 8位
g<<=8;
}
if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0XB505||
lcddev.id==0XC505)return r; //这几种 IC 直接返回颜色值
else if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)return (((r>>11)<<11)
|((g>>10)<<5)|(b>>11)); //ILI9341/NT35310/NT35510 需要公式转换一下
else return LCD_BGR2RGB(r); //其他 IC
}
在 LCD_ReadPoint 函数中,因为我们的代码不止支持一种 LCD 驱动器,所以,我们根据不同的 LCD 驱动器((lcddev.id)型号,执行不同的操作,以实现对各个驱动器兼容,提高函数的通用性。
史海拾趣
|
并行口与串行口的区别是交换信息的方式不同,并行口能同时通过8条数据线传输信息,一次传输一个字节;而串行口只能用1条线传输一位数据,每次传输一个字节的一位。并行口由于同时传输更多的信息,速度明显高于串行... … 查看全部问答> |
|
初学者, 想去 示波器,以及电源器 刚才淘宝上看到一处买示波器, 有几种价格,便宜的三四百, 不知道能不能用, 各价格有什么区别,懂的人看看 http://store.taobao.com/shop/xshop/wui_page-cat-35391858-36790672-ob7Eo8Tiyr6yqMb3ob8=.htm ...… 查看全部问答> |
|
或者说在task A中让task B退出。 如果调用taskExit(), 该接口不带参数,无法指定到task B退出,只能使当前调用的task exit。 请问有没有方法让task B能退出?(注意不是删除task B) task B退出后的task status是什么?… 查看全部问答> |
|
小弟我看EBOOT的相关内容,在BOOTLOADERMAIN()中有个KernelRelocate()函数。 static BOOL KernelRelocate (ROMHDR *const pTOC) { ULONG loop; COPYentry *cptr; if (pTOC == (ROMHDR *const) ...… 查看全部问答> |
|
移植2.6内核问题!Failed to execute /linuxrc boot ram 0x30008000 Copy linux kernel from 0xea0000b1 to 0x30008000, size = 0xea0000b3 ... done zImage magic = 0x016f2818 Setup linux parameters at 0x30000100 linux command line is: \"noinitrd root=/dev/mtdblock3 init=/linuxrc ...… 查看全部问答> |




