原创 跟我学STM324 2.8寸LCD显示

2009-12-31 21:52 10185 9 15 分类: MCU/ 嵌入式

    该代码基于STMSKY网络开发板硬件.驱动板载2.8寸LCD,采用FSMC 16位方式驱动.其中最关键的是对FSMC进行初始化,这个搞定了,其他的就比较容易了,这里我全部使用寄存器操作,可读性没库函数好,但是等你熟悉了之后,这个问题就不存在了,而且代码更加简洁.


LCD驱动部分代码如下:


#include "lcd.h"
#include "stdlib.h"
#include "font.h"
u16 POINT_COLOR = 0x0000, BACK_COLOR = 0xFFFF;
//STMSKY开发板2.8寸TFT液晶驱动(9325)
//FSMC驱动
//正点原子@深圳南山
//2009.12.31
//V1.1


//写寄存器
void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)
{    
 LCD->LCD_REG = LCD_Reg;//写入要写的寄存器序号 
 LCD->LCD_RAM = LCD_RegValue;//写入数据
}   
//读寄存器
u16 LCD_ReadReg(u8 LCD_Reg)
{            
 LCD->LCD_REG = LCD_Reg;//写入要读的寄存器序号   
 return (LCD->LCD_RAM);//返回读到的值
}  
//开始写GRAM
void LCD_WriteRAM_Prepare(void)
{
 LCD->LCD_REG = R34;

//LCD写GRAM
void LCD_WriteRAM(u16 RGB_Code)
{          
 LCD->LCD_RAM = RGB_Code;//写十六位GRAM
}
//LCD读GRAM
u16 LCD_ReadRAM(void)
{  
 u16 ts;
 LCD->LCD_REG = R34; //选择GRAM地址
 ts=LCD->LCD_RAM; //第一个数据放弃
 ts=LCD->LCD_RAM; //得到数据
 return ts;
}
//LCD开启显示
void LCD_DisplayOn(void)
{       
 LCD_WriteReg(R7, 0x0173); //26万色显示开启

//LCD关闭显示
void LCD_DisplayOff(void)
{   
 LCD_WriteReg(R7, 0x0);//关闭显示
}   
//LCD延时函数 10MS
void Delay (u32 nCount)
{
 volatile int i;   
 for (i=0;i<nCount*100;i++);
}
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u8 Xpos, u16 Ypos)
{
 LCD_WriteReg(R32, Xpos);
 LCD_WriteReg(R33, Ypos);
}
//画点
//x:0~239
//y:0~319
//POINT_COLOR:此点的颜色
void LCD_DrawPoint(u8 x,u16 y)
{
 LCD_SetCursor(x,y);//设置光标位置
 LCD->LCD_REG=R34;//开始写入GRAM
 LCD->LCD_RAM=POINT_COLOR;
}
 
//初始化lcd
//该初始化函数可以初始化各种ILI93XX液晶,但是其他函数是基于ILI9300的!!!
//在其他型号的驱动芯片上没有测试!
void LCD_Init(void)
{
 u16 DeviceCode; 
 RCC->AHBENR|=1<<8;    //使能FSMC时钟
 RCC->APB2ENR|=0X01E5;    //使能PORTA,D,E,F,G AFIO时钟


 GPIOA->CRH&=0XFFFFFFF0;//GPIOA.8 推挽输出 背光
 GPIOA->CRH|=0XFFFFFFF3;
 //PORTD复用推挽输出  
 GPIOD->CRH&=0X00FFF000;
 GPIOD->CRH|=0XBB000BBB;
 GPIOD->CRL&=0XFF00FF00;
 GPIOD->CRL|=0X00BB00BB;    
 //PORTE复用推挽输出  
 GPIOE->CRH&=0X00000000;
 GPIOE->CRH|=0XBBBBBBBB;
 GPIOE->CRL&=0X0FFFFFFF;
 GPIOE->CRL|=0XB0000000;
 //PORTF复用推挽输出                   
 GPIOF->CRL&=0XFFFFFFF0;
 GPIOF->CRL|=0X0000000B;
 //PORTG12复用推挽输出 A0                  
 GPIOG->CRH&=0XFFF0FFFF;
 GPIOG->CRH|=0X000B0000;
     
 //寄存器清零
 //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
 //这里我们使用NE4 ,也就对应BTCR[6],[7]。       
 FSMC_Bank1->BTCR[6]=0X00000000;
 FSMC_Bank1->BTCR[7]=0X00000000;
 FSMC_Bank1E->BWTR[6]=0X00000000;
 //操作BCR寄存器 使用异步模式
 FSMC_Bank1->BTCR[6]|=1<<12;//存储器写使能
 FSMC_Bank1->BTCR[6]|=1<<4; //存储器数据宽度为16bit     
 //操作BTR寄存器           
 FSMC_Bank1->BTCR[7]|=1<<9; //数据保存时间为3个HCLK   
 //闪存写时序寄存器 
 FSMC_Bank1E->BWTR[6]=0x0FFFFFFF;//默认值
 //使能BANK4(PC卡设备)
 FSMC_Bank1->BTCR[6]|=1<<0; 
      
 Delay(5); // delay 50 ms
 LCD_WriteReg(0x0000,0x0001);
 Delay(5); // delay 50 ms
 DeviceCode = LCD_ReadReg(0x0000);  
 if(DeviceCode==0x9325||DeviceCode==0x9328)//ILI9325
 {
    LCD_WriteReg(0x00e7,0x0010);     
        LCD_WriteReg(0x0000,0x0001);//开启内部时钟
        LCD_WriteReg(0x0001,0x0100);    
        LCD_WriteReg(0x0002,0x0700);//电源开启                   
  //LCD_WriteReg(0x0003,(1<<3)|(1<<4) );  //65K  RGB
  //DRIVE TABLE(寄存器 03H)
  //BIT3=AM BIT4:5=ID0:1
  //AM ID0 ID1   FUNCATION
  // 0  0   0    R->L D->U
  // 1  0   0    D->U R->L
  // 0  1   0    L->R D->U
  // 1  1   0    D->U L->R
  // 0  0   1    R->L U->D
  // 1  0   1    U->D R->L
  // 0  1   1    L->R U->D 正常就用这个.
  // 1  1   1    U->D L->R
        LCD_WriteReg(0x0003,(1<<12)|(3<<4)|(0<<3) );//65K   
        LCD_WriteReg(0x0004,0x0000);                                  
        LCD_WriteReg(0x0008,0x0207);           
        LCD_WriteReg(0x0009,0x0000);        
        LCD_WriteReg(0x000a,0x0000);//display setting        
        LCD_WriteReg(0x000c,0x0001);//display setting         
        LCD_WriteReg(0x000d,0x0000);//0f3c         
        LCD_WriteReg(0x000f,0x0000);
  //电源配置
        LCD_WriteReg(0x0010,0x0000);  
        LCD_WriteReg(0x0011,0x0007);
        LCD_WriteReg(0x0012,0x0000);                                                                
        LCD_WriteReg(0x0013,0x0000);                
        Delay(5);
        LCD_WriteReg(0x0010,0x1590);  
        LCD_WriteReg(0x0011,0x0227);
        Delay(5);
        LCD_WriteReg(0x0012,0x009c);                 
        Delay(5);
        LCD_WriteReg(0x0013,0x1900);  
        LCD_WriteReg(0x0029,0x0023);
        LCD_WriteReg(0x002b,0x000e);
        Delay(5);
        LCD_WriteReg(0x0020,0x0000);                                                           
        LCD_WriteReg(0x0021,0x013f);          
  Delay(5);
  //伽马校正
        LCD_WriteReg(0x0030,0x0007);
        LCD_WriteReg(0x0031,0x0707);  
        LCD_WriteReg(0x0032,0x0006);
        LCD_WriteReg(0x0035,0x0704);
        LCD_WriteReg(0x0036,0x1f04);
        LCD_WriteReg(0x0037,0x0004);
        LCD_WriteReg(0x0038,0x0000);       
        LCD_WriteReg(0x0039,0x0706);    
        LCD_WriteReg(0x003c,0x0701);
        LCD_WriteReg(0x003d,0x000f);
        Delay(5);
        LCD_WriteReg(0x0050,0x0000); //水平GRAM起始位置
        LCD_WriteReg(0x0051,0x00ef); //水平GRAM终止位置                   
        LCD_WriteReg(0x0052,0x0000); //垂直GRAM起始位置                   
        LCD_WriteReg(0x0053,0x013f); //垂直GRAM终止位置 
       
        LCD_WriteReg(0x0060,0xa700);       
        LCD_WriteReg(0x0061,0x0001);
        LCD_WriteReg(0x006a,0x0000);
        LCD_WriteReg(0x0080,0x0000);
        LCD_WriteReg(0x0081,0x0000);
        LCD_WriteReg(0x0082,0x0000);
        LCD_WriteReg(0x0083,0x0000);
        LCD_WriteReg(0x0084,0x0000);
        LCD_WriteReg(0x0085,0x0000);
     
        LCD_WriteReg(0x0090,0x0010);    
        LCD_WriteReg(0x0092,0x0000); 
        LCD_WriteReg(0x0093,0x0003);
        LCD_WriteReg(0x0095,0x0110);
        LCD_WriteReg(0x0097,0x0000);       
        LCD_WriteReg(0x0098,0x0000); 
        //开启显示设置   
        LCD_WriteReg(0x0007,0x0133);  
        LCD_WriteReg(0x0020,0x0000);                                                           
        LCD_WriteReg(0x0021,0x013f);
 }
 else if(DeviceCode==0x9320||DeviceCode==0x9300)
 {
  LCD_WriteReg(0x00,0x0000);
  LCD_WriteReg(0x01,0x0100); //Driver Output Contral.
  LCD_WriteReg(0x02,0x0700); //LCD Driver Waveform Contral.
  //LCD_WriteReg(0x03,0x1030);//Entry Mode Set.
  LCD_WriteReg(0x03,0x1018); //Entry Mode Set.
 
  LCD_WriteReg(0x04,0x0000); //Scalling Contral.
  LCD_WriteReg(0x08,0x0202); //Display Contral 2.(0x0207)
  LCD_WriteReg(0x09,0x0000); //Display Contral 3.(0x0000)
  LCD_WriteReg(0x0a,0x0000); //Frame Cycle Contal.(0x0000)
  LCD_WriteReg(0x0c,(1<<0)); //Extern Display Interface Contral 1.(0x0000)
  LCD_WriteReg(0x0d,0x0000); //Frame Maker Position.
  LCD_WriteReg(0x0f,0x0000); //Extern Display Interface Contral 2.    
  Delay(5);
  LCD_WriteReg(0x07,0x0101); //Display Contral.
  Delay(5);          
  LCD_WriteReg(0x10,(1<<12)|(0<<8)|(1<<7)|(1<<6)|(0<<4)); //Power Control 1.(0x16b0)
  LCD_WriteReg(0x11,0x0007);        //Power Control 2.(0x0001)
  LCD_WriteReg(0x12,(1<<8)|(1<<4)|(0<<0));    //Power Control 3.(0x0138)
  LCD_WriteReg(0x13,0x0b00);        //Power Control 4.
  LCD_WriteReg(0x29,0x0000);        //Power Control 7.
 
  LCD_WriteReg(0x2b,(1<<14)|(1<<4));    
  LCD_WriteReg(0x50,0); //Set X Star
  //水平GRAM终止位置Set X End.
  LCD_WriteReg(0x51,239); //Set Y Star
  LCD_WriteReg(0x52,0); //Set Y End.t.
  LCD_WriteReg(0x53,319); //
 
  LCD_WriteReg(0x60,0x2700); //Driver Output Control.
  LCD_WriteReg(0x61,0x0001); //Driver Output Control.
  LCD_WriteReg(0x6a,0x0000); //Vertical Srcoll Control.
 
  LCD_WriteReg(0x80,0x0000); //Display Position? Partial Display 1.
  LCD_WriteReg(0x81,0x0000); //RAM Address Start? Partial Display 1.
  LCD_WriteReg(0x82,0x0000); //RAM Address End-Partial Display 1.
  LCD_WriteReg(0x83,0x0000); //Displsy Position? Partial Display 2.
  LCD_WriteReg(0x84,0x0000); //RAM Address Start? Partial Display 2.
  LCD_WriteReg(0x85,0x0000); //RAM Address End? Partial Display 2.
 
  LCD_WriteReg(0x90,(0<<7)|(16<<0)); //Frame Cycle Contral.(0x0013)
  LCD_WriteReg(0x92,0x0000); //Panel Interface Contral 2.(0x0000)
  LCD_WriteReg(0x93,0x0001); //Panel Interface Contral 3.
  LCD_WriteReg(0x95,0x0110); //Frame Cycle Contral.(0x0110)
  LCD_WriteReg(0x97,(0<<8)); //
  LCD_WriteReg(0x98,0x0000); //Frame Cycle Contral.   
  LCD_WriteReg(0x07,0x0173); //(0x0173)
 }
 
 else if(DeviceCode==0x1505)
 {
  // second release on 3/5  ,luminance is acceptable,water wave appear during camera preview
        LCD_WriteReg(0x0007,0x0000);
        Delay(5);
        LCD_WriteReg(0x0012,0x011C);//0x011A   why need to set several times?
        LCD_WriteReg(0x00A4,0x0001);//NVM 
        LCD_WriteReg(0x0008,0x000F);
        LCD_WriteReg(0x000A,0x0008);
        LCD_WriteReg(0x000D,0x0008);    
    //伽马校正
        LCD_WriteReg(0x0030,0x0707);
        LCD_WriteReg(0x0031,0x0007); //0x0707
        LCD_WriteReg(0x0032,0x0603);
        LCD_WriteReg(0x0033,0x0700);
        LCD_WriteReg(0x0034,0x0202);
        LCD_WriteReg(0x0035,0x0002); //?0x0606
        LCD_WriteReg(0x0036,0x1F0F);
        LCD_WriteReg(0x0037,0x0707); //0x0f0f  0x0105
        LCD_WriteReg(0x0038,0x0000);
        LCD_WriteReg(0x0039,0x0000);
        LCD_WriteReg(0x003A,0x0707);
        LCD_WriteReg(0x003B,0x0000); //0x0303
        LCD_WriteReg(0x003C,0x0007); //?0x0707
        LCD_WriteReg(0x003D,0x0000); //0x1313//0x1f08
        Delay(5);
        LCD_WriteReg(0x0007,0x0001);
        LCD_WriteReg(0x0017,0x0001);//开启电源
        Delay(5);
    //电源配置
        LCD_WriteReg(0x0010,0x17A0);
        LCD_WriteReg(0x0011,0x0217);//reference voltage VC[2:0]   Vciout = 1.00*Vcivl
        LCD_WriteReg(0x0012,0x011E);//0x011c  //Vreg1out = Vcilvl*1.80   is it the same as Vgama1out ?
        LCD_WriteReg(0x0013,0x0F00);//VDV[4:0]-->VCOM Amplitude VcomL = VcomH - Vcom Ampl
        LCD_WriteReg(0x002A,0x0000); 
        LCD_WriteReg(0x0029,0x000A);//0x0001F  Vcomh = VCM1[4:0]*Vreg1out    gate source voltage??
        LCD_WriteReg(0x0012,0x013E);// 0x013C  power supply on
        //Coordinates Control//
        LCD_WriteReg(0x0050,0x0000);//0x0e00
        LCD_WriteReg(0x0051,0x00EF);
        LCD_WriteReg(0x0052,0x0000);
        LCD_WriteReg(0x0053,0x013F);
     //Pannel Image Control//
        LCD_WriteReg(0x0060,0x2700);
        LCD_WriteReg(0x0061,0x0001);
        LCD_WriteReg(0x006A,0x0000);
        LCD_WriteReg(0x0080,0x0000);
     //Partial Image Control//
        LCD_WriteReg(0x0081,0x0000);
        LCD_WriteReg(0x0082,0x0000);
        LCD_WriteReg(0x0083,0x0000);
        LCD_WriteReg(0x0084,0x0000);
        LCD_WriteReg(0x0085,0x0000);
    //Panel Interface Control//
        LCD_WriteReg(0x0090,0x0013);//0x0010 frenqucy
        LCD_WriteReg(0x0092,0x0300);
        LCD_WriteReg(0x0093,0x0005);
        LCD_WriteReg(0x0095,0x0000);
        LCD_WriteReg(0x0097,0x0000);
        LCD_WriteReg(0x0098,0x0000);
 
        LCD_WriteReg(0x0001,0x0100);
        LCD_WriteReg(0x0002,0x0700);
        LCD_WriteReg(0x0003,0x1030);
        LCD_WriteReg(0x0004,0x0000);
        LCD_WriteReg(0x000C,0x0000);
        LCD_WriteReg(0x000F,0x0000);
        LCD_WriteReg(0x0020,0x0000);
        LCD_WriteReg(0x0021,0x0000);
        LCD_WriteReg(0x0007,0x0021);
        Delay(20);
        LCD_WriteReg(0x0007,0x0061);
        Delay(20);
        LCD_WriteReg(0x0007,0x0173);
        Delay(20);
 }       
 else if(DeviceCode==0x8989)
 {
  LCD_WriteReg(0x0000,0x0001);Delay(5);//打开晶振
     LCD_WriteReg(0x0003,0xA8A4);Delay(5);//0xA8A4
     LCD_WriteReg(0x000C,0x0000);Delay(5);   
     LCD_WriteReg(0x000D,0x080C);Delay(5);   
     LCD_WriteReg(0x000E,0x2B00);Delay(5);   
     LCD_WriteReg(0x001E,0x00B0);Delay(5);   
     LCD_WriteReg(0x0001,0x2B3F);Delay(5);//驱动输出控制320*240  0x6B3F
     LCD_WriteReg(0x0002,0x0600);Delay(5);
     LCD_WriteReg(0x0010,0x0000);Delay(5);
     LCD_WriteReg(0x0011,0x6070);Delay(5);//定义数据格式  16位色   横屏 0x6058
     LCD_WriteReg(0x0005,0x0000);Delay(5);
     LCD_WriteReg(0x0006,0x0000);Delay(5);
     LCD_WriteReg(0x0016,0xEF1C);Delay(5);
     LCD_WriteReg(0x0017,0x0003);Delay(5);
     LCD_WriteReg(0x0007,0x0233);Delay(5);//0x0233      
     LCD_WriteReg(0x000B,0x0000);Delay(5);
     LCD_WriteReg(0x000F,0x0000);Delay(5);//扫描开始地址
     LCD_WriteReg(0x0041,0x0000);Delay(5);
     LCD_WriteReg(0x0042,0x0000);Delay(5);
     LCD_WriteReg(0x0048,0x0000);Delay(5);
     LCD_WriteReg(0x0049,0x013F);Delay(5);
     LCD_WriteReg(0x004A,0x0000);Delay(5);
     LCD_WriteReg(0x004B,0x0000);Delay(5);
     LCD_WriteReg(0x0044,0xEF00);Delay(5);
     LCD_WriteReg(0x0045,0x0000);Delay(5);
     LCD_WriteReg(0x0046,0x013F);Delay(5);
     LCD_WriteReg(0x0030,0x0707);Delay(5);
     LCD_WriteReg(0x0031,0x0204);Delay(5);
     LCD_WriteReg(0x0032,0x0204);Delay(5);
     LCD_WriteReg(0x0033,0x0502);Delay(5);
     LCD_WriteReg(0x0034,0x0507);Delay(5);
     LCD_WriteReg(0x0035,0x0204);Delay(5);
     LCD_WriteReg(0x0036,0x0204);Delay(5);
     LCD_WriteReg(0x0037,0x0502);Delay(5);
     LCD_WriteReg(0x003A,0x0302);Delay(5);
     LCD_WriteReg(0x003B,0x0302);Delay(5);
     LCD_WriteReg(0x0023,0x0000);Delay(5);
     LCD_WriteReg(0x0024,0x0000);Delay(5);
     LCD_WriteReg(0x0025,0x8000);Delay(5);
     LCD_WriteReg(0x004f,0);        //行首址0
     LCD_WriteReg(0x004e,0);        //列首址0
 }      
 Delay(5000); 
 LCD_Clear(WHITE);
}   
//清屏函数
//Color:要清屏的填充色
void LCD_Clear(u16 Color)
{
 u32 index="0";     
 LCD_SetCursor(0x00,0x0000);//设置光标位置
 LCD_WriteRAM_Prepare();     //开始写入GRAM    
 for(index=0;index<76800;index++)
 {
  LCD->LCD_RAM=Color;
  //delay_ms(2);
 }

//在指定区域内填充指定颜色
//区域大小:
//  (xend-xsta)*(yend-ysta)
void LCD_Fill(u8 xsta,u16 ysta,u8 xend,u16 yend,u16 color)
{                   
    u32 n;
 //设置窗口          
 LCD_WriteReg(R80, xsta); //水平方向GRAM起始地址
 LCD_WriteReg(R81, xend); //水平方向GRAM结束地址
 LCD_WriteReg(R82, ysta); //垂直方向GRAM起始地址
 LCD_WriteReg(R83, yend); //垂直方向GRAM结束地址 
 LCD_SetCursor(xsta,ysta);//设置光标位置 
 LCD_WriteRAM_Prepare();  //开始写入GRAM         
 n=(u32)(yend-ysta+1)*(xend-xsta+1);   
 while(n--){LCD->LCD_RAM=color;}//显示所填充的颜色.
 //恢复设置
 LCD_WriteReg(R80, 0x0000); //水平方向GRAM起始地址
 LCD_WriteReg(R81, 0x00EF); //水平方向GRAM结束地址
 LCD_WriteReg(R82, 0x0000); //垂直方向GRAM起始地址
 LCD_WriteReg(R83, 0x013F); //垂直方向GRAM结束地址    

//画线
//x1,y1:起点坐标
//x2,y2:终点坐标 
void LCD_DrawLine(u8 x1, u16 y1, u8 x2, u16 y2)
{
    u16 x, y, t;
 if((x1==x2)&&(y1==y2))LCD_DrawPoint(x1, y1);
 else if(abs(y2-y1)>abs(x2-x1))//斜率大于1
 {
  if(y1>y2)
  {
   t=y1;
   y1=y2;
   y2=t;
   t=x1;
   x1=x2;
   x2=t;
  }
  for(y=y1;y<y2;y++)//以y轴为基准
  {
   x=(u32)(y-y1)*(x2-x1)/(y2-y1)+x1;
   LCD_DrawPoint(x, y); 
  }
 }
 else     //斜率小于等于1
 {
  if(x1>x2)
  {
   t=y1;
   y1=y2;
   y2=t;
   t=x1;
   x1=x2;
   x2=t;
  }  
  for(x=x1;x<=x2;x++)//以x轴为基准
  {
   y =(u32)(x-x1)*(y2-y1)/(x2-x1)+y1;
   LCD_DrawPoint(x,y);
  }
 }
}   
//画矩形
void LCD_DrawRectangle(u8 x1, u16 y1, u8 x2, u16 y2)
{
 LCD_DrawLine(x1,y1,x2,y1);
 LCD_DrawLine(x1,y1,x1,y2);
 LCD_DrawLine(x1,y2,x2,y2);
 LCD_DrawLine(x2,y1,x2,y2);
}
//在指定位置画一个指定大小的圆
//(x,y):中心点
//r    :半径
void Draw_Circle(u8 x0,u16 y0,u8 r)
{
 int a,b;
 int di;
 a=0;b=r;  
 di=3-(r<<1);             //判断下个点位置的标志
 while(a<=b)
 {
  LCD_DrawPoint(x0-b,y0-a);             //3          
  LCD_DrawPoint(x0+b,y0-a);             //0          
  LCD_DrawPoint(x0-a,y0+b);             //1      
  LCD_DrawPoint(x0-b,y0-a);             //7          
  LCD_DrawPoint(x0-a,y0-b);             //2            
  LCD_DrawPoint(x0+b,y0+a);             //4              
  LCD_DrawPoint(x0+a,y0-b);             //5
  LCD_DrawPoint(x0+a,y0+b);             //6
  LCD_DrawPoint(x0-b,y0+a);            
  a++;
  //使用Bresenham算法画圆    
  if(di<0)di +=4*a+6;  
  else
  {
   di+=10+4*(a-b);  
   b--;
  }
  LCD_DrawPoint(x0+a,y0+b);
 }
}
//在指定位置显示一个字符
//x:0~234
//y:0~308
//num:要显示的字符:" "--->"~"
//size:字体大小 12/16
//mode:叠加方式(1)还是非叠加方式(0)
void LCD_ShowChar(u8 x,u16 y,u8 num,u8 size,u8 mode)
{      
#define MAX_CHAR_POSX 232
#define MAX_CHAR_POSY 304
    u8 temp;
    u8 pos,t;     
    if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return;    
 //设置窗口          
 LCD_WriteReg(R80,x);           //水平方向GRAM起始地址
 LCD_WriteReg(R81,x+(size/2-1));//水平方向GRAM结束地址
 LCD_WriteReg(R82,y);           //垂直方向GRAM起始地址
 LCD_WriteReg(R83,y+size-1);    //垂直方向GRAM结束地址 
 LCD_SetCursor(x,y);            //设置光标位置 
 LCD_WriteRAM_Prepare();        //开始写入GRAM   
 num=num-' ';//得到偏移后的值
 if(!mode) //非叠加方式
 {
  for(pos=0;pos<size;pos++)
  {
   if(size==12)temp=asc2_1206[num][pos];//调用1206字体
   else temp="asc2"_1608[num][pos];   //调用1608字体
   for(t=0;t<size/2;t++)
      {                
          if(temp&0x01)LCD->LCD_RAM=POINT_COLOR;
          else LCD->LCD_RAM=BACK_COLOR;    
          temp>>=1;
      }
  } 
 }else//叠加方式
 {
  for(pos=0;pos<size;pos++)
  {
   if(size==12)temp=asc2_1206[num][pos];//调用1206字体
   else temp="asc2"_1608[num][pos];   //调用1608字体
   for(t=0;t<size/2;t++)
      {                
          if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//画一个点    
          temp>>=1;
      }
  }
 }    
 //恢复窗体大小 
 LCD_WriteReg(R80, 0x0000); //水平方向GRAM起始地址
 LCD_WriteReg(R81, 0x00EF); //水平方向GRAM结束地址
 LCD_WriteReg(R82, 0x0000); //垂直方向GRAM起始地址
 LCD_WriteReg(R83, 0x013F); //垂直方向GRAM结束地址

//m^n函数
u32 mypow(u8 m,u8 n)
{
 u32 result="1"; 
 while(n--)result*=m;   
 return result;
}     
//显示2个数字
//x,y :起点坐标 
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~65536); 
void LCD_ShowNum(u8 x,u16 y,u16 num,u8 len,u8 size)
{          
 u8 t,temp;        
 for(t=0;t<len;t++)
 {
  temp=(num/mypow(10,len-t-1))%10;
   LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0);
 }
}
//显示字符串
//x,y:起点坐标 
//*p:字符串起始地址
//用16字体
void LCD_ShowString(u8 x,u16 y,const u8 *p)
{        
    while(*p!='\0')
    {      
        if(x>MAX_CHAR_POSX){x=0;y+=16;}
        if(y>MAX_CHAR_POSY){y=x=0;LCD_Clear(WHITE);}
        LCD_ShowChar(x,y,*p,16,0);
        x+=8;
        p++;
    } 
}


主函数代码如下:


#include <stm32f10x_lib.h>
#include "sys.h"
#include "usart.h"  
#include "delay.h"
#include "lcd.h"   
//STMSKY开发板 2.8寸液晶测试代码
//正点原子@深圳南山
//2009.12.31    
      
int main(void)
{
    u8 x="0";   
 Stm32_Clock_Init(9);//系统时钟设置
 delay_init(72);  //延时初始化
 uart_init(72,9600); //串口1初始化    
 LCD_Init();   //初始化液晶   
   while(1)
 {  
  switch(x)
  {
   case 0:LCD_Clear(YELLOW);break;
   case 1:LCD_Clear(GRAY);break;
   case 2:LCD_Clear(BLUE);break;
   case 3:LCD_Clear(RED);break;
   case 4:LCD_Clear(MAGENTA);break;
   case 5:LCD_Clear(GREEN);break;
   case 6:LCD_Clear(CYAN);break;
  }
  POINT_COLOR=RED;  
  LCD_ShowString(30,50,"STMSKY ^_^"); 
  LCD_ShowString(30,70,"2.8'LCD TEST"); 
  LCD_ShowString(30,90,"ATOM@HYW");
  LCD_ShowString(30,110,"2009/12/31");          
     x++;
  if(x==7)x=0;     
  delay_ms(1000); 
 } 
}


源码:


https://static.assets-stash.eet-china.com/album/old-resources/2009/12/31/3504b6a6-ad8d-4f74-945a-7ccb4f1b5096.rar


显示效果:


点击看大图


点击看大图


点击看大图


点击看大图


点击看大图


点击看大图


 


 


 


 


 


 


 


 


 


 


 


 


 

PARTNER CONTENT

文章评论6条评论)

登录后参与讨论

用户1503809 2011-6-9 16:21

你好,我想问一下那个地址脚Ax和基址的关系,就是说如果连接的是A1,地址怎么算,关键是这个计算不会

用户205979 2010-7-15 22:47

怎么联系你啊,可以留下你的QQ号吗?有些问题想请教一下

用户205979 2010-7-13 01:06

//在指定位置显示一个大字符 //30*60大小的 //num:0~9 //:/./C这三个字符 void TFT_ShowBigChar(u8 x,u16 y,u8 num) { u8 n,t; u8 temp; u8 t1,deadline; TFT_WR_CMD(0,0x2,x);//设置到原点 TFT_WR_CMD(1,0x3,y); TFT_WR_CMD(0,0x04,x+29);//结束列数(0~239) TFT_WR_CMD(1,0x05,y+59); //结束行数(0~319) if(num==':')t1=150; else if(num=='.')t1=165; else if(num=='C')t1=180; else t1=15*num; deadline=t1+15; TFT_WR_REG(0x0E); for(;t1

用户166298 2010-1-14 09:54

请问你LCD是什么型号的?

liujun6037_345432000 2010-1-12 19:04

那个的TFT液晶触摸屏是在广州买的,不是在淘宝上. 不过淘宝上也有很多卖的啊,你只要找找就能找到的了.

用户1041518 2010-1-9 11:43

hi,你好,请问“自制的STM32开发板(STM32F103RBT6)"这个是您的大作吧,能不能麻烦告诉我下tft的那个触摸屏在淘宝哪个地址买的啊。多谢啦!!!给你站内短信了,一直没回复,可能最近您比较忙吧。
相关推荐阅读
正点原子 2013-05-17 23:47
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十一章 战舰STM32开发板综合实验(标准例程终结篇)
   第六十一章 战舰STM32开发板综合实验        前面已经给大家讲了55个实例了,本章将设计一个综合实例,作为本指南的最后一个实验 ,该实验向大家展示了STM...
正点原子 2013-05-03 23:02
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十章 UCOSII实验3-消息队列、信号量集和软件定时器
   第六十章 UCOSII实验3-消息队列、信号量集和软件定时器   上一章,我们学习了UCOSII的信号量和邮箱的使用,本章,我们将学习消息队列、信号量集和软件定时器...
正点原子 2013-05-03 20:42
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
第五十七章 ENC28J60网络实验   本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块...
正点原子 2013-05-01 23:00
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十九章 UCOSII实验2-信号量和邮箱
第五十九章 UCOSII实验2-信号量和邮箱      上一章,我们学习了如何使用UCOSII,学习了UCOSII的任务调度,但是并没有用到任务间的同步与通信,本章我们将学习两个最基本的...
正点原子 2013-04-30 10:55
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十八章 UCOSII实验1-任务调度
  第五十八章 UCOSII实验1-任务调度      前面我们所有的例程都是跑的裸机程序(裸奔),从本章开始,我们将分3个章节向大家介绍UCOSII(实时多任务操作系...
正点原子 2013-04-26 23:16
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
 第五十七章 ENC28J60网络实验  本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块和uIP 1...
我要评论
6
9
关闭 站长推荐上一条 /1 下一条