经过近两个星期的奋战!今天我敢说我成功了,因为我在液晶屏上成功的显示了彩色图片!真是不容易啊。回顾这些日子,我没睡一个安稳觉,实验达一百多次,与现在兴奋相比,都是浮云了!再一次次失败中我也在总结经验,一直在问位什么?下面:
我开始做TFT液晶实在做完SD卡之后,虽然我没有弄文件系统,可是SD作为一个超大容量的RAM还是可以的,这一点我在技术上是能实现的!那么怎样才能把SD卡上的数据准确无误的显示在TFT液晶上呢?没有任何头绪,虽然做过12864但是你看看TFT的数据手册,你就明白了什么叫做不是一个级别!做之前,我在网上疯狂的搜着关于TFT液晶的资料,最后只找到了一份英文的TFT手册,我不懂英文!但还没有中文的!在网上的大都是只言片语的简介!于是开始用金山词霸翻译!大约有一个星期左右,关于TFT大概的知识懂了一点g点,当然现在的我也只是知道一点!因为他的功能实在是太强了!知道了控制器是9325的!知道了他的数据操作时分很多种的(16,8,SPI,...)。知道了他内部的寄存器很多!但是那是的我认为,不就是一块液晶吗!能难倒哪去?我现在才知道我当时错了!大概有个了解后,我开始搭接实验板!单片机驱动液晶调试正式开始,按照8位数据传输模式连接接口!数据按照一次传送8位,传两次(因为不论是数据还是指令都是16位的数据结构)高字节在前的顺序!开始我只想运行刷屏的程序,可是迟迟不能运行,后来发现是数据跟指令没搞明白!RS=1表示写的是数据,RS=0表示写的是寄存器的地址。然后初始化,这里的初始话我是调用别人的做好的!后来程序开始在液晶上运行了!当然是刷屏程序!接下来市让屏幕上显示彩条!就想电视里的那种一条红一条绿,一样,这是为了测试液晶的GRAM你能可靠地控制!我实现这一步也要感谢网络!正式网络我才一点点的积累经验,实现了自如的控制GRAM的显示!(我想在液晶的任意坐标系内显示任意的颜色或色条!)到这里我不禁想起了12864,因为当你控制了这一点时,你基本上离显示图片不远了!因为你控制了这一点很容易的能实现行和场的扫描!有了行场扫描你就可以显示一幅画了!当然这是理论上!这是前天晚上的事!昨天一天我都在调一个东西!那就是关键的也是最后一步!SD卡和TFT液晶联合试验!单片机要完成从SD卡中读取数据!然后送入到TFT液晶的控制器里,并且提供行扫描光和场扫描!SD卡的程序我以前调好的,直接拿来用!液晶的也拿来用,组合起来用XDATE中的RAM作为联系两个期间的数据缓冲单元!当我写入内存卡一幅图片!想着显示出的画面有多好时!打开电源!扫描开始!然而我失望了!出来的竟然是无数的红绿白黑的点!俗称花屏!为什么会这样那?我开始考虑!是不是取模有问题!然后改变image2lcd的取模方式!复制粘贴!WINHEX中查看数据!这样反复,还是不能显示!相反出现了一个有趣的现象!出现了很多网文!这是行场不同步,像素没有正确的写入自己的位置造成的!这个问题从昨天下午直到半夜!还是没解决!心情很郁闷!但是我总感觉我里成功很近了,一步之遥!昨晚上做到很晚,梦里还在想!结果谁大了,7:30才醒!醒了我就在想这个网文!我忽略了一个细节!当时我扫描方式时!我曾采用过行逆程显示!结果表明有一部分图像显现出来!不过在边缘!,里面都是网文!和乱踢八糟的彩色点!只有在边缘是细腻的图像,只有一小块,而且每隔多少行一块!突然一个想法在脑子里闪现!是不是我重复数据扫描了!有一想我主程序里是512个扫描周期,分了两个字节!总共是1024!而我读一扇区只有512,所以肯定有一半的数据是重复的!,想到这里我想赶紧验证下!电话响了!安保近的,说工地有事让我去趟!我也没顾得实验!直接去工地,办完事回来吧程序改了,512改成了256,这样正是512字节,然后又实验!这次能显示图像的轮廓了,但是很模糊!我有WINHEX开查看!是字节未按高字节在前的顺序,排列,调整后,一点也不大差的显示在屏幕上了!IMAGE取模吧JPG转换成BMP的彩色图片宽度240,高度320,16位色,高位在前,水平扫描!生成BIN文件存入存储卡中OVER!当然在中间还要用串口查看数据是否正确!
}
程序:
- #include
- #define uchar unsigned char
- #define uint unsigned int
- #define DATE P0
- //bit flage;
- //SD卡的
- ***it p1_7=P1^7;
- ***it CS=P2^0; //片选信号(低电平有效)
- ***it DATEIN =P2^1;//主-从数据输入
- ***it SCLK=P2^2;//时钟信号
- ***it DATEOUT=P2^3;//从-主数据输出
- //液晶的
- ***it RS=P3^7;
- ***it RW=P3^6;
- ***it RES=P3^5;
- ***it CStft=P3^4;
- uint btime;
- uchar c;
- unsigned char bdata dat;
- ***it dat_0=dat^0;
- ***it dat_1=dat^1;
- ***it dat_2=dat^2;
- ***it dat_3=dat^3;
- ***it dat_4=dat^4;
- ***it dat_5=dat^5;
- ***it dat_6=dat^6;
- ***it dat_7=dat^7;
- bit is_init;//决定是否延时;
- uchar lpp;
- unsigned char fhz;//返回值
- uchar fhz_buff; //读返回值中间量
- unsigned char xdata tab[512];
- void delay(uint time)
- { while(time)
- time--;
- }
- //**********************************************
- /*读sd卡子程序,无返回值,有参函数,参数为要写入DATEIN数据线的字节*/
- void write(unsigned char wr_)// 写入一个字节SD卡
- {
- dat=wr_;
- DATEIN=dat_7;
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- DATEIN=dat_6;
- SCLK=0;
- if(!is_init)delay(2);
- if(is_init)delay(200);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- DATEIN=dat_5;
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- DATEIN=dat_4;
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- DATEIN=dat_3;
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- DATEIN=dat_2;
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- DATEIN=dat_1;
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- DATEIN=dat_0;
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=1;
- if(is_init) delay(200);
- if(!is_init)delay(2);
- }
- unsigned char read()// 读取一个字节SD卡
- {
- DATEOUT=1;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_7=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_6=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_5=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_4=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_3=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_2=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_1=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- SCLK=0;
- if(is_init)delay(200);
- if(!is_init)delay(2);
- dat_0=DATEOUT;
- return (dat);
- }
- void restsd()//复位SD卡
- { uchar i;
- uchar pcmd[6]={0x40,0x00,0x00,0x00,0x00,0x95};
- is_init=1;
- CS=1;
- for(i=0;i<15;i++)
- {
- //120时钟
- write(0xff);
- }
- CS=1;
- write(0xff);//据说是提高兼容性
- CS=0;//片选开
- write( pcmd[0]);
- write( pcmd[1]);
- write( pcmd[2]);
- write( pcmd[3]);
- write( pcmd[4]);
- write( pcmd[5]);
- fhz=read();
- for(;;)
- {
- fhz=read();
- if(fhz==0x01)break;
- }
- CS=1;
- write(0xff);
- }
- void initsd()//初始化
- {
- //
- uchar pcmd[6]={0x41,0x00,0x00,0x00,0x00,0xff};//
- //
- CS=1;
- write(0xff);//据说是提高兼容性
- CS=0;//片选开
- write( pcmd[0]);
- write( pcmd[1]);
- write( pcmd[2]);
- write( pcmd[3]);
- write( pcmd[4]);
- write( pcmd[5]);
- fhz=read();
- for(;;)
- {
- fhz=read();
- if(fhz==0x00)break;
- }
- CS=1;
- write(0xff);
- }
- void readsd(unsigned long addstart)//读SD卡物理扇区
- { unsigned long sdbuff1,sdbuff2,sdbuff3,sdbuff4;
- uint j,n;
- uchar zh1,zh2,zh3,zh4;
- sdbuff1=addstart;
- sdbuff2=addstart;
- sdbuff3=addstart;
- sdbuff4=addstart;
- zh1=(sdbuff1>>24)&0x000000ff;
- zh2=(sdbuff2>>16)&0x000000ff;
- zh3=(sdbuff3>>8)&0x000000ff;
- zh4=sdbuff4&0x000000ff;
- // uchar pcmd[6]={0x51,zh1,zh2,zh3,zh4,0xff};//原来这里是高地址字节在前地地址在后啊201012月14日逻辑扇区在253*512=0X0001fa00
- CS=1;
- write(0xff);//据说是提高兼容性
- CS=0;//片选开
- write( 0x51);
- write( zh1);
- write( zh2);
- write( zh3);
- write( zh4);
- write( 0xff);
- DATEOUT=1;
- for(;;)
- {
- fhz=read();
- if(fhz==0x00)break;
- }
- DATEOUT=1;
- for(;;)
- {
- fhz=read();
- if(fhz==0xfe)break;
- }
- DATEOUT=1;
- n=0;
- for(j=512;j;j--)
- {
- tab[n]=read();
- n++;
- }
- fhz=read();
- fhz=read();
- CS=1;
- write(0xff);
- }
- /*
- //********************************一下是液晶的
- void delay1ms(uint x) //延时程序
- { unsigned char a,b,c;
- uint z;
- for(z=x;z;z--)
- {
- for(c=8;c>0;c--)
- for(b=197;b>0;b--)
- for(a=2;a>0;a--);
- }
- }
- void write_date(uchar hight,uchar low) //定义搞八位字节和低八位字节写然后写入数据
- {
- CStft=0;
- RS=1;
- DATE=hight;
- RW=0;
- RW=1;
- DATE=low;
- RW=0;
- RW=1;
- CStft=1;
- }
- void write_cmd(uchar hight,uchar low )//定义搞八位字节和低八位字节写然后写入指令
- {
- CStft=0;
- RS=0;
- DATE=hight;
- RW=0;
- RW=1;
- DATE=low;
- RW=0;
- RW=1;
- CStft=1;
- }
- void wr_cmd_date(uint cmmd,uint datesh) //写入指令和相应的数据;
- {
- uchar g,d,g1,d1; /* 2010年12月21日与天津第四项目部终于做完了9325的TFT262万色彩色液晶,感觉比他妈的12864爽多了,
- 毕竟一个是黑白的一个是彩色的,呵呵,加油啊,下一步是组合SD卡和TFT液晶,让液晶显示彩色图片,加油吧!*/
- d=datesh;
- d=(d&0x00ff);
- g=(datesh>>8)&0x0ff;
- d1=cmmd;
- d1=(d1&0x00ff);
- g1=(cmmd>>8)&0x0ff;
- write_cmd(g1,d1 );
- write_date(g,d ) ;
- }
- void initTFT()//注意:这里是用的设置库,网络上多的很,感谢网络啊。
- {
- wr_cmd_date(0x0001,0x0100); //s1-s720
- wr_cmd_date(0x0002,0x0700);
- wr_cmd_date(0x0003,0x1030);
- wr_cmd_date(0x0004,0x0000);
- wr_cmd_date(0x0008,0x0207);
- wr_cmd_date(0x0009,0x0000);
- wr_cmd_date(0x000A,0x0000);
- wr_cmd_date(0x000C,0x0000);
- wr_cmd_date(0x000D,0x0000);
- wr_cmd_date(0x000F,0x0000);
- //power on sequence VGHVGL
- wr_cmd_date(0x0010,0x0000);
- wr_cmd_date(0x0011,0x0007);
- wr_cmd_date(0x0012,0x0000);
- wr_cmd_date(0x0013,0x0000);
- //vgh
- wr_cmd_date(0x0010,0x1290);
- wr_cmd_date(0x0011,0x0227);
- delay1ms(100);
- //vregiout
- wr_cmd_date(0x0012,0x001d); //0x001b
- delay1ms(100);
- //vom amplitude
- wr_cmd_date(0x0013,0x1500);
- delay1ms(100);
- //vom H
- wr_cmd_date(0x0029,0x0018);
- wr_cmd_date(0x002B,0x000D);
- //gamma
- wr_cmd_date(0x0030,0x0004);
- wr_cmd_date(0x0031,0x0307);
- wr_cmd_date(0x0032,0x0002);// 0006
- wr_cmd_date(0x0035,0x0206);
- wr_cmd_date(0x0036,0x0408);
- wr_cmd_date(0x0037,0x0507);
- wr_cmd_date(0x0038,0x0204);//0200
- wr_cmd_date(0x0039,0x0707);
- wr_cmd_date(0x003C,0x0405);// 0504
- wr_cmd_date(0x003D,0x0F02);
- //ram
- wr_cmd_date(0x0050,0x0000);
- wr_cmd_date(0x0051,0x00EF);
- wr_cmd_date(0x0052,0x0000);
- wr_cmd_date(0x0053,0x013F);
- wr_cmd_date(0x0060,0xA700);
- wr_cmd_date(0x0061,0x0001);
- wr_cmd_date(0x006A,0x0000);
- //
- wr_cmd_date(0x0080,0x0000);
- wr_cmd_date(0x0081,0x0000);
- wr_cmd_date(0x0082,0x0000);
- wr_cmd_date(0x0083,0x0000);
- wr_cmd_date(0x0084,0x0000);
- wr_cmd_date(0x0085,0x0000);
- //
- wr_cmd_date(0x0090,0x0010);
- wr_cmd_date(0x0093,0x0003);
- wr_cmd_date(0x0095,0x0110);
- wr_cmd_date(0x0097,0x0000);
- wr_cmd_date(0x0098,0x0000);
- wr_cmd_date(0x0007,0x0133);
- }
- //****************以上是液晶的
- void lcm_coordinate(unsigned int x1,unsigned int y1 )//扫描地
- {
- wr_cmd_date(0x0050,x1);
- wr_cmd_date(0x0051,x1);
- wr_cmd_date(0x0052,y1);
- wr_cmd_date(0x0053,y1);
- wr_cmd_date(0x0020,x1);
- wr_cmd_date(0x0021,y1);
- }
- void main()
- { unsigned long numb;
- unsigned int x,y; //扫描地址;
- uint a;
- uint f,buff_sd_tft;
- uint m1,m2;
- delay1ms(30);
- CS=1;
- RES=0;
- delay1ms(150);
- RES=1;
- delay1ms(50);
- //******
- initTFT();
- //InitUART(); //串口初始化
- is_init=1;
- restsd();
- initsd();
- is_init=0;//提高始终频率
- //p1_7=0;
- //********
- while(1)
- {
- /* x=0;y=0;
- for(;;)
- {
- lcm_coordinate(x,y );
- wr_cmd_date(0x0022,0x0000);
- x++;
- delay20us();
- if(x==240){x=0;y++;}
- if(y==80)break; //检测是否写到屏的边缘 240x320
- }
- for(;;)
- {
- lcm_coordinate(x,y );
- wr_cmd_date(0x0022,0xf800);
- x++;
- delay20us(); //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日
- if(x==240){x=0;y++;}
- if(y==160)break; //检测是否写到屏的边缘 240x320
- }
- for(;;)
- {
- lcm_coordinate(x,y );
- wr_cmd_date(0x0022,0x0000);
- x++;
- delay20us(); //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日
- if(x==240){x=0;y++;}
- if(y==240)break; //检测是否写到屏的边缘 240x320
- }
- for(;;)
- {
- lcm_coordinate(x,y );
- wr_cmd_date(0x0022,0x001f);
- x++;
- delay20us(); //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日
- if(x==240){x=0;y++;}
- if(y==320)break; //检测是否写到屏的边缘 240x320
- }
- }*/
- // while(1);
- //p1_7=1;
- // btime=65536;
- // SendOneByte(0x88);
- x=0;y=0;
- numb=4327936;
- do
- {
- readsd(numb);//读物理扇区
- //SendOneByte(0x88);
- f=0;
- for(a=256;a;a--)
- {
- m1=tab[f];
- // SendOneByte(m1);
- m1=(m1<<8)&0xff00;
- f++;
- m2=tab[f];
- // SendOneByte(m2);
- f++;
- buff_sd_tft=m1+m2;
- lcm_coordinate(x,y );
- wr_cmd_date(0x0022,buff_sd_tft);
- x++;
- delay1ms(1); //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日
- if(x==240){x=0;y++;}
- if(y==320)y=0; //检测是否写到屏的边缘 240x320
- }
- //SendOneByte(0xcc);
- numb=(numb+512);
- }
- while(0x0044620!=numb);
- // EA=0;
- // ES = 0;
- // TR1 = 0;
- while(1);
- }
|