tornadomeet 发表于 2011-5-6 09:23:01

niosII控制9325tft显示的奇怪现象

最近用niosII来驱动ili9325的控制器tft液晶,但是出现了一个奇怪的显示,图片是能很清晰的显示出来,但是感觉被左右拉伸了,从对角线开始,即图片看起来是斜的。后面我每显示一个点时,延时5ms来观察,发现数据显示确实是从左到右,从上到下显示的,并不是从对角线开始的。数据用的img2lcd这个软件,数据取模也是从左到右,从上到下的。这个太神奇了,像了很久也没有明白,求救!

ppptawong 发表于 2011-5-6 12:59:11

可否將資料傳上來..

jeffwei 发表于 2011-5-6 13:02:00

我作stm32f107的BMP显示的时候遇到过,检查自己的程序吧。

tornadomeet 发表于 2011-5-6 14:59:48

回复【1楼】ppptawong
-----------------------------------------------------------------------

过两天回学校后把图片传上来,现在没相机。

初步完成图片的显示(只是倾斜了),可以用按键实现上翻,下翻,放大,缩小图片,代码如下:
/*
* "Hello World" example.
*
* This example prints 'Hello from Nios II' to the STDOUT stream. It runs on
* the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example
* designs. It runs with or without the MicroC/OS-II RTOS and requires a STDOUT
* device in your system's hardware.
* The memory footprint of this hosted application is ~69 kbytes by default
* using the standard reference design.
*
* For a reduced footprint version of this template, and an explanation of how
* to reduce the memory footprint for a given application, see the
* "small_hello_world" template.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <alt_types.h>
#include "sys/alt_irq.h"
#include "system.h"                      //包含基本的硬件描述信息
#include "altera_avalon_pio_regs.h"      //包含基本的I/O口信息
#include "image.h"
#include "image1.h"
#include "image2.h"

#define LCD_CS      *(volatile unsigned char*)LCD_CS_BASE
#define LCD_RD      *(volatile unsigned char*)LCD_RD_BASE
#define LCD_WR      *(volatile unsigned char*)LCD_WR_BASE
#define LCD_RS      *(volatile unsigned char*)LCD_RS_BASE
#define LCD_RESET   *(volatile unsigned char*)LCD_RESET_BASE
#define LCD_DATAL   *(volatile unsigned char*)LCD_DATAL_BASE
#define KEY_UPPER   *(volatile unsigned char *) KEY_UPPER_BASE
#define KEY_NEXT    *(volatile unsigned char *) KEY_NEXT_BASE
#define KEY_BIG   *(volatile unsigned char *) KEY_BIG_BASE
#define KEY_SMALL   *(volatile unsigned char *) KEY_SMALL_BASE

#define X_START   0x0050 // 水平的开始地址组
#define X_END       0x0051 // 水平的结束地址组
#define Y_START   0x0052 // 水平的开始地址组
#define Y_END       0x0053 // 水平的结束地址组

#define X_COUNT   0X0020//水平地址计数器
#define Y_COUNT   0X0021//垂直地址计数器
#define WR_GRAM   0X0022//GRAM的写入和读取端口

int count=1,i=0,j=0,size=3;
//延时1ms子程序
void Delay_1ms(unsigned int count)
{
   
      int i,j;
      for(i=0;i<count;i++)
         for(j=0;j<2000;j++);
}


// 通过8位的数据口LCD_DATAL写入16位的数据,先写高8位,再写低8位
void Write_Data(unsigned char DataH,unsigned char DataL)
{
    LCD_CS=0;
    LCD_RS=1;         //RS=1时位写数据
    LCD_DATAL=DataH;
    LCD_WR=0;         //RW的上升沿写入数据
    LCD_WR=1;
    LCD_DATAL=DataL;   //先写高位,再写低位
    LCD_WR=0;
    LCD_WR=1;
    LCD_CS=1;
}


// 通过8位的数据口LCD_DATAL写入16位的命令,先写高8位,再写低8位
void Write_Cmd(unsigned char DataH,unsigned char DataL)
{
    LCD_CS=0;
    LCD_RS=0;         //RS=0时位写命令
    LCD_DATAL=DataH;
    LCD_WR=0;         //RW的上升沿写入数据
    LCD_WR=1;
    LCD_DATAL=DataL;   //先写高位,再写低位
    LCD_WR=0;
    LCD_WR=1;
    LCD_CS=1;
}

// 先发命令,紧接着发送数据,调用该函数时比较方便
void Write_Cmd_Data(unsigned int Cmd,unsigned int Data)
{
    unsigned char x,y,z;
    x=(unsigned char)Cmd;               //因为实际的命令高8位肯定位00,所以只需取其低8位
    y=(unsigned char)(Data>>8);         //取数据的高8位
    z=(unsigned char)Data;            //取数据的低8位
    Write_Cmd(0x00,x);
    Write_Data(y,z);
}


/*
//16位模式下的驱动
void Lcd_Init()
{
//   Delay_1ms(200);
    LCD_RD=1;
    LCD_RESET=1;
    Delay_1ms(2);
    LCD_RESET=0;
    Delay_1ms(2);
    LCD_RESET=1;
    Delay_1ms(2);
    //早期初始化序列
    LCD_CS=0;
    Write_Cmd_Data(0x00E5,0x78F0);
    Write_Cmd_Data(0x0001,0x0100);
    Write_Cmd_Data(0x0002,0x0700);
    Write_Cmd_Data(0x0003,0x1030);
    Write_Cmd_Data(0x0004,0x0000);
    Write_Cmd_Data(0x0008,0x0207);
    Write_Cmd_Data(0x0009,0x0000);
    Write_Cmd_Data(0x000A,0x0000);
    Write_Cmd_Data(0x000C,0x0000);
    Write_Cmd_Data(0x000D,0x0000);
    Write_Cmd_Data(0x000F,0x0000);
    //上电后初始化序列
    Write_Cmd_Data(0x0010,0x0000);
    Write_Cmd_Data(0x0011,0x0007);
    Write_Cmd_Data(0x0012,0x0000);
    Write_Cmd_Data(0x0013,0x0000);
    Write_Cmd_Data(0x0007,0x0001);
    Delay_1ms(2);
    Write_Cmd_Data(0x0010,0x1090); //这里修改了
    Write_Cmd_Data(0x0011,0x0227);
    Delay_1ms(2);
    Write_Cmd_Data(0x0012,0x001F);//这里修改了
    Delay_1ms(2);
    Write_Cmd_Data(0x0013,0x1500);
//Delay_1ms(100);
    Write_Cmd_Data(0x0029,0x0027); //这里修改了
    Write_Cmd_Data(0x002B,0x000D);
    Delay_1ms(2);   
    //gamma
    Write_Cmd_Data(0x0020,0x0000);
    Write_Cmd_Data(0x0021,0x0000);
    Write_Cmd_Data(0x0030,0x0000);//这里修改了
    Write_Cmd_Data(0x0031,0x0707);//这里修改了
    Write_Cmd_Data(0x0032,0x0307);//这里修改了
    Write_Cmd_Data(0x0035,0x0200);//这里修改了
    Write_Cmd_Data(0x0036,0x0008);//这里修改了
    Write_Cmd_Data(0x0037,0x0004); //这里修改了
    Write_Cmd_Data(0x0038,0x0000);//这里修改了
    Write_Cmd_Data(0x0039,0x0707);
    Write_Cmd_Data(0x003C,0x0002);//这里修改了
    Write_Cmd_Data(0x003D,0x1D04);//这里修改了
//ram
    Write_Cmd_Data(0x0050,0x0000);
    Write_Cmd_Data(0x0051,0x00EF);
    Write_Cmd_Data(0x0052,0x0000);
    Write_Cmd_Data(0x0053,0x013F);
    Write_Cmd_Data(0x0060,0xA700);
    Write_Cmd_Data(0x0061,0x0001);
    Write_Cmd_Data(0x006A,0x0000);
//
    Write_Cmd_Data(0x0080,0x0000);
    Write_Cmd_Data(0x0081,0x0000);
    Write_Cmd_Data(0x0082,0x0000);
    Write_Cmd_Data(0x0083,0x0000);
    Write_Cmd_Data(0x0084,0x0000);
    Write_Cmd_Data(0x0085,0x0000);
//
    Write_Cmd_Data(0x0090,0x0010);
    Write_Cmd_Data(0x0092,0x0600);
//   Write_Cmd_Data(0x0093,0x0003);
//   Write_Cmd_Data(0x0095,0x0110);
//   Write_Cmd_Data(0x0097,0x0000);
//   Write_Cmd_Data(0x0098,0x0000);
    Write_Cmd_Data(0x0007,0x0133);
    LCD_CS=1;
}
*/


//8位模式下的驱动
void Lcd_Init()
{
    Delay_1ms(500);
    //早期初始化序列
    LCD_RD=1;
    LCD_RESET=1;
    Delay_1ms(2);
    LCD_RESET=0;
    Delay_1ms(2);
    LCD_RESET=1;//此处的复位脚一定要设成为高电平,否则肯定不能显示。用单独的那个tft+sd卡模块时
//Delay_1ms(2);
//LCD_RD=0;
    LCD_CS=0;
//    Write_Cmd_Data(0x00E5,0x78F0);
    Write_Cmd_Data(0x0001,0x0100);
    Write_Cmd_Data(0x0002,0x0700);
    Write_Cmd_Data(0x0003,0x1030);
    Write_Cmd_Data(0x0004,0x0000);
    Write_Cmd_Data(0x0008,0x0207);
    Write_Cmd_Data(0x0009,0x0000);
    Write_Cmd_Data(0x000A,0x0000);
    Write_Cmd_Data(0x000C,0x0000);
    Write_Cmd_Data(0x000D,0x0000);
    Write_Cmd_Data(0x000F,0x0000);
    //上电后初始化序列
    Write_Cmd_Data(0x0010,0x0000);
    Write_Cmd_Data(0x0011,0x0007);
    Write_Cmd_Data(0x0012,0x0000);
    Write_Cmd_Data(0x0013,0x0000);
//Write_Cmd_Data(0x0007,0x0001); //该模式下没有这1句
    Delay_1ms(100);
    Write_Cmd_Data(0x0010,0x1290); //这里修改了
    Write_Cmd_Data(0x0011,0x0227);
    Delay_1ms(100);
    Write_Cmd_Data(0x0012,0x001d);//这里修改了
    Delay_1ms(100);
    Write_Cmd_Data(0x0013,0x1500);
    Delay_1ms(100);
    Write_Cmd_Data(0x0029,0x0018); //这里修改了
    Write_Cmd_Data(0x002B,0x000D);
//Delay_1ms(100);   
    //gamma
   
//    Write_Cmd_Data(0x0020,0x0000);//该模式下没有这2句
//    Write_Cmd_Data(0x0021,0x0000);

    Write_Cmd_Data(0x0030,0x0004);//这里修改了
    Write_Cmd_Data(0x0031,0x0307);//这里修改了
    Write_Cmd_Data(0x0032,0x0002);//这里修改了
    Write_Cmd_Data(0x0035,0x0206);//这里修改了
    Write_Cmd_Data(0x0036,0x0408);//这里修改了
    Write_Cmd_Data(0x0037,0x0507); //这里修改了
    Write_Cmd_Data(0x0038,0x0204);//这里修改了
    Write_Cmd_Data(0x0039,0x0707);
    Write_Cmd_Data(0x003C,0x0405);//这里修改了
    Write_Cmd_Data(0x003D,0x0F02);//这里修改了
//ram
    Write_Cmd_Data(0x0050,0x0000);
    Write_Cmd_Data(0x0051,0x00EF);
    Write_Cmd_Data(0x0052,0x0000);
    Write_Cmd_Data(0x0053,0x013F);
    Write_Cmd_Data(0x0060,0xA700);
    Write_Cmd_Data(0x0061,0x0001);
    Write_Cmd_Data(0x006A,0x0000);
//
    Write_Cmd_Data(0x0080,0x0000);
    Write_Cmd_Data(0x0081,0x0000);
    Write_Cmd_Data(0x0082,0x0000);
    Write_Cmd_Data(0x0083,0x0000);
    Write_Cmd_Data(0x0084,0x0000);
    Write_Cmd_Data(0x0085,0x0000);
//
    Write_Cmd_Data(0x0090,0x0010);
    Write_Cmd_Data(0x0092,0x0600);
    Write_Cmd_Data(0x0093,0x0003);
    Write_Cmd_Data(0x0095,0x0110);
    Write_Cmd_Data(0x0097,0x0000);
    Write_Cmd_Data(0x0098,0x0000);
    Write_Cmd_Data(0x0007,0x0133);
    LCD_CS=1;
}


//定义坐标
void LCD_Set_Pos(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1)
{
Write_Cmd_Data(X_START,x0);
Write_Cmd_Data(X_END,x1);
Write_Cmd_Data(Y_START,y0);
Write_Cmd_Data(Y_END,y1);
Write_Cmd_Data(X_COUNT,x0);
Write_Cmd_Data(Y_COUNT,y0);
Write_Cmd(0x00,0x22);//LCD_WriteCMD(GRAMWR);
}

void Clean_LCD(unsigned char ColourH,unsigned char ColourL)
{
    unsigned int i,j;
    LCD_CS=0;
    LCD_Set_Pos(0,240,0,320);
    for (i=0;i<320;i++)
    {
   
       for (j=0;j<240;j++)
         Write_Data(ColourH,ColourL);
    }
    LCD_CS=1;
}


void key_scan( )
{
    if(0==KEY_NEXT){
      Delay_1ms(1);
      if(0==KEY_NEXT){
            count++;
            if(6==count)count=1;
      }
    }
   else if(0==KEY_UPPER){
      Delay_1ms(1);
      if(0==KEY_UPPER){
            count--;
            if(0==count)count=5;
      }
    }
    else if(0==KEY_SMALL){
      Delay_1ms(1);
      if(0==KEY_SMALL){
            size--;
            if(1==size)size=2;
      }
    }
   else if(0==KEY_BIG){
      Delay_1ms(1);
      if(0==KEY_BIG){
            size++;
            if(5==size)size=4;
      }
    }
}

void main()
{
    Lcd_Init();
    Clean_LCD(0x0f,0xf0);
//    printf("My God!");
    while(1)
    {
      LCD_CS =0;//打开片选使能
      key_scan();
    //    LCD_Set_Pos(0,240,0,320);//320x240
      if(3==size){
            Write_Cmd_Data(0x0004,0x0000);
            LCD_Set_Pos(0,240,0,320);//320x240
      if(1==count){
            for(i=0;i<76800;i++)
             {
               Write_Data(image1,image1);//数组的的前面是颜色的高位,后面是低位,这里注意      
            }
      }
      else if(2==count){
            for(i=0;i<76800;i++)
             {
               Write_Data(image2,image2);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
      }
      else if(3==count){
            for(i=0;i<76800;i++)
             {
               Write_Data(image3,image3);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
      }else if(4==count){
            for(i=0;i<76800;i++)
             {
               Write_Data(image4,image4);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
      }else if(5==count){
            for(i=0;i<76800;i++)
             {
               Write_Data(image5,image5);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
         }
      }
   //缩小4倍   
      if(2==size){
             Clean_LCD(0x00,0x00);
             Write_Cmd_Data(0x0004,0x0001);
             LCD_Set_Pos(60,180,80,240);//320x240
      if(1==count){
            for(i=0;i<76800;i=i+1)
             {
               Write_Data(image1,image1);//数组的的前面是颜色的高位,后面是低位,这里注意      
            }
      }
      else if(2==count){
            for(i=0;i<76800;i=i+1)
             {
               Write_Data(image2,image2);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
      }
      else if(3==count){
            for(i=0;i<76800;i=i+1)
             {
               Write_Data(image3,image3);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
      }else if(4==count){
            for(i=0;i<76800;i=i+1)
             {
               Write_Data(image4,image4);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
      }else if(5==count){
            for(i=0;i<76800;i=i+1)
             {
               Write_Data(image5,image5);//数组的的前面是颜色的高位,后面是低位,这里注意            
            }
         }
      }
      
         //放大4倍   
      if(4==size){
      //       Clean_LCD(0x00,0x00);
             Write_Cmd_Data(0x0004,0x0000);
             LCD_Set_Pos(0,240,0,320);//320x240
          //   LCD_Set_Pos(60,180,80,240);//320x240
      if(1==count){
            /*
            for(i=0;i<76800;i=i+1)
             {
               Write_Data(image1,image1);//数组的的前面是颜色的高位,后面是低位,这里注意      
            }
            */
            for(j=0;j<320;j++)
                for(i=0;i<240;i++)
                {
                  if(i>=60&&i<180)
                  {
                  Write_Data(image1[(240*j+i-1)*2+1],image1[(240*j+i)*2]);
                  Write_Data(image1[(240*j+i-1)*2+1],image1[(240*j+i)*2]);
                  }
                }
      
/*      for(j=0;j<160;j++)
                for(i=0;i<120;i++)
                {
                  LCD_Set_Pos(2*i,2*i,2*j,2*j);
                  Write_Data(image1[]);
                }
                */
      }
      else if(2==count){
            for(j=0;j<320;j++)
                for(i=0;i<240;i++)
                {
                  if(i>=60&&i<180)
                  {
                  Write_Data(image2[(240*j+i-1)*2+1],image2[(240*j+i)*2]);
                  Write_Data(image2[(240*j+i-1)*2+1],image2[(240*j+i)*2]);
                  }
                }
      }
      else if(3==count){
             for(j=0;j<320;j++)
                for(i=0;i<240;i++)
                {
                  if(i>=60&&i<180)
                  {
                  Write_Data(image3[(240*j+i-1)*2+1],image3[(240*j+i)*2]);
                  Write_Data(image3[(240*j+i-1)*2+1],image3[(240*j+i)*2]);
                  }
                }
      }else if(4==count){
             for(j=0;j<320;j++)
                for(i=0;i<240;i++)
                {
                  if(i>=60&&i<180)
                  {
                  Write_Data(image4[(240*j+i-1)*2+1],image4[(240*j+i)*2]);
                  Write_Data(image4[(240*j+i-1)*2+1],image4[(240*j+i)*2]);
                  }
                }
      }else if(5==count){
             for(j=0;j<320;j++)
                for(i=0;i<240;i++)
                {
                  if(i>=60&&i<180)
                  {
                  Write_Data(image5[(240*j+i-1)*2+1],image5[(240*j+i)*2]);
                  Write_Data(image5[(240*j+i-1)*2+1],image5[(240*j+i)*2]);
                  }
                }
             }
      }
         
         LCD_CS=1;//关闭片选使能      
         
    }
   
}

tornadomeet 发表于 2011-5-6 15:01:33

回复【2楼】jeffwei
-----------------------------------------------------------------------

也就是说是程序的问题咯?如果硬件没有错,那就好。

sczh01 发表于 2011-5-6 15:19:43

tornadomeet 发表于 2011-5-8 17:04:12

问题已经得到解决,是定义屏幕范围时有问题,开始是定义的(0,240,0,320)后面在本论坛中发现有人定义的x坐标只差为奇数时会出现这样,偶数不会。而我的是偶数就出现了,后面改成奇数就可以了,即(0,239,0,320),后面就ok了。只是现在还想不通为什么。
页: [1]
查看完整版本: niosII控制9325tft显示的奇怪现象