硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4253|回复: 4
收起左侧

[emWin] TFT ILI9486  8位的,能正常显示,但无法读出ID和颜色值,移植EMWIN有问题

[复制链接]

17

主题

132

回帖

183

积分

初级会员

积分
183
发表于 2015-4-29 13:00:08 | 显示全部楼层 |阅读模式
手上有块TFT,ILI9486 8位的,能正常显示,但无法读出ID和颜色值,移植EMwin出现问题,怀疑LCD_RD_DATA和LCD_ReadPoint函数有问题,请大家帮忙看看程序哪有问题?
#define Bank1_LCD_D    ((uint32_t)0x6C000040)    //disp Data ADDR
#define Bank1_LCD_C    ((uint32_t)0x6C000000)     //disp Reg ADDR
//写寄存器函数
//regval:寄存器值
void LCD_WR_REG(uint8_t index)
{
    *(__IO uint8_t *) (Bank1_LCD_C)= index;
}
//写LCD数据
//data:要写入的值
void LCD_WR_DATA(uint8_t val)
{
    *(__IO uint8_t *) (Bank1_LCD_D)= val;
}

//读LCD数据
//返回值:读到的值
uint16_t LCD_RD_DATA(void)
{
    uint16_t  a;
   
    uint16_t low = 0;
    uint16_t high = 0;
   
   
    LCD_WR_REG(0x2e);
    a=*(__IO uint8_t *) (Bank1_LCD_D);
    a=*(__IO uint8_t *) (Bank1_LCD_D);
    high=*(__IO uint8_t *) (Bank1_LCD_D);
    low=*(__IO uint8_t *) (Bank1_LCD_D);
    a= (high<<8)|(low&0xFF);
    return a;
}                       
//写寄存器
//LCD_Reg:寄存器地址
//LCD_RegValue:要写入的数据
//void LCD_WriteReg(uint8_t index, vu16 LCD_RegValue)
//{   
//////    LCD->LCD_REG = LCD_Reg>>8;        //写入要写的寄存器序号
////    LCD->LCD_REG = LCD_Reg;
////    LCD->LCD_RAM = LCD_RegValue>>8;//写入数据
////    LCD->LCD_RAM = LCD_RegValue;            
//}      
//读寄存器
//LCD_Reg:寄存器地址
//返回值:读到的数据
u16 LCD_ReadReg(vu16 LCD_Reg)
{                                          
    vu16 info;
    LCD_WR_REG(LCD_Reg);        //写入要读的寄存器序号
    delay_us(5);
    info=LCD_RD_DATA();
    info<<=8;
    info|=LCD_RD_DATA();
    return info;        //返回读到的值
}   
//开始写GRAM
void LCD_WriteRAM_Prepare(void)
{
     *(__IO uint8_t *) (Bank1_LCD_C)=0x2C;      
}     
//LCD写GRAM
//RGB_Code:颜色值
void LCD_WriteRAM(u16 RGB_Code)
{                                
    *(__IO uint8_t *) (Bank1_LCD_D) = RGB_Code>>8;//写十六位GRAM
    *(__IO uint8_t *) (Bank1_LCD_D) = RGB_Code&0xFF;   
}

//当mdk -O1时间优化时需要设置
//延时i
void opt_delay(u8 i)
{
    while(i--);
}
//读取个某点的颜色值     
//x,y:坐标
//返回值:此点的颜色
u16 LCD_ReadPoint(u16 x,u16 y)
{
     vu16 r=0,g=0,b=0;
    if(x>=272||y>=480)return 0;    //超过了范围,直接返回           
    LCD_SetCursor(x,y);        
    LCD_WR_REG(0X2E);//9486 发送读GRAM指令
    LCD_RD_DATA();                                    //dummy Read      
    opt_delay(2);                                         
     return (LCD_RD_DATA());                         //实际坐标颜色,要分2次读出

}            
//LCD开启显示
void LCD_DisplayOn(void)
{                       
    LCD_WR_REG(0X29);    //开启显示
}     
//LCD关闭显示
void LCD_DisplayOff(void)
{      
    LCD_WR_REG(0X28);    //关闭显示
}   
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{         
    LCD_WR_REG(0x2A);   
    LCD_WR_DATA((Xpos+24)>>8);
    LCD_WR_DATA(0xFF&(Xpos+24));        
//    LCD_WR_DATA((272-1)>>8);
//    LCD_WR_DATA((272-1));
   
    LCD_WR_REG(0x2B);   
    LCD_WR_DATA(Ypos>>8);
    LCD_WR_DATA(0x00FF&Ypos);        
//    LCD_WR_DATA((480-1)>>8);
//    LCD_WR_DATA((480-1));
}         
   
//画点
//x,y:坐标
//POINT_COLOR:此点的颜色
void LCD_DrawPoint(u16 x,u16 y)
{
    LCD_SetCursor(x,y);        //设置光标位置
    LCD_WriteRAM_Prepare();    //开始写入GRAM
    LCD_WriteRAM(POINT_COLOR);
}


//设置窗口,并自动设置画点坐标到窗口左上角(sx,sy).
//sx,sy:窗口起始坐标(左上角)
//width,height:窗口宽度和高度,必须大于0!!
//窗体大小:width*height.
//68042,横屏时不支持窗口设置!!
void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)
{   
    width=sx+width-1;
    height=sy+height-1;

    LCD_WR_REG(0x2A);
    LCD_WR_DATA(sx>>8);
    LCD_WR_DATA(sx&0XFF);     
    LCD_WR_DATA(width>>8);
    LCD_WR_DATA(width&0XFF);  
    LCD_WR_REG(0x2B);
    LCD_WR_DATA(sy>>8);
    LCD_WR_DATA(sy&0XFF);
    LCD_WR_DATA(height>>8);
    LCD_WR_DATA(height&0XFF);
}
//初始化lcd
//该初始化函数可以初始化各种ILI93XX液晶,但是其他函数是基于ILI9320的!!!
//在其他型号的驱动芯片上没有测试!
void LCD_Init(void)
{     
    vu32 i=0;

    GPIO_InitTypeDef  GPIO_InitStructure;
    FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
    FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;
    FSMC_NORSRAMTimingInitTypeDef  writeTiming;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOG, ENABLE);//使能PD,PE,PF,PG时钟  
    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);//使能FSMC时钟  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//PC6 推挽输出,控制背光
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化 //PC6 推挽输出,控制背光
    GPIO_ResetBits(GPIOC,GPIO_Pin_6);  //关闭背光
   
    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_11;//PB11 推挽输出,控制LCD复位
    GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化 //PB11 推挽输出,控制LCD复位
   
    GPIO_InitStructure.GPIO_Pin = (3<<0)|(3<<4)|(7<<8)|(3<<14);//PD0,1,4,5,8,9,10,14,15 AF OUT
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化  

    GPIO_InitStructure.GPIO_Pin = (0X1FF<<7);//PE7~15,AF OUT
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//PF12,FSMC_A6
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//PG12,LCD_CS
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化

    GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);//PD0,AF12
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);//PD1,AF12
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);//PD15,AF12

    GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC);//PE7,AF12
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);//PE15,AF12

    GPIO_PinAFConfig(GPIOF,GPIO_PinSource12,GPIO_AF_FSMC);//PF12,AF12
    GPIO_PinAFConfig(GPIOG,GPIO_PinSource12,GPIO_AF_FSMC);

  readWriteTiming.FSMC_AddressSetupTime = 0XF;     //地址建立时间(ADDSET)为16个HCLK 1/168M=6ns*16=96ns   
  readWriteTiming.FSMC_AddressHoldTime = 0x00;     //地址保持时间(ADDHLD)模式A未用到   
  readWriteTiming.FSMC_DataSetupTime = 60;            //数据保存时间为60个HCLK    =6*60=360ns
  readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
  readWriteTiming.FSMC_CLKDivision = 0x00;
  readWriteTiming.FSMC_DataLatency = 0x00;
  readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;     //模式A
   

    writeTiming.FSMC_AddressSetupTime =9;          //地址建立时间(ADDSET)为9个HCLK =54ns
  writeTiming.FSMC_AddressHoldTime = 0x00;     //地址保持时间(A        
  writeTiming.FSMC_DataSetupTime = 8;         //数据保存时间为6ns*9个HCLK=54ns
  writeTiming.FSMC_BusTurnAroundDuration = 0x00;
  writeTiming.FSMC_CLKDivision = 0x00;
  writeTiming.FSMC_DataLatency = 0x00;
  writeTiming.FSMC_AccessMode = FSMC_AccessMode_A;     //模式A

    FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;//  这里我们使用NE4 ,也就对应BTCR[6],[7]。
    FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不复用数据地址
    FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM;  //SRAM   
    FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;//存储器数据宽度为16bit   
    FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
    FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;   
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;  
    FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;    //  存储器写使能
    FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;   
    FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // 读写使用不同的时序
    FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序
    FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming;  //写时序

    FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  //初始化FSMC配置
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);  // 使能BANK1
   
    /*===========LCD 复位=======================*/
    GPIO_ResetBits(GPIOB, GPIO_Pin_11);
    delay_ms(150); // delay 50 ms                        
    GPIO_SetBits(GPIOB, GPIO_Pin_11 );              
    delay_ms(150); // delay 50 ms ;
        
    //尝试9486 ID的读取        
    LCD_WR_REG(0XD3);                  
    lcdid=LCD_RD_DATA();    //dummy read     
    lcdid=LCD_RD_DATA();     //读到0X00
    lcdid=LCD_RD_DATA();       //读取94                                   
    lcdid<<=8;
    lcdid|=LCD_RD_DATA();      //读取86     
         
    printf(" LCD ID:%x\r\n",lcdid); //打印LCD ID  
//    if(lcddev.id==0X9486)    //9486初始化
    if(1)    //9486初始化
    {     
        LCD_WR_REG(0x11);
        delay_ms(120);   
        LCD_WR_REG(0x13);
        delay_ms(120);

        LCD_WR_REG(0xD0);//电源设置,有3个参数,P115,色彩过白就调节这个3个参数
       LCD_WR_DATA(0x07);//P115
       LCD_WR_DATA(0x45);//P115
       LCD_WR_DATA(0x18);//P115-116
        LCD_WR_REG( 0xD1);
       LCD_WR_DATA( 0x03);
       LCD_WR_DATA( 0x10);//VCM
       LCD_WR_DATA( 0x05);//VDV

        //     LCD_WR_REG(0x00D1);//VCOM Control,有3个参数,P117
        //     LCD_WR_INITDATA(0x0000);//P118
        //     LCD_WR_INITDATA(0x0001);//P117
        //     LCD_WR_INITDATA(0x001F);//P117-118

        LCD_WR_REG(0xD2);//Power Setting for Normal Mode,有2个参数,P119
       LCD_WR_DATA(0x01);//P118
       LCD_WR_DATA(0x11);//P119

        LCD_WR_REG(0xC0);//Panel Driving Setting,有6个参数,P102,主要设置行扫描
       LCD_WR_DATA(0x00);//P102-103 GS=0
       LCD_WR_DATA(0x3B);//P103,(0x3B + 1) * 8 = 480行
       LCD_WR_DATA(0x00);//P103
       LCD_WR_DATA(0x00);//P103
       LCD_WR_DATA(0x11);//P103-104
        //    LCD_WR_INITDATA(0x0000);//P103-104

        LCD_WR_REG(0xC1);//Didsplay Timing Setting for Normal Mode,有3个参数,P106
       LCD_WR_DATA(0x10);//P106
       LCD_WR_DATA(0x0B);//P106
       LCD_WR_DATA(0x88);//P107

        LCD_WR_REG(0xC5);//Frame Rate and Inversion control,有1个参数,P112
       LCD_WR_DATA(0x00);//P112

        LCD_WR_REG(0xC8);//Gamma Setting,有12个参数,P114
       LCD_WR_DATA(0x00);//P114
       LCD_WR_DATA(0x14);//P114
       LCD_WR_DATA(0x33);//P114
       LCD_WR_DATA(0x10);//P114
       LCD_WR_DATA(0x00);//P114
       LCD_WR_DATA(0x16);//P114
       LCD_WR_DATA(0x44);//P114
       LCD_WR_DATA(0x36);//P114
       LCD_WR_DATA(0x77);//P114
       LCD_WR_DATA(0x00);//P114
       LCD_WR_DATA(0x0F);//P114
       LCD_WR_DATA(0x00);//P114

        LCD_WR_REG(0x30); //
       LCD_WR_DATA(0x00); //
       LCD_WR_DATA(0x18); //
       LCD_WR_DATA(0x01); //
       LCD_WR_DATA(0x10); //

        LCD_WR_REG(0x3A);//Set Pixel Format,有1个参数,P86
       LCD_WR_DATA(0x55);//0x0055为65K色,0x0066为26万色,P86
      
        LCD_WR_REG(0x36); //Set_address_mode
       LCD_WR_DATA(0x00); //竖屏,从左下角开始,从左到右,从下到上
      
        LCD_WR_REG(0x2A);
       LCD_WR_DATA(0x00);
       LCD_WR_DATA(0x00);
       LCD_WR_DATA(0x01);
       LCD_WR_DATA(0x27);

        LCD_WR_REG(0x2B);
       LCD_WR_DATA(0x00);
       LCD_WR_DATA(0x00);
       LCD_WR_DATA(0x01);
       LCD_WR_DATA(0xDF);
        delay_ms(120);
        LCD_WR_REG(0x29);

    }

    LCD_LED=1;                    //点亮背光
    LCD_Clear(RED);
}  
//清屏函数
//color:要清屏的填充色
void LCD_Clear(u16 color)
{
    u32 index=0;      
    u32 totalpoint=272;
   
        uint8_t color1;
      uint8_t color2;
   
        color1=color>>8;
    color2=color&0xff;
   
    totalpoint*=480;             //得到总点数
    LCD_SetCursor(0x00,0x0000);    //设置光标位置
    LCD_WriteRAM_Prepare();             //开始写入GRAM           
    for(index=0;index<totalpoint;index++)
    {
//        LCD_WriteRAM(color);   
        LCD_WR_DATA(color1);
        LCD_WR_DATA(color2);
    }
}  
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115777
QQ
发表于 2015-4-29 17:43:51 | 显示全部楼层
你8位屏的颜色是16位的? 看你的代码,颜色已经连续读两次了。
回复

使用道具 举报

17

主题

132

回帖

183

积分

初级会员

积分
183
 楼主| 发表于 2015-4-29 20:21:44 | 显示全部楼层
看9486手册,颜色是16位,用8位屏要写2次,读数据度2次8位合成16位颜色值,写没有问题,读数据不正常。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115777
QQ
发表于 2015-4-30 15:40:56 | 显示全部楼层

回 rgzdb 的帖子

rgzdb:看9486手册,颜色是16位,用8位屏要写2次,读数据度2次8位合成16位颜色值,写没有问题,读数据不正常。 (2015-04-29 20:21) 
读取颜色时,再多读取一次试试,看你的代码已经多读取一次了。
回复

使用道具 举报

7

主题

31

回帖

52

积分

初级会员

积分
52
QQ
发表于 2018-10-27 17:33:23 | 显示全部楼层
您好,我最近也在写ILI9486驱动,ID读取正常,像素点写入再读出来也正常,但是没有显示。能不能把您的程序分享一份,谢谢!(邮箱:123006188@qq.com
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-17 12:17 , Processed in 0.291337 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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