找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5537|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机TFT9325液晶显示SD卡中的图片源程序

[复制链接]
跳转到指定楼层
楼主
ID:83710 发表于 2015-6-23 16:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
经过近两个星期的奋战!今天我敢说我成功了,因为我在液晶屏上成功的显示了彩色图片!真是不容易啊。回顾这些日子,我没睡一个安稳觉,实验达一百多次,与现在兴奋相比,都是浮云了!再一次次失败中我也在总结经验,一直在问位什么?下面:
我开始做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!当然在中间还要用串口查看数据是否正确!

}
程序:


  1. #include <reg52.h>

  2. #define uchar unsigned char

  3. #define uint unsigned int

  4. #define DATE P0

  5. //bit flage;

  6. //SD卡的

  7. sbit p1_7=P1^7;

  8. sbit CS=P2^0; //片选信号(低电平有效)

  9. sbit DATEIN =P2^1;//主-从数据输入

  10. sbit SCLK=P2^2;//时钟信号

  11. sbit DATEOUT=P2^3;//从-主数据输出



  12. //液晶的

  13. sbit RS=P3^7;

  14.    sbit RW=P3^6;

  15.    sbit RES=P3^5;

  16.    sbit CStft=P3^4;





  17. uint btime;

  18. uchar c;



  19. unsigned char bdata dat;

  20. sbit dat_0=dat^0;

  21. sbit dat_1=dat^1;

  22. sbit dat_2=dat^2;

  23. sbit dat_3=dat^3;

  24. sbit dat_4=dat^4;

  25. sbit dat_5=dat^5;

  26. sbit dat_6=dat^6;

  27. sbit dat_7=dat^7;



  28. bit is_init;//决定是否延时;

  29.   uchar lpp;

  30. unsigned char fhz;//返回值

  31. uchar fhz_buff; //读返回值中间量

  32. unsigned char xdata tab[512];





  33. void delay(uint time)

  34. {  while(time)

  35.   time--;

  36. }



  37. //**********************************************

  38. /*读sd卡子程序,无返回值,有参函数,参数为要写入DATEIN数据线的字节*/

  39. void write(unsigned char wr_)// 写入一个字节SD卡

  40. {

  41.             dat=wr_;

  42.           DATEIN=dat_7;

  43.    

  44.           SCLK=0;

  45.        if(is_init)delay(200);

  46.         if(!is_init)delay(2);

  47.           SCLK=1;

  48.           if(is_init) delay(200);

  49.             if(!is_init)delay(2);

  50.    

  51.           DATEIN=dat_6;

  52.    

  53.           SCLK=0;

  54.           if(!is_init)delay(2);

  55.          if(is_init)delay(200);

  56.           SCLK=1;

  57.           if(is_init) delay(200);

  58.           if(!is_init)delay(2);



  59.           DATEIN=dat_5;

  60.    

  61.           SCLK=0;

  62.          if(is_init)delay(200);

  63.           if(!is_init)delay(2);

  64.           SCLK=1;

  65.           if(is_init) delay(200);

  66.          if(!is_init)delay(2);



  67.           DATEIN=dat_4;

  68.    

  69.           SCLK=0;

  70.          if(is_init)delay(200);

  71.            if(!is_init)delay(2);

  72.           SCLK=1;

  73.           if(is_init) delay(200);

  74.           if(!is_init)delay(2);



  75.          DATEIN=dat_3;

  76.    

  77.           SCLK=0;

  78.          if(is_init)delay(200);

  79.            if(!is_init)delay(2);

  80.           SCLK=1;

  81.           if(is_init) delay(200);

  82.          if(!is_init)delay(2);



  83.          DATEIN=dat_2;

  84.    

  85.           SCLK=0;

  86.          if(is_init)delay(200);

  87.            if(!is_init)delay(2);

  88.           SCLK=1;

  89.           if(is_init) delay(200);

  90.            if(!is_init)delay(2);



  91.          DATEIN=dat_1;

  92.    

  93.           SCLK=0;

  94.          if(is_init)delay(200);

  95.           if(!is_init)delay(2);

  96.           SCLK=1;

  97.           if(is_init) delay(200);

  98.           if(!is_init)delay(2);



  99.          DATEIN=dat_0;

  100.    

  101.           SCLK=0;

  102.          if(is_init)delay(200);

  103.            if(!is_init)delay(2);

  104.           SCLK=1;

  105.           if(is_init) delay(200);

  106.           if(!is_init)delay(2);

  107. }

  108. unsigned char read()// 读取一个字节SD卡

  109. {

  110.           DATEOUT=1;

  111.          SCLK=1;

  112.       if(is_init)delay(200);

  113.         if(!is_init)delay(2);

  114.       SCLK=0;

  115.        if(is_init)delay(200);

  116.        if(!is_init)delay(2);

  117.        dat_7=DATEOUT;



  118.         SCLK=1;

  119.       if(is_init)delay(200);

  120.       if(!is_init)delay(2);

  121.       SCLK=0;

  122.        if(is_init)delay(200);

  123.         if(!is_init)delay(2);

  124.        dat_6=DATEOUT;



  125.        SCLK=1;

  126.       if(is_init)delay(200);

  127.         if(!is_init)delay(2);

  128.       SCLK=0;

  129.        if(is_init)delay(200);

  130.         if(!is_init)delay(2);

  131.        dat_5=DATEOUT;



  132.        SCLK=1;

  133.       if(is_init)delay(200);

  134.          if(!is_init)delay(2);

  135.       SCLK=0;

  136.        if(is_init)delay(200);

  137.        if(!is_init)delay(2);

  138.        dat_4=DATEOUT;



  139.       SCLK=1;

  140.       if(is_init)delay(200);

  141.          if(!is_init)delay(2);

  142.       SCLK=0;

  143.        if(is_init)delay(200);

  144.             if(!is_init)delay(2);

  145.        dat_3=DATEOUT;



  146.      SCLK=1;

  147.       if(is_init)delay(200);

  148.             if(!is_init)delay(2);

  149.       SCLK=0;

  150.        if(is_init)delay(200);

  151.             if(!is_init)delay(2);

  152.        dat_2=DATEOUT;



  153.       SCLK=1;

  154.       if(is_init)delay(200);

  155.                if(!is_init)delay(2);

  156.       SCLK=0;

  157.        if(is_init)delay(200);

  158.               if(!is_init)delay(2);

  159.        dat_1=DATEOUT;





  160.       SCLK=1;

  161.       if(is_init)delay(200);

  162.                   if(!is_init)delay(2);

  163.       SCLK=0;

  164.        if(is_init)delay(200);

  165.                    if(!is_init)delay(2);

  166.        dat_0=DATEOUT;





  167.    return (dat);



  168. }



  169. void restsd()//复位SD卡

  170. {  uchar i;

  171.   uchar pcmd[6]={0x40,0x00,0x00,0x00,0x00,0x95};

  172.   is_init=1;



  173.   CS=1;

  174.   for(i=0;i<15;i++)

  175.   {

  176.                 //120时钟

  177.     write(0xff);

  178.   }





  179.   

  180.   

  181.        CS=1;

  182.     write(0xff);//据说是提高兼容性

  183.     CS=0;//片选开



  184.     write( pcmd[0]);

  185.     write( pcmd[1]);

  186.     write( pcmd[2]);

  187.     write( pcmd[3]);

  188.     write( pcmd[4]);

  189.     write( pcmd[5]);



  190.     fhz=read();

  191.   for(;;)

  192.   {

  193.     fhz=read();

  194.     if(fhz==0x01)break;





  195.   }



  196.   

  197.   CS=1;

  198.   write(0xff);



  199. }









  200. void initsd()//初始化

  201. {

  202. //

  203.    uchar pcmd[6]={0x41,0x00,0x00,0x00,0x00,0xff};//

  204. //



  205.       CS=1;

  206.     write(0xff);//据说是提高兼容性

  207.     CS=0;//片选开



  208.     write( pcmd[0]);

  209.     write( pcmd[1]);

  210.     write( pcmd[2]);

  211.     write( pcmd[3]);

  212.     write( pcmd[4]);

  213.     write( pcmd[5]);

  214.    

  215.    

  216.     fhz=read();

  217.   for(;;)

  218.   {

  219.     fhz=read();

  220.     if(fhz==0x00)break;





  221.   }



  222.   

  223.   CS=1;

  224.   write(0xff);

















  225. }

  226. void readsd(unsigned long addstart)//读SD卡物理扇区

  227.       

  228. {  unsigned long sdbuff1,sdbuff2,sdbuff3,sdbuff4;   

  229.    uint j,n;

  230. uchar zh1,zh2,zh3,zh4;

  231.    sdbuff1=addstart;

  232.    sdbuff2=addstart;

  233.    sdbuff3=addstart;

  234.    sdbuff4=addstart;



  235.       zh1=(sdbuff1>>24)&0x000000ff;

  236.        zh2=(sdbuff2>>16)&0x000000ff;

  237.          zh3=(sdbuff3>>8)&0x000000ff;

  238.          zh4=sdbuff4&0x000000ff;

  239.    // uchar pcmd[6]={0x51,zh1,zh2,zh3,zh4,0xff};//原来这里是高地址字节在前地地址在后啊201012月14日逻辑扇区在253*512=0X0001fa00







  240.    CS=1;

  241.     write(0xff);//据说是提高兼容性

  242.     CS=0;//片选开



  243.     write( 0x51);

  244.     write( zh1);

  245.     write( zh2);

  246.     write( zh3);

  247.     write( zh4);

  248.     write( 0xff);

  249.     DATEOUT=1;

  250.    

  251.   for(;;)

  252.   {

  253.     fhz=read();

  254.     if(fhz==0x00)break;





  255.   }

  256.   DATEOUT=1;



  257.   for(;;)

  258.   {

  259.     fhz=read();

  260.     if(fhz==0xfe)break;





  261.   }



  262.   DATEOUT=1;

  263.   n=0;

  264. for(j=512;j;j--)

  265. {  

  266.    tab[n]=read();

  267.     n++;



  268. }

  269. fhz=read();

  270. fhz=read();

  271. CS=1;

  272. write(0xff);

















  273. }

  274. /*

  275. //********************************一下是液晶的

  276. void delay1ms(uint x) //延时程序

  277. {  unsigned char a,b,c;

  278.          uint z;

  279.          for(z=x;z;z--)

  280.          {

  281.          for(c=8;c>0;c--)

  282.              for(b=197;b>0;b--)

  283.             for(a=2;a>0;a--);

  284.             }

  285.   }



  286. void write_date(uchar hight,uchar low) //定义搞八位字节和低八位字节写然后写入数据

  287. {

  288.    CStft=0;

  289.    RS=1;

  290.    DATE=hight;

  291.    RW=0;

  292.    RW=1;

  293.    DATE=low;

  294.    RW=0;

  295.      RW=1;

  296.    CStft=1;



  297. }

  298. void write_cmd(uchar hight,uchar low )//定义搞八位字节和低八位字节写然后写入指令

  299. {



  300.      CStft=0;

  301.    RS=0;

  302.    DATE=hight;

  303.    RW=0;

  304.    RW=1;

  305.    DATE=low;

  306.    RW=0;

  307.      RW=1;

  308.    CStft=1;



  309. }

  310. void wr_cmd_date(uint cmmd,uint datesh) //写入指令和相应的数据;

  311. {

  312.    uchar g,d,g1,d1;              /*  2010年12月21日与天津第四项目部终于做完了9325的TFT262万色彩色液晶,感觉比他妈的12864爽多了,

  313.                                               毕竟一个是黑白的一个是彩色的,呵呵,加油啊,下一步是组合SD卡和TFT液晶,让液晶显示彩色图片,加油吧!*/

  314.                         



  315.        d=datesh;

  316.        d=(d&0x00ff);

  317.        g=(datesh>>8)&0x0ff;

  318.       

  319.       

  320.        d1=cmmd;

  321.        d1=(d1&0x00ff);

  322.        g1=(cmmd>>8)&0x0ff;

  323.       

  324.     write_cmd(g1,d1 );

  325.      write_date(g,d ) ;





  326. }

  327. void initTFT()//注意:这里是用的设置库,网络上多的很,感谢网络啊。

  328. {   

  329.   wr_cmd_date(0x0001,0x0100); //s1-s720

  330.   wr_cmd_date(0x0002,0x0700);

  331.   wr_cmd_date(0x0003,0x1030);

  332. wr_cmd_date(0x0004,0x0000);

  333.   wr_cmd_date(0x0008,0x0207);

  334.   wr_cmd_date(0x0009,0x0000);

  335.   wr_cmd_date(0x000A,0x0000);

  336.   wr_cmd_date(0x000C,0x0000);

  337.   wr_cmd_date(0x000D,0x0000);

  338. wr_cmd_date(0x000F,0x0000);

  339. //power on sequence VGHVGL

  340.   wr_cmd_date(0x0010,0x0000);  

  341.   wr_cmd_date(0x0011,0x0007);

  342.   wr_cmd_date(0x0012,0x0000);

  343.   wr_cmd_date(0x0013,0x0000);

  344. //vgh

  345.   wr_cmd_date(0x0010,0x1290);  

  346.   wr_cmd_date(0x0011,0x0227);

  347. delay1ms(100);

  348. //vregiout

  349.   wr_cmd_date(0x0012,0x001d); //0x001b

  350. delay1ms(100);

  351. //vom amplitude

  352.   wr_cmd_date(0x0013,0x1500);

  353. delay1ms(100);

  354. //vom H

  355.   wr_cmd_date(0x0029,0x0018);

  356.   wr_cmd_date(0x002B,0x000D);



  357. //gamma

  358.   wr_cmd_date(0x0030,0x0004);

  359.   wr_cmd_date(0x0031,0x0307);

  360.   wr_cmd_date(0x0032,0x0002);// 0006

  361.   wr_cmd_date(0x0035,0x0206);

  362.   wr_cmd_date(0x0036,0x0408);

  363.   wr_cmd_date(0x0037,0x0507);

  364.   wr_cmd_date(0x0038,0x0204);//0200

  365.   wr_cmd_date(0x0039,0x0707);

  366.   wr_cmd_date(0x003C,0x0405);// 0504

  367.   wr_cmd_date(0x003D,0x0F02);

  368. //ram

  369.   wr_cmd_date(0x0050,0x0000);

  370.   wr_cmd_date(0x0051,0x00EF);

  371.   wr_cmd_date(0x0052,0x0000);

  372.   wr_cmd_date(0x0053,0x013F);

  373.   wr_cmd_date(0x0060,0xA700);

  374.   wr_cmd_date(0x0061,0x0001);

  375.   wr_cmd_date(0x006A,0x0000);

  376. //

  377.   wr_cmd_date(0x0080,0x0000);

  378.   wr_cmd_date(0x0081,0x0000);

  379.   wr_cmd_date(0x0082,0x0000);

  380.   wr_cmd_date(0x0083,0x0000);

  381.   wr_cmd_date(0x0084,0x0000);

  382.   wr_cmd_date(0x0085,0x0000);

  383. //

  384.   wr_cmd_date(0x0090,0x0010);

  385.   wr_cmd_date(0x0093,0x0003);

  386.   wr_cmd_date(0x0095,0x0110);

  387.   wr_cmd_date(0x0097,0x0000);

  388.   wr_cmd_date(0x0098,0x0000);

  389.   wr_cmd_date(0x0007,0x0133);





  390. }

  391. //****************以上是液晶的

  392. void lcm_coordinate(unsigned int x1,unsigned int y1 )//扫描地

  393. {

  394.   wr_cmd_date(0x0050,x1);

  395.   wr_cmd_date(0x0051,x1);

  396.   wr_cmd_date(0x0052,y1);

  397.   wr_cmd_date(0x0053,y1);

  398.   wr_cmd_date(0x0020,x1);

  399.   wr_cmd_date(0x0021,y1);

  400. }

  401. void main()



  402. { unsigned long numb;

  403. unsigned int x,y; //扫描地址;

  404.     uint a;

  405.    uint f,buff_sd_tft;

  406.   uint  m1,m2;

  407. delay1ms(30);

  408.    CS=1;

  409.    RES=0;

  410.    delay1ms(150);

  411.    RES=1;

  412.    delay1ms(50);



  413. //******

  414.    initTFT();

  415. //InitUART(); //串口初始化

  416. is_init=1;

  417. restsd();

  418. initsd();

  419. is_init=0;//提高始终频率

  420. //p1_7=0;

  421. //********

  422. while(1)

  423. {

  424.   /* x=0;y=0;



  425.    for(;;)

  426.            {

  427.       lcm_coordinate(x,y );

  428.   wr_cmd_date(0x0022,0x0000);

  429. x++;

  430. delay20us();



  431.      if(x==240){x=0;y++;}

  432.      if(y==80)break;                        //检测是否写到屏的边缘 240x320

  433.    

  434.        }



  435.    for(;;)

  436.            {

  437.       lcm_coordinate(x,y );

  438.   wr_cmd_date(0x0022,0xf800);

  439. x++;

  440. delay20us();  //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日

  441.      if(x==240){x=0;y++;}

  442.      if(y==160)break;                        //检测是否写到屏的边缘 240x320

  443.    

  444.        }



  445.   for(;;)

  446.            {

  447.       lcm_coordinate(x,y );

  448.   wr_cmd_date(0x0022,0x0000);

  449. x++;

  450. delay20us();  //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日

  451.      if(x==240){x=0;y++;}

  452.      if(y==240)break;                        //检测是否写到屏的边缘 240x320

  453.    

  454.        }

  455.   for(;;)

  456.            {

  457.       lcm_coordinate(x,y );

  458.   wr_cmd_date(0x0022,0x001f);

  459. x++;

  460. delay20us();  //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日

  461.      if(x==240){x=0;y++;}

  462.      if(y==320)break;                        //检测是否写到屏的边缘 240x320

  463.    

  464.        }

  465. }*/



  466. // while(1);

  467. //p1_7=1;

  468.   // btime=65536;



















  469. // SendOneByte(0x88);

  470. x=0;y=0;

  471.    numb=4327936;

  472. do

  473.   {





  474. readsd(numb);//读物理扇区

  475.       //SendOneByte(0x88);

  476.        f=0;

  477.   for(a=256;a;a--)

  478.       {

  479.       

  480.       m1=tab[f];

  481.      // SendOneByte(m1);

  482.       m1=(m1<<8)&0xff00;

  483.       f++;

  484.       m2=tab[f];

  485.      // SendOneByte(m2);

  486.       f++;

  487.       buff_sd_tft=m1+m2;



  488.       

  489.       lcm_coordinate(x,y );

  490.   wr_cmd_date(0x0022,buff_sd_tft);

  491.            x++;

  492.          delay1ms(1);                                //必须加延时,实时胜于雄辩,如果不加延时的话,极易出现花屏,及扫描过高引起的数据无法写入,他妈的耽误了我一下午时间啊!2010年12月22日

  493.      if(x==240){x=0;y++;}

  494.      if(y==320)y=0;                       //检测是否写到屏的边缘 240x320

  495.        }

  496.       //SendOneByte(0xcc);

  497.       numb=(numb+512);

  498.   }

  499.    while(0x0044620!=numb);

  500. // EA=0;



  501.   //  ES = 0;

  502.    // TR1 = 0;



  503. while(1);







  504. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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