TFT屏

  原代码有近3000行,因为设备较多,而且有的文件设计到ucosIII的配置,因此再这里进行了删减

#include "lcd.h"
#include "stdlib.h"
#include "font.h"
#include "usart.h"    
#include "delay.h"       
    

//LCD的画笔颜色和背景色       
u16 POINT_COLOR=0x0000;    //画笔颜色
u16 BACK_COLOR=0xFFFF;  //背景色
 
//管理LCD重要参数
//默认为竖屏
_lcd_dev lcddev;
    
//写寄存器函数
//regval:寄存器值
void LCD_WR_REG(u16 regval)
{   
    LCD->LCD_REG=regval;//写入要写的寄存器序号    
}
//写LCD数据
//data:要写入的值
void LCD_WR_DATA(u16 data)
{    
    LCD->LCD_RAM=data;        
}
//读LCD数据
//返回值:读到的值
u16 LCD_RD_DATA(void)
{
    vu16 ram;            //防止被优化
    ram=LCD->LCD_RAM;    
    return ram;    
}                       
//写寄存器
//LCD_Reg:寄存器地址
//LCD_RegValue:要写入的数据
void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
{    
    LCD->LCD_REG = LCD_Reg;        //写入要写的寄存器序号    
    LCD->LCD_RAM = LCD_RegValue;//写入数据                
}       
//读寄存器
//LCD_Reg:寄存器地址
//返回值:读到的数据
u16 LCD_ReadReg(u16 LCD_Reg)
{                                           
    LCD_WR_REG(LCD_Reg);        //写入要读的寄存器序号
    delay_us(5);          
    return LCD_RD_DATA();        //返回读到的值
}   
//开始写GRAM
void LCD_WriteRAM_Prepare(void)
{
     LCD->LCD_REG=lcddev.wramcmd;      
}    
//LCD写GRAM
//RGB_Code:颜色值
void LCD_WriteRAM(u16 RGB_Code)
{                                
    LCD->LCD_RAM = RGB_Code;//写十六位GRAM
}

void opt_delay(u8 i)
{
    while(i--);
}
//读取个某点的颜色值    
//x,y:坐标
//返回值:此点的颜色


//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{
        Xpos=lcddev.width-1-Xpos;
        LCD_WR_REG(lcddev.setxcmd);
        LCD_WR_DATA(0);LCD_WR_DATA(0);         
        LCD_WR_DATA(Xpos>>8);LCD_WR_DATA(Xpos&0XFF);             
        
        LCD_WR_REG(lcddev.setycmd);
        LCD_WR_DATA(Ypos>>8);LCD_WR_DATA(Ypos&0XFF);         
        LCD_WR_DATA((lcddev.height-1)>>8);LCD_WR_DATA((lcddev.height-1)&0XFF);                      
    
}         
//设置LCD的自动扫描方向
//注意:其他函数可能会受到此函数设置的影响(尤其是9341/6804这两个奇葩),
//所以,一般设置为L2R_U2D即可,如果设置为其他扫描方式,可能导致显示不正常.
//dir:0~7,代表8个方向(具体定义见lcd.h)
//9320/9325/9328/4531/4535/1505/b505/5408/9341/5310/5510/1963等IC已经实际测试              
void LCD_Scan_Dir(u8 dir)
{
    u16 regval=0;
    u16 dirreg=0;
    u16 temp;             
    regval|=(0<<7)|(1<<6)|(1<<5);
    dirreg=0X3600;
    LCD_WriteReg(dirreg,regval);
    temp=lcddev.width;
    lcddev.width=lcddev.height;
    lcddev.height=temp;
    LCD_WR_REG(lcddev.setxcmd);
    LCD_WR_DATA(0);LCD_WR_DATA(0);
    LCD_WR_DATA((lcddev.width-1)>>8);
    LCD_WR_DATA((lcddev.width-1)&0XFF);
    LCD_WR_REG(lcddev.setycmd);
    LCD_WR_DATA(0);LCD_WR_DATA(0);
    LCD_WR_DATA((lcddev.height-1)>>8);
    LCD_WR_DATA((lcddev.height-1)&0XFF);  
        
}

//快速画点
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color)
{       

     if(lcddev.dir==1)x=lcddev.width-1-x;//横屏其实就是调转x,y坐标
    LCD_WriteReg(lcddev.setxcmd,x);
    LCD_WriteReg(lcddev.setycmd,y);
            
    LCD->LCD_REG=lcddev.wramcmd;
    LCD->LCD_RAM=color;
}    

//设置LCD显示方向
//dir:0,竖屏;1,横屏
void LCD_Display_Dir(u8 dir)
{
    if(dir==0)            //竖屏
    {
        lcddev.dir=0;    //竖屏
        lcddev.width=240;
        lcddev.height=320;

        lcddev.wramcmd=0X22;
         lcddev.setxcmd=0X20;
        lcddev.setycmd=0X21;  

    }

    LCD_Scan_Dir(DFT_SCAN_DIR);    //默认扫描方向
}    

void LCD_Init(void)
{                     
     GPIO_InitTypeDef GPIO_InitStructure;
    FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;
    FSMC_NORSRAMTimingInitTypeDef  writeTiming;
    
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);    //使能FSMC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOG,ENABLE);//使能PORTB,D,E,G以及AFIO复用功能时钟

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                 //PB0 推挽输出 背光
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
    
     //PORTD复用推挽输出  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_14|GPIO_Pin_15;                 //    //PORTD复用推挽输出  
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;          //复用推挽输出   
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOD, &GPIO_InitStructure);
      
    //PORTE复用推挽输出  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;                 //    //PORTD复用推挽输出  
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;          //复用推挽输出   
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOE, &GPIO_InitStructure);                                                             

       //    //PORTG12复用推挽输出 A0    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_12;     //    //PORTD复用推挽输出  
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;          //复用推挽输出   
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOG, &GPIO_InitStructure);

    readWriteTiming.FSMC_AddressSetupTime = 0x01;     //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns
  readWriteTiming.FSMC_AddressHoldTime = 0x00;     //地址保持时间(ADDHLD)模式A未用到    
  readWriteTiming.FSMC_DataSetupTime = 0x0f;         // 数据保存时间为16个HCLK,因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC。
  readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
  readWriteTiming.FSMC_CLKDivision = 0x00;
  readWriteTiming.FSMC_DataLatency = 0x00;
  readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;     //模式A
    

    writeTiming.FSMC_AddressSetupTime = 0x00;     //地址建立时间(ADDSET)为1个HCLK  
  writeTiming.FSMC_AddressHoldTime = 0x00;     //地址保持时间(A        
  writeTiming.FSMC_DataSetupTime = 0x03;         数据保存时间为4个HCLK    
  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_16b;//存储器数据宽度为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
        
 
    delay_ms(50);                     // delay 50 ms
     
        LCD_WriteReg(0x0000,0x0000);
        LCD_WriteReg(0x0000,0x0000);
        LCD_WriteReg(0x0000,0x0000);
        LCD_WriteReg(0x0000,0x0000);
        
        LCD_WriteReg(0x00a4,0x0001);
        delay_ms(20);          
        LCD_WriteReg(0x0060,0x2700);
        LCD_WriteReg(0x0008,0x0202);
        
        LCD_WriteReg(0x0030,0x0214);
        LCD_WriteReg(0x0031,0x3715);
        LCD_WriteReg(0x0032,0x0604);
        LCD_WriteReg(0x0033,0x0e16);
        LCD_WriteReg(0x0034,0x2211);
        LCD_WriteReg(0x0035,0x1500);
        LCD_WriteReg(0x0036,0x8507);
        LCD_WriteReg(0x0037,0x1407);
        LCD_WriteReg(0x0038,0x1403);
        LCD_WriteReg(0x0039,0x0020);
        
        LCD_WriteReg(0x0090,0x001a);
        LCD_WriteReg(0x0010,0x0000);
        LCD_WriteReg(0x0011,0x0007);
        LCD_WriteReg(0x0012,0x0000);
        LCD_WriteReg(0x0013,0x0000);
        delay_ms(20);
        
        LCD_WriteReg(0x0010,0x0730);
        LCD_WriteReg(0x0011,0x0137);
        delay_ms(20);
        
        LCD_WriteReg(0x0012,0x01b8);
        delay_ms(20);
        
        LCD_WriteReg(0x0013,0x0f00);
        LCD_WriteReg(0x002a,0x0080);
        LCD_WriteReg(0x0029,0x0048);
        delay_ms(20);
        
        LCD_WriteReg(0x0001,0x0100);
        LCD_WriteReg(0x0002,0x0700);
        LCD_WriteReg(0x0003,0x1038);//扫描方向 上->下  左->右
        LCD_WriteReg(0x0008,0x0202);
        LCD_WriteReg(0x000a,0x0000);
        LCD_WriteReg(0x000c,0x0000);
        LCD_WriteReg(0x000d,0x0000);
        LCD_WriteReg(0x000e,0x0030);
        LCD_WriteReg(0x0050,0x0000);
        LCD_WriteReg(0x0051,0x00ef);
        LCD_WriteReg(0x0052,0x0000);
        LCD_WriteReg(0x0053,0x013f);
        LCD_WriteReg(0x0060,0x2700);
        LCD_WriteReg(0x0061,0x0001);
        LCD_WriteReg(0x006a,0x0000);
        //LCD_WriteReg(0x0080,0x0000);
        //LCD_WriteReg(0x0081,0x0000);
        LCD_WriteReg(0x0090,0X0011);
        LCD_WriteReg(0x0092,0x0600);
        LCD_WriteReg(0x0093,0x0402);
        LCD_WriteReg(0x0094,0x0002);
        delay_ms(20);
        
        LCD_WriteReg(0x0007,0x0001);
        delay_ms(20);
        LCD_WriteReg(0x0007,0x0061);
        LCD_WriteReg(0x0007,0x0173);
        
        LCD_WriteReg(0x0020,0x0000);
        LCD_WriteReg(0x0021,0x0000);      
        LCD_WriteReg(0x00,0x22);  
        LCD_Display_Dir(0);        //默认为竖屏
        LCD_LED=1;                //点亮背光
        LCD_Clear(WHITE);
}  
//清屏函数
//color:要清屏的填充色
void LCD_Clear(u16 color)
{
    u32 index=0;      
    u32 totalpoint=lcddev.width;
    totalpoint*=lcddev.height;             //得到总点数
    
    LCD_SetCursor(0x00,0x0000);    //设置光标位置
    LCD_WriteRAM_Prepare();             //开始写入GRAM           
    for(index=0;index<totalpoint;index++)
    {
        LCD->LCD_RAM=color;    
    }
}  
 
//在指定位置显示一个字符
//x,y:起始坐标
//num:要显示的字符:" "--->"~"
//size:字体大小 12/16/24
//mode:叠加方式(1)还是非叠加方式(0)
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{                                
    u8 temp,t1,t;
    u16 y0=y;
    u8 csize=(size/8+((size%8)?1:0))*(size/2);        //得到字体一个字符对应点阵集所占的字节数    
     num=num-' ';//得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)
    for(t=0;t<csize;t++)
    {   
        if(size==12)temp=asc2_1206[num][t];          //调用1206字体
        else if(size==16)temp=asc2_1608[num][t];    //调用1608字体
        else if(size==24)temp=asc2_2412[num][t];    //调用2412字体
        else return;                                //没有的字库
        for(t1=0;t1<8;t1++)
        {                
            if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR);
            else if(mode==0)LCD_Fast_DrawPoint(x,y,BACK_COLOR);
            temp<<=1;
            y++;
            if(y>=lcddev.height)return;        //超区域了
            if((y-y0)==size)
            {
                y=y0;
                x++;
                if(x>=lcddev.width)return;    //超区域了
                break;
            }
        }      
    }                            
}   
//m^n函数
//返回值:m^n次方.
u32 LCD_Pow(u8 m,u8 n)
{
    u32 result=1;    
    while(n--)result*=m;    
    return result;
}        


//显示数字,高位为0,则不显示
//x,y :起点坐标    
//len :数字的位数
//size:字体大小
//color:颜色
//num:数值(0~4294967295);    
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)
{             
    u8 t,temp;
    u8 enshow=0;                           
    for(t=0;t<len;t++)
    {
        temp=(num/LCD_Pow(10,len-t-1))%10;
        if(enshow==0&&t<(len-1))
        {
            if(temp==0)
            {
                LCD_ShowChar(x+(size/2)*t,y,' ',size,0);
                continue;
            }else enshow=1;
             
        }
         LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0);
    }
}


//显示字符串
//x,y:起点坐标
//width,height:区域大小  
//size:字体大小
//*p:字符串起始地址          
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p)
{         
    u8 x0=x;
    width+=x;
    height+=y;
    while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
    {       
        if(x>=width){x=x0;y+=size;}
        if(y>=height)break;//退出
        LCD_ShowChar(x,y,*p,size,0);
        x+=size/2;
        p++;
    }  
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值