STM32的TFTLCD屏问题

2019-07-20 13:57发布

修改程序后,LCD屏读不出,但是能够打印出  ID9341。

使用原子哥的例程做出的接口修改:
#define        LCD_LED PCout(1)                         //LCD背光                    PB1

#define        LCD_CS_SET          GPIOC->BSRR=1<<9            //片选端口                  PC9
#define        LCD_RS_SET        GPIOC->BSRR=1<<8            //数据/命令                 PC8          
#define        LCD_WR_SET        GPIOC->BSRR=1<<7            //写数据                PC7
#define        LCD_RD_SET        GPIOC->BSRR=1<<6            //读数据                PC6
                                                                    
#define        LCD_CS_CLR          GPIOC->BRR=1<<9             //片选端口                  PC9
#define        LCD_RS_CLR        GPIOC->BRR=1<<8             //数据/命令                PC8          
#define        LCD_WR_CLR        GPIOC->BRR=1<<7             //写数据                PC7
#define        LCD_RD_CLR        GPIOC->BRR=1<<6             //读数据                PC6  

//PD0~15,作为数据线
#define DATAOUT(x) GPIOD->ODR=x; //数据输出
#define DATAIN     GPIOD->IDR;   //数据输入

下面是寄存器修改:
u16 LCD_RD_DATA(void)
{   
   u16 t;
   GPIOD->CRL=0X88888888; //PB0-7  上拉输入
   GPIOD->CRH=0X88888888; //PB8-15 上拉输入
   GPIOD->ODR=0X0000;     //全部输出0

   LCD_RS_SET;
   LCD_CS_CLR;
   //读取数据(读寄存器时,并不需要读2次)
   LCD_RD_CLR;
   if(lcddev.id==0X8989)delay_us(2);//FOR 8989,延时2us   
   LCD_RD_SET;
   t=DATAIN;  
   LCD_CS_SET;

   GPIOD->CRL=0X33333333; //PB0-7  上拉输出
   GPIOD->CRH=0X33333333; //PB8-15 上拉输出
   GPIOD->ODR=0XFFFF;    //全部输出高
   return t;  
}

u16 LCD_ReadPoint(u16 x,u16 y)
{
   u16 r,g,b;
   if(x>=lcddev.width||y>=lcddev.height)return 0; //超过了范围,直接返回   
   LCD_SetCursor(x,y);
   if(lcddev.id==0X9341||lcddev.id==0X6804)LCD_WR_REG(0X2E); //9341/6804发送读GRAM指令
   else LCD_WR_REG(R34);       //其他IC发送读GRAM指令
   GPIOD->CRL=0X88888888; //PB0-7  上拉输入
   GPIOD->CRH=0X88888888; //PB8-15 上拉输入
   GPIOD->ODR=0XFFFF;     //全部输出高

   LCD_RS_SET;
   LCD_CS_CLR;   
   //读取数据(读GRAM时,第一次为假读)
   LCD_RD_CLR;
   delay_us(1);//延时1us   
   LCD_RD_SET;
   //dummy READ
   LCD_RD_CLR;   
   delay_us(1);//延时1us   
   LCD_RD_SET;
   r=DATAIN;  
   if(lcddev.id==0X9341)
   {  
      LCD_RD_CLR;   
      LCD_RD_SET;
      b=DATAIN;//读取蓝 {MOD}值   
      g=r&0XFF;//对于9341,第一次读取的是RG的值,R在前,G在后,各占8位
      g<<=8;
   }else if(lcddev.id==0X6804)
   {
      LCD_RD_CLR;   
      LCD_RD_SET;
      r=DATAIN;//6804第二次读取的才是真实值
   }  
   LCD_CS_SET;

   GPIOD->CRL=0X33333333; //PB0-7  上拉输出
   GPIOD->CRH=0X33333333; //PB8-15 上拉输出
   GPIOD->ODR=0XFFFF;    //全部输出高  
   if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0X8989||lcddev.id==0XB505)return r; //这几种IC直接返回颜 {MOD}值
   else if(lcddev.id==0X9341)return (((r>>11)<<11)|((g>>10)<<5)|(b>>11)); //ILI9341需要公式转换一下
   else return LCD_BGR2RGB(r); //其他IC
}

//初始化lcd
//该初始化函数可以初始化各种ALIENTEK出品的LCD液晶屏
//本函数占用较大flash,用户可以根据自己的实际情况,删掉未用到的LCD初始化代码.以节省空间.
void LCD_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE); //使能PORTB,C时钟和AFIO时钟
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//开启SWD,失能JTAG
       
        //PB1(lcd_BL)背光
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;           ///PB1复用推挽输出
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB         
       
        //PC6(lcd_RD),PC7(lcd_WR),PC8(lcd_RS),PC9(lcd_CS)
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6;           ///PORTC6~9复用推挽输出
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC       
        GPIO_SetBits(GPIOC,GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6);

        //lcd数据引脚
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;        //  PORTD推挽输出
        GPIO_Init(GPIOD, &GPIO_InitStructure); //GPIOD
        GPIO_SetBits(GPIOD,GPIO_Pin_All);

        delay_ms(50); // delay 50 ms
        LCD_WriteReg(0x0000,0x0001);
        delay_ms(50); // delay 50 ms
          lcddev.id = LCD_ReadReg(0x0000);   
        if(lcddev.id<0XFF||lcddev.id==0XFFFF||lcddev.id==0X9300)//读到ID不正确,新增lcddev.id==0X9300判断,因为9341在未被复位的情况下会被读成9300
        {       
                //尝试9341 ID的读取               
                LCD_WR_REG(0XD3);                                  
                LCD_RD_DATA();                                 //dummy read        
                LCD_RD_DATA();                       //读到0X00
                  lcddev.id=LCD_RD_DATA();           //读取93                                                                  
                lcddev.id<<=8;
                lcddev.id|=LCD_RD_DATA();          //读取41                                      
                if(lcddev.id!=0X9341)                //非9341,尝试是不是6804
                {       
                        LCD_WR_REG(0XBF);                                  
                        LCD_RD_DATA();                         //dummy read          
                         LCD_RD_DATA();               //读回0X01                          
                         LCD_RD_DATA();                         //读回0XD0                                  
                          lcddev.id=LCD_RD_DATA();//这里读回0X68
                        lcddev.id<<=8;
                          lcddev.id|=LCD_RD_DATA();//这里读回0X04          
                        if(lcddev.id!=0X6804)        //也不是6804,尝试看看是不是NT35310
                        {
                                LCD_WR_REG(0XD4);                                  
                                LCD_RD_DATA();                                 //dummy read  
                                LCD_RD_DATA();                           //读回0X01         
                                lcddev.id=LCD_RD_DATA();        //读回0X53       
                                lcddev.id<<=8;         
                                lcddev.id|=LCD_RD_DATA();        //这里读回0X10         
                                if(lcddev.id!=0X5310)                //也不是NT35310,尝试看看是不是NT35510
                                {
                                        LCD_WR_REG(0XDA00);       
                                        LCD_RD_DATA();                   //读回0X00         
                                        LCD_WR_REG(0XDB00);       
                                        lcddev.id=LCD_RD_DATA();//读回0X80
                                        lcddev.id<<=8;       
                                        LCD_WR_REG(0XDC00);       
                                        lcddev.id|=LCD_RD_DATA();//读回0X00               
                                        if(lcddev.id==0x8000)lcddev.id=0x5510;//NT35510读回的ID是8000H,为方便区分,我们强制设置为5510
                                        if(lcddev.id!=0X5510)                        //也不是NT5510,尝试看看是不是SSD1963
                                        {
                                                LCD_WR_REG(0XA1);
                                                lcddev.id=LCD_RD_DATA();
                                                lcddev.id=LCD_RD_DATA();        //读回0X57
                                                lcddev.id<<=8;         
                                                lcddev.id|=LCD_RD_DATA();        //读回0X61       
                                                if(lcddev.id==0X5761)lcddev.id=0X1963;//SSD1963读回的ID是5761H,为方便区分,我们强制设置为1963
                                        }
                                }
                        }
                }         
        }
        printf(" LCD ID:%x ",lcddev.id); //打印LCD ID  
        if(lcddev.id==0X9341)        //9341初始化
        {         
                LCD_WR_REG(0xCF);  
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0xC1);
                LCD_WR_DATAX(0X30);
                LCD_WR_REG(0xED);  
                LCD_WR_DATAX(0x64);
                LCD_WR_DATAX(0x03);
                LCD_WR_DATAX(0X12);
                LCD_WR_DATAX(0X81);
                LCD_WR_REG(0xE8);  
                LCD_WR_DATAX(0x85);
                LCD_WR_DATAX(0x10);
                LCD_WR_DATAX(0x7A);
                LCD_WR_REG(0xCB);  
                LCD_WR_DATAX(0x39);
                LCD_WR_DATAX(0x2C);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x34);
                LCD_WR_DATAX(0x02);
                LCD_WR_REG(0xF7);  
                LCD_WR_DATAX(0x20);
                LCD_WR_REG(0xEA);  
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_REG(0xC0);    //Power control
                LCD_WR_DATAX(0x1B);   //VRH[5:0]
                LCD_WR_REG(0xC1);    //Power control
                LCD_WR_DATAX(0x01);   //SAP[2:0];BT[3:0]
                LCD_WR_REG(0xC5);    //VCM control
                LCD_WR_DATAX(0x30);          //3F
                LCD_WR_DATAX(0x30);          //3C
                LCD_WR_REG(0xC7);    //VCM control2
                LCD_WR_DATAX(0XB7);
                LCD_WR_REG(0x36);    // Memory Access Control
                LCD_WR_DATAX(0x48);
                LCD_WR_REG(0x3A);   
                LCD_WR_DATAX(0x55);
                LCD_WR_REG(0xB1);   
                LCD_WR_DATAX(0x00);   
                LCD_WR_DATAX(0x1A);
                LCD_WR_REG(0xB6);    // Display Function Control
                LCD_WR_DATAX(0x0A);
                LCD_WR_DATAX(0xA2);
                LCD_WR_REG(0xF2);    // 3Gamma Function Disable
                LCD_WR_DATAX(0x00);
                LCD_WR_REG(0x26);    //Gamma curve selected
                LCD_WR_DATAX(0x01);
                LCD_WR_REG(0xE0);    //Set Gamma
                LCD_WR_DATAX(0x0F);
                LCD_WR_DATAX(0x2A);
                LCD_WR_DATAX(0x28);
                LCD_WR_DATAX(0x08);
                LCD_WR_DATAX(0x0E);
                LCD_WR_DATAX(0x08);
                LCD_WR_DATAX(0x54);
                LCD_WR_DATAX(0XA9);
                LCD_WR_DATAX(0x43);
                LCD_WR_DATAX(0x0A);
                LCD_WR_DATAX(0x0F);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);                  
                LCD_WR_REG(0XE1);    //Set Gamma
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x15);
                LCD_WR_DATAX(0x17);
                LCD_WR_DATAX(0x07);
                LCD_WR_DATAX(0x11);
                LCD_WR_DATAX(0x06);
                LCD_WR_DATAX(0x2B);
                LCD_WR_DATAX(0x56);
                LCD_WR_DATAX(0x3C);
                LCD_WR_DATAX(0x05);
                LCD_WR_DATAX(0x10);
                LCD_WR_DATAX(0x0F);
                LCD_WR_DATAX(0x3F);
                LCD_WR_DATAX(0x3F);
                LCD_WR_DATAX(0x0F);
                LCD_WR_REG(0x2B);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x01);
                LCD_WR_DATAX(0x3f);
                LCD_WR_REG(0x2A);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0xef);         
                LCD_WR_REG(0x11); //Exit Sleep
                delay_ms(120);
                LCD_WR_REG(0x29); //display on       
        }
               
        LCD_Display_Dir(0);                         //默认为竖屏
        LCD_LED=1;                                        //点亮背光
        LCD_Clear(WHITE);
}

请问各问大神是什么地方出错了。


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
正点原子
1楼-- · 2019-07-20 17:24
这种修改IO的问题,请自行验证。
验证方法:
1,用仿真器单步跟踪。
2,每设置一个你修改过的IO,仿真器暂停(设断点),用万用表测IO电平,是否和预期 一致。
3,依照方法2检查所有改过的IO。
这样,你就知道哪里出问题了
布达拉
2楼-- · 2019-07-20 18:26
 精彩回答 2  元偷偷看……

一周热门 更多>