OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7817|回复: 12

学习STM32 玩TFT屏 第五季

[复制链接]

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
发表于 2012-6-22 04:46:01 | 显示全部楼层 |阅读模式
 
好,这一季,我们来说说我手头上的这个B505的屏的问题.

我们先看看它是如何表达颜色的.上些季我们学了颜色的格式,就是  Bit0~Bit4 表示蓝色,  Bit5~Bit10表示绿色.  Bit11~Bit15表示红色.

蓝色,红色用5个Bit来表示,绿色用6个Bit来表示.就是说  蓝色和红色只有31个色阶.我们人眼能分辨出256种色阶,我们的数码产品显示图片,都是256个色阶.多了没用,我们分不出来.
所以可以十分肯定,这种屏显示文字可以,但显示图片会很坑爹.丢个灰度球进去那个球就象西瓜一样了.很多色阶显不出来,显示图片会丢很多细节.

好,我们写些代码,一个个色来显示出他的各色阶情况.我们的屏有320行,如每10条线一种色阶,那就能将31个色阶全显出来.我们更改一下MAIN()函数.显示一下蓝色的色阶.


int main(void)
{
  u16  RGB1;
  u16 CRGB,k,l;
  u16 i,j;
  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

  while (1) 
    {   
//******************************************************************************************** 
LCD_WriteReg(0x0020,0x00);  //X
LCD_WriteReg(0x0021,0x00);  //Y
LCD_WR_REG(0x22);

RGB1=CRGB=0x00;//0x1f;
k=0;
for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_WR_DATA(CRGB);
}
 k=k+1;
 if (k==10)
 {
RGB1=RGB1+1;
CRGB=RGB1;
k=0;

 }
}

//******************************************************************************************** 
}
}

大家看一下,这就是我们所能出的纯蓝色.只能有这么多种了纯蓝了.我们再试下红色,代码如下:


int main(void)
{
  u16  RGB1;
  u16 CRGB,k,l;//FOX[5]={0x001F,0XF81F,0XFFE0,0X07FF,0xF800};
  u16 i,j;
  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

//  LCD_WriteReg(0x0007, 0x0);   //<<====关屏
//  LCD_WriteReg(0x0007, 0x0173); //26万色显示开启    1001000100000

  while (1) 
    {   
//******************************************************************************************** 
LCD_WriteReg(0x0020,0x00);  //X
LCD_WriteReg(0x0021,0x00);  //Y
LCD_WR_REG(0x22);

RGB1=CRGB=0x00;//0x1f;
k=0;
for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_WR_DATA(CRGB);
}
 k=k+1;
 if (k==10)
 {
RGB1=RGB1+1;
CRGB=RGB1<<11;
k=0;

 }
}

//******************************************************************************************** 
}
}

好,我们再来显示一下绿色.因为它用6个Bit来表示,比蓝色和红色多一倍.所以我们画5行再加一个色阶.代码如下.

int main(void)
{
  u16  RGB1;
  u16 CRGB,k,l;//FOX[5]={0x001F,0XF81F,0XFFE0,0X07FF,0xF800};
  u16 i,j;
  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

//  LCD_WriteReg(0x0007, 0x0);   //<<====关屏
//  LCD_WriteReg(0x0007, 0x0173); //26万色显示开启    1001000100000

  while (1) 
    {   
//******************************************************************************************** 
LCD_WriteReg(0x0020,0x00);  //X
LCD_WriteReg(0x0021,0x00);  //Y
LCD_WR_REG(0x22);

RGB1=CRGB=0x00;//0x1f;
k=0;
for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_WR_DATA(CRGB);
}
 k=k+1;
 if (k==5)
 {
RGB1=RGB1+1;
CRGB=RGB1<<5;
k=0;

 }
}

//******************************************************************************************** 
}
}


看到没有,三种颜色我们都看过了,发现在暗色的那好几个色阶很明显分段.说明它在显示图片时暗色部位失真更厉害,失直多少?那要用专业的分光密度仪来量了. 色彩学有很多很多东东可以说,
我们到此为止吧,要不几十季都说不完.

有人说为啥不写个代码一次全显出来?其实我是从一次显三色的代码改过来的,我有个经验要说一下,学习计算机或其外设的时候,写代码越简单越好,经验告诉我,写得复杂的话还没学会
就在找自己的代码的错处.这样越学就越不想学了.最快的时间出成绩,才会让我们更有兴趣学下去!

好了,我再扫一下色学盲,RGB有了,那么他们的补色,就是它们的反色是怎么显示出来呢,它的的补色是  CMY  青品黄   ,红色R的补色是青C, 绿G的补色是品色M,蓝B的补色是黄,  它们的关系就象
数学的正负数, 合在一起就会没有颜色!! 相互吸叫掉了,如你用蓝色的电筒去照黄的的纸, 你看到的颜色是黑色!!

我们如何用RGB来产生CMY呢,三基色原理==>  B+G=C   B+R=M   R+G=Y   ,明白了吧,RGB中,任意两种颜色的各是第三种颜色的补色!!

好,我们来写个代码显示青色CMY, RGB的数值都是等量的:

好,先来显示C的代码:

int main(void)
{
  u16  RGB1,RGB2,RGB3;
  u16 CRGB,k,l;//FOX[5]={0x001F,0XF81F,0XFFE0,0X07FF,0xF800};
  u16 i,j;
  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

  while (1) 
    {   
//******************************************************************************************** 
LCD_WriteReg(0x0020,0x00);  //X
LCD_WriteReg(0x0021,0x00);  //Y
LCD_WR_REG(0x22);

RGB1=RGB2=RGB3=CRGB=0x00;//0x1f;
k=0;
for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_WR_DATA(CRGB);
}
 k=k+1;
 if (k==10)
 {
RGB1=RGB1+1;
CRGB=RGB1;

RGB2=RGB2+2;   <<====也可以加1,但觉得青不够,你们可以试一下加1看结果
RGB3=RGB2<<5;

CRGB |=RGB3;
k=0;

 }
}

//******************************************************************************************** 
}
}

不要以为是蓝哈,这是青!!只是不纯的青!!因为这屏只能表达成这样了.

好,品M是这样的.代码如下:

int main(void)
{
  u16  RGB1,RGB2,RGB3;
  u16 CRGB,k,l;//FOX[5]={0x001F,0XF81F,0XFFE0,0X07FF,0xF800};
  u16 i,j;
  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

  while (1) 
    {   
//******************************************************************************************** 
LCD_WriteReg(0x0020,0x00);  //X
LCD_WriteReg(0x0021,0x00);  //Y
LCD_WR_REG(0x22);

RGB1=RGB2=RGB3=CRGB=0x00;//0x1f;
k=0;
for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_WR_DATA(CRGB);
}
 k=k+1;
 if (k==10)
 {
RGB1=RGB1+1;
CRGB=RGB1;

RGB2=RGB2+1;
RGB3=RGB2<<11;

CRGB |=RGB3;
k=0;

 }
}

//******************************************************************************************** 
}
}

这就是品了,好,显示黄色的代码如下:

int main(void)
{
  u16  RGB1,RGB2,RGB3;
  u16 CRGB,k,l;//FOX[5]={0x001F,0XF81F,0XFFE0,0X07FF,0xF800};
  u16 i,j;
  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

  while (1) 
    {   
//******************************************************************************************** 
LCD_WriteReg(0x0020,0x00);  //X
LCD_WriteReg(0x0021,0x00);  //Y
LCD_WR_REG(0x22);

RGB1=RGB2=RGB3=CRGB=0x00;//0x1f;
k=0;

for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_WR_DATA(CRGB);
}
 k=k+1;
 if (k==10)
 {
RGB1=RGB1+2;<<====也可以加1,但觉得青不够,但加了2绿又多了......你们可以试一下加1看结果
CRGB=RGB1<<5;

RGB2=RGB2+1;
RGB3=RGB2<<11;

CRGB |=RGB3;
k=0;

 }
}

//******************************************************************************************** 
}
}

这就是黄.有人说有几行偏色了.对,没错,我们的屏只能这样了,我们的屏是给山寨手机用的.显示字符可以但显示图片是太勉强它了.

其实,要真正能按要求显示纯正图片的屏普通人是很难见到的,这样的屏,21英寸的,价格要20万人民币左右.我们常用的电脑显示屏,要稳定达到正真的真彩,是达不到的.SO我们的电脑
显示器只要1000左右,山寨手机屏 30元左右, 所以,我们要知足哈.

好了,从我的B505颜色寄存器可知,能显示2的16次方种颜色,就是65535种色彩.灰阶只有31种.

好,我们写个灰阶的代码出来:~~~~~~~~~~~~~~~

不行,为啥呢?

因为大家看 原子的书, 153页.   屏里的寄存器  是18位的.就是说红色的Bit0和Bit5是连在一起的.蓝色的Bit4和Bit0是连在一起的.坑爹了!!!!!!!!!!!!!!!!!!!!

就是说,要在屏的显存里RGB三个色的值都一样的话,只有很少的几个值了.我编了个程式,算出 只有 0到7 25到31这15个值的时候 屏里的RGB三色的色值才相等.所以 代码只能这样写了:
那么上边的CMY的代码都得变了,怎么变,大家自己思考了,真坑爹呀,不够脚就不要加内存嘛,这样搞更麻烦,真不知做屏的人怎么想的!!

int main(void)
{
  u16  CRGB,RGB0,RGB1,RGB2,RGB3,RGB4,RGB5;
  u16  i,j,k,l;

  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

//  LCD_WriteReg(0x0007, 0x0);   //<<====关屏
//  LCD_WriteReg(0x0007, 0x0173); //26万色显示开启    1001000100000

  while (1) 
    {   
//******************************************************************************************** 
LCD_WriteReg(0x0020,0x00);  //X
LCD_WriteReg(0x0021,0x00);  //Y
LCD_WR_REG(0x22);

RGB0=RGB1=RGB2=RGB3=RGB4=CRGB=0x00;

k=l=0;
for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_WR_DATA(CRGB);
}
 k=k+1;
 if (k==10)
 {
RGB0=RGB0+1;

RGB1=RGB1+2;<<====也可以加1,但觉得偏品色,你们可以试一下加1看结果
RGB2=RGB1<<5;

RGB3=RGB3+1;
RGB4=RGB3<<11;

l=l+1;
if ((l<=7)|(l>=25))
{
CRGB =RGB0|RGB2|RGB4;
}
k=0;

 }
}

//******************************************************************************************** 
}
}

看到没,这个灰中间层掉了好多.只能有一头一尾......................
哇靠呀,这个屏基本做不了颜色运算.白搭.只能做些简单的色彩介面了,但总比我们之前用过的屏好多了~~~~~~~~~~~~~~~~~~~


我的工作就是天天在玩
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2011-8-16
在线时间
0 小时
发表于 2012-6-22 06:59:17 | 显示全部楼层
楼主好早啊,写得很好,顶了。
STM32好难……
回复 支持 反对

使用道具 举报

117

主题

598

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
1702
金钱
1702
注册时间
2012-5-10
在线时间
439 小时
发表于 2012-6-22 15:33:24 | 显示全部楼层
回复【楼主位】chinafox:
---------------------------------
最快的时间出成绩,才会让我们更有兴趣学下去!
十分同意这句话
如有技术问题,微信扫头像交流,STM32,JAVA,服务器
回复 支持 反对

使用道具 举报

2

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2012-5-7
在线时间
8 小时
发表于 2012-6-22 16:16:24 | 显示全部楼层
楼主你太犀利了,看着你的帖子真的学的好多啊!呵呵,希望楼主继续啊
耐心做事,好好做人。O(∩_∩)O!
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2012-6-8
在线时间
3 小时
发表于 2012-6-27 09:10:43 | 显示全部楼层
 
RGB1=CRGB=0x00;//0x1f;   问楼主,这句话后面那个注释什么意思
回复 支持 反对

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
 楼主| 发表于 2012-7-5 22:34:12 | 显示全部楼层
哈,木有任何意思。可以无视
我的工作就是天天在玩
回复 支持 反对

使用道具 举报

25

主题

163

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
443
金钱
443
注册时间
2012-4-29
在线时间
38 小时
发表于 2014-2-25 20:51:44 | 显示全部楼层
发个在战舰上用的刷blue色的程序。
int main(void)
{

u16 RGB1;
u16 k;
u16 i,j;
u8 lcd_id[12]; //存放LCD ID字符串
   Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,9600);   //串口初始化为9600
delay_init(72);       //延时初始化 
LED_Init();    //初始化与LED连接的硬件接口
  LCD_Init();
sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
POINT_COLOR=0x0000;


   while(1) 
{
RGB1=0x0000;
k=0;
for (i=0;i<320;i++) 
{
for (j=0;j<240;j++)
{
LCD_DrawPoint(j,i);
}
  k=k+1;
if (k==10)
{
RGB1=RGB1+1;
POINT_COLOR=RGB1;
k=0; 
}
}
   }
}
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2014-5-19
在线时间
0 小时
发表于 2014-5-19 09:36:37 | 显示全部楼层
我滴个乖乖,这个楼主真的是碉堡了,从OLED第一节跟过来,一路受益匪浅
敬畏耶和华是智慧的开端,认识至圣者便是聪明。
回复 支持 反对

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
 楼主| 发表于 2014-5-20 01:02:51 | 显示全部楼层
给本尊吓尿了吧?哈哈哈。因为我搞过几年的颜色。
我的工作就是天天在玩
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
发表于 2014-6-4 15:48:08 | 显示全部楼层
请教楼主一个问题,我以前TFT屏用原子哥配的例程下载进去都可以实现功能,刚才关了下开发板的电源,然后再开,就发现TFT屏一直只有显示白色,无论程序怎么改TFT屏都只是白色。。我有点吓尿的感觉
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
 楼主| 发表于 2014-6-7 02:48:49 | 显示全部楼层
关久点再开。一个TFT屏才十几元,多大的事呀。
我的工作就是天天在玩
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2012-2-11
在线时间
3 小时
发表于 2014-6-7 16:55:03 | 显示全部楼层
楼主辛苦,过来学习一下啊~~~
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2014-6-12
在线时间
0 小时
发表于 2014-6-21 11:40:30 | 显示全部楼层
好人一生平安。。。。。。。。。。。
呵呵=呵呵
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-7 00:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表