STM32F405RGT6 驱动2寸的8080液晶感觉刷屏不够快

2019-07-20 14:03发布

STM32F405RGT6 最小系统板加一个2.0寸的液晶 因为没有FSMC所以用的是模拟8080的并口


#include "sys.h"
#include "ILI93xx.h"
#include "delay.h"
#include <stdio.h>
#include "font.h"
//#include <MM1_240.h>
//#include <MM3_240.h>
u16 POINT_COLOR=0x0000;        //画笔颜 {MOD}
u16 BACK_COLOR=0xFFFF;  //背景 {MOD}
//管理LCD重要参数
//默认为横屏
_lcd_dev lcddev;

void LCD_GPIO_Config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
       
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOB, ENABLE);//使能PORTA~E,PORTG时钟

       
        //GPIO初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_4|GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
       

  GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 |         GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化       
  LCD_RD_H;        //不读

}

static void LCD_Rst(void)
{                       
    LCD_RST_L;
    delay_ms(10);                                          
    LCD_RST_H;                          
    delay_ms(10);       
}
void WriteComm(u16 CMD)
{       
        LCD_CS_L;
        LCD_RS_L; //写地址
        LCD_WR_L;
        DATAOUT(CMD);
        LCD_WR_H;
        LCD_CS_H;
}
void WriteData(u16 tem_data)
{       
        LCD_CS_L;               
        LCD_RS_H; //写数据
        LCD_WR_L;
DATAOUT(tem_data);
        LCD_WR_H;
        LCD_CS_H;
}

void Write_long_Comm(u16 CMD)
{       
        LCD_CS_L;
        LCD_RS_L; //写地址
        LCD_WR_L;
        DATAOUT(CMD>>8);
        LCD_WR_H;
       
        LCD_WR_L;
        DATAOUT(CMD);
        LCD_WR_H;
       
        LCD_CS_H;
}
void Write_long_Data(u16 tem_data)
{       
        LCD_CS_L;               
        LCD_RS_H; //写数据
       
        LCD_WR_L;
  DATAOUT(tem_data>>8);
        LCD_WR_H;
       
        LCD_WR_L;
        DATAOUT(tem_data);
        LCD_WR_H;
       
        LCD_CS_H;
}

u16 Read_long_Data(void)
{       
        u16 tl,th;
        GPIOC->MODER=(GPIOC->MODER&0Xffff0000); //PC0-7  上拉输入
        GPIOC->ODR=(GPIOC->ODR&0Xff00);     //全部输出0
        LCD_CS_L;               
        LCD_RS_H;
       
        LCD_RD_L;
  th=DATAIN;
        LCD_RD_H;

        LCD_RD_L;
  tl=DATAIN;
        LCD_RD_H;
       
        LCD_CS_H;
        GPIOC->MODER=(GPIOC->MODER|0X00005555); //PC0-7  上拉输出
        GPIOC->ODR=(GPIOC->ODR|0X00FF);     //全部输出高
       
        return (th<<8)|tl;  
}
u16 ReadData(void)
{       
        u16 t;
        GPIOC->MODER=(GPIOC->MODER&0Xffff0000); //PC0-7  上拉输入
        GPIOC->ODR=(GPIOC->ODR&0Xff00);     //全部输出0
        LCD_CS_L;               
        LCD_RS_H;
       
        LCD_RD_L;
  t=DATAIN;
        LCD_CS_H;
       
        GPIOC->MODER=(GPIOC->MODER|0X00005555); //PC0-7  上拉输出
        GPIOC->ODR=(GPIOC->ODR|0X00FF);     //全部输出高
       
        return t;  
}
/**********************************************
Lcd初始化函数
***********************************************/
void Lcd_Initialize(void)
{       
        LCD_GPIO_Config();
       
        LCD_Rst();
        WriteComm(0x00);                                  
  lcddev.id=Read_long_Data(); //读器件ID测试用可以屏蔽
       
        LCD_WR_REG(0x00,0x0001);
        delay_ms(20);
        LCD_WR_REG(0x00,0x0000);
       

//************* Start Initial Sequence **********//
        if(lcddev.dir==0)
        {
        LCD_WR_REG(0x0001, 0x0000);         // 横屏
        }
        else if(lcddev.dir==1)
        {
         LCD_WR_REG(0x0001, 0x0100);        // 竖屏
        }
        LCD_WR_REG(0x0002, 0x0200);         // set 1 line inversion
        LCD_WR_REG(0x0003, 0x1028);         // set GRAM write direction and BGR=1.   
        LCD_WR_REG(0x0008, 0x0202);         // set the back porch and front porch
        LCD_WR_REG(0x0009, 0x0000);         // set non-display area refresh cycle ISC[3:0]
        LCD_WR_REG(0x000A, 0x0000);                // FMARK function
        LCD_WR_REG(0x000C, 0x0000);        // RGB interface setting
        LCD_WR_REG(0x000D, 0x0000);                // Frame marker Position
        LCD_WR_REG(0x0060, 0x2700);        // Gate Scan Line
        LCD_WR_REG(0x0061, 0x0001);         // NDL,VLE, REV
        LCD_WR_REG(0x006A, 0x0000);                  // set scrolling line
        delay_ms(10);   
//*************Power On sequence ****************//                                                     // Dis-charge capacitor power voltage
        LCD_WR_REG(0x0010, 0x1490);        // SAP, BT[3:0], AP, DSTB, SLP, STB
        LCD_WR_REG(0x0011, 0x0227);        // DC1[2:0], DC0[2:0], VC[2:0]
                        delay_ms(80);                                                             // Delay 50ms     
        LCD_WR_REG(0x0012, 0x008C);        // Internal reference voltage= Vci;
                        delay_ms(10);                                                             // Delay 50ms
        LCD_WR_REG(0x0013, 0x1900);        // Set VDV[4:0] for VCOM amplitude
        LCD_WR_REG(0x0029, 0x0029);        // Set VCM[5:0] for VCOMH
        LCD_WR_REG(0x002B, 0x000D);      // Set Frame Rate   
                        delay_ms(10);                                                        // Delay 50ms
        LCD_WR_REG(0x0020, 0x0000);        // GRAM horizontal Address
        LCD_WR_REG(0x0021, 0x0000);        // GRAM Vertical Address   
// ----------- Adjust the Gamma    Curve ----------//
        LCD_WR_REG(0x0030, 0x0000);
        LCD_WR_REG(0x0031, 0x0303);
        LCD_WR_REG(0x0032, 0x0102);
        LCD_WR_REG(0x0035, 0x0101);
        LCD_WR_REG(0x0036, 0x0008);
        LCD_WR_REG(0x0037, 0x0506);
        LCD_WR_REG(0x0038, 0x0404);
        LCD_WR_REG(0x0039, 0x0707);
        LCD_WR_REG(0x003C, 0x0101);
        LCD_WR_REG(0x003D, 0x0804);
//------------------ Set GRAM area ---------------//
        LCD_WR_REG(0x0050, 0x0000);         // Horizontal GRAM Start Address
        LCD_WR_REG(0x0051, 0x00EF);        // Horizontal GRAM End Address
        LCD_WR_REG(0x0052, 0x0000);         // Vertical GRAM Start Address
        LCD_WR_REG(0x0053, 0x013F);         // Vertical GRAM Start Address
        delay_ms(10);

        LCD_WR_REG(0x0007, 0x0133);         // 262K color and display ON

        delay_ms(10);
               
        LCD_BL=1;
                Lcd_Clear(White);
}
/******************************************
函数名:Lcd写命令函数
功能:向Lcd指定位置写入应有命令或数据
入口参数:Index 要寻址的寄存器地址
          ConfigTemp 写入的数据或命令值
******************************************/
void LCD_WR_REG(u16 Index,u16 CongfigTemp)
{
        Write_long_Comm(Index);
        Write_long_Data(CongfigTemp);
}
/************************************************
函数名:Lcd写开始函数
功能:控制Lcd控制引脚 执行写操作
************************************************/
void Lcd_WR_Start(void)
{
WriteComm(0x00);
WriteComm(0x22);
}
/*************************************************
函数名:Lcd光标起点定位函数
功能:指定320240液晶上的一点作为写数据的起始点
入口参数:x 坐标 0~239
          y 坐标 0~319
返回值:无
*************************************************/
void Lcd_SetCursor(u16 x,u16 y)
{
        //坐标调转
        if(lcddev.dir==0)//横屏
        {
        LCD_WR_REG(0x20,y);//水平坐标
        LCD_WR_REG(0x21,x);//垂直坐?
        }
  else if(lcddev.dir==1)//竖屏
        {
        LCD_WR_REG(0x20,x);//水平坐标
        LCD_WR_REG(0x21,y);//垂直坐?
        }         
}
void Lcd_SetGRAM(u16 x,u16 y)
{
        //坐标调转
        if(lcddev.dir==0)//横屏
        {
        LCD_WR_REG(0x0050,y);//水平 GRAM起始位置
        LCD_WR_REG(0x0052,x);//垂直GRAM起始位置
        }
  else if(lcddev.dir==1)//竖屏
        {
        LCD_WR_REG(0x0050,x);//水平 GRAM起始位置
        LCD_WR_REG(0x0052,y);//垂直GRAM起始位置        
        }         
}

//开始全屏写,设置地址
void Lcd_Start(void)
{  
        Lcd_SetCursor(0,0);     
        LCD_WR_REG(0x0050,0x00);//水平 GRAM起始位置
        LCD_WR_REG(0x0051,239);//水平GRAM终止位置
        LCD_WR_REG(0x0052,0x00);//垂直GRAM起始位置
        LCD_WR_REG(0x0053,319);//垂直GRAM终止位置   
        Lcd_WR_Start();
}
/**********************************************
函数名:Lcd全屏擦除函数
功能:将Lcd整屏擦为指定颜 {MOD}
入口参数:color 指定Lcd全屏颜 {MOD} RGB(5-6-5)
返回值:无
***********************************************/
void Lcd_Clear(u16 Color)
{
        u32 temp;
        Lcd_Start();
        for (temp = 0; temp < 76800; temp++)
        {
                Write_long_Data( Color);
        }
}

/******************************************
函数名:Lcd图像填充100*100
功能:向Lcd指定位置填充图像
入口参数:Index 要寻址的寄存器地址
          ConfigTemp 写入的数据或命令值
******************************************/
void LCD_Fill_Pic(u16 x, u16 y,u16 pic_H, u16 pic_V, const unsigned char* pic)
{
  unsigned long i;

//         WriteComm(0x36); //Set_address_mode
//         WriteData(0x0a); //横屏,从左下角开始,从左到右,从下到上
        Lcd_Start();
        for (i = 0; i < pic_H*pic_V*2; i++)
        {
//                j=pic[i];
//                j=j<<8;
//                j=j+pic[i+1];
        WriteData(pic[i]);
        }
//         WriteComm(0x36); //Set_address_mode
//         WriteData(0xaa);
}

void LCD_Fast_DrawPoint(u16 x, u16 y, u16 Color)
{

        Lcd_SetCursor(x,y);
        Lcd_SetGRAM(x,y);
  Lcd_WR_Start();
        Write_long_Data(Color);
}
u16 LCD_ReadPoint(u16 x,u16 y)
{
        if(x>=320||y>=240)return 0;        //超过了范围,直接返回               
        if(lcddev.dir==0)//横屏
        {
        Lcd_SetCursor(x,y);
        }
        else if(lcddev.dir==1)//竖屏
        {
  Lcd_SetCursor(x,y);
        }
        Lcd_WR_Start();
        return Read_long_Data();;
}

//在指定区域内填充单个颜 {MOD}
//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为ex-sx+1)*(ey-sy+1)   
//color:要填充的颜 {MOD}
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
{         
                        u16 i,j;
                        u16 xlen=0;

                xlen=ex-sx+1;         
                for(i=sy;i<=ey;i++)
                {
                         Lcd_SetCursor(sx,i);                                      //设置光标位置
            Lcd_SetGRAM(sx,i);                //设置GRAM位置
                        Lcd_WR_Start();                   //开始写
       
                        for(j=0;j<xlen;j++)Write_long_Data(color);        //显示颜 {MOD}             
                }
        }         



//在指定位置显示一个字符
//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>=240)return;                //超区域了
                        if((y-y0)==size)
                        {
                                y=y0;
                                x++;
                                if(x>=320)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:颜 {MOD}
//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);
        }
}
//显示数字,高位为0,还是显示
//x,y:起点坐标
//num:数值(0~999999999);         
//len:长度(即要显示的位数)
//size:字体大小
//mode:
//[7]:0,不填充;1,填充0.
//[6:1]:保留
//[0]:0,非叠加显示;1,叠加显示.
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode)
{  
        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)
                        {
                                if(mode&0X80)LCD_ShowChar(x+(size/2)*t,y,'0',size,mode&0X01);  
                                else LCD_ShowChar(x+(size/2)*t,y,' ',size,mode&0X01);  
                                continue;
                        }else enshow=1;
                          
                }
                 LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,mode&0X01);
        }
}
//显示字符串
//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++;
    }  
}


#ifndef __ILI93xx_H
#define __ILI93xx_H
#include "sys.h"

//LCD重要参数集
typedef struct  
{                                                                                    
        u16 width;                        //LCD 宽度
        u16 height;                        //LCD 高度
        u16 id;                                //LCD ID
        u8  dir;                        //横屏还是竖屏控制:0,竖屏;1,横屏。       
}_lcd_dev;           

extern _lcd_dev lcddev;        //管理LCD重要参数

extern u16  POINT_COLOR;//默认红 {MOD}   
extern u16  BACK_COLOR; //背景颜 {MOD}.默认为白 {MOD}

#define LCD_CS PBout(6)
#define LCD_RS PBout(7)
#define LCD_WR PBout(8)
#define LCD_RD PBout(9)
#define LCD_RST PBout(4)
#define LCD_BL PBout(5)

#define LCD_CS_L  GPIOB->BSRRH = GPIO_Pin_6;
#define LCD_RS_L  GPIOB->BSRRH = GPIO_Pin_7;
#define LCD_WR_L  GPIOB->BSRRH = GPIO_Pin_8;
#define LCD_RD_L  GPIOB->BSRRH = GPIO_Pin_9;
#define LCD_RST_L GPIOB->BSRRH = GPIO_Pin_4;

#define LCD_CS_H GPIOB->BSRRL = GPIO_Pin_6;
#define LCD_RS_H GPIOB->BSRRL= GPIO_Pin_7;
#define LCD_WR_H GPIOB->BSRRL = GPIO_Pin_8;
#define LCD_RD_H GPIOB->BSRRL = GPIO_Pin_9;
#define LCD_RST_H GPIOB->BSRRL = GPIO_Pin_4;

#define DATAOUT(LCD_DATA)    GPIOC->ODR=( GPIOC->ODR&0xff00)|(LCD_DATA&0x00ff);
#define DATAIN                GPIOC->IDR&0x00ff;   //数据输入       

//#define DATAOUTH(LCD_DATA)    GPIOC->BSRRL=( GPIOC->BSRRL)|(LCD_DATA&0x00ff);
//#define DATAOUTL(LCD_DATA)    GPIOC->BSRRH=( GPIOC->BSRRH)|(~(LCD_DATA&0x00ff));

//Lcd初始化及其低级控制函数

void LCD_GPIO_Config(void);
void Lcd_Configuration(void);
void DataToWrite(u16 data);
void Lcd_Initialize(void);
void LCD_WR_REG(u16 Index,u16 CongfigTemp);
void Lcd_WR_Start(void);
void Lcd_Clear(u16 Color);

void Lcd_SetCursor(u16 x,u16 y);
void Lcd_SetGRAM(u16 x,u16 y);
void Write_long_Data(u16 tem_data);
//Lcd高级控制函数
//void Lcd_ColorBox(u16 x,u16 y,u16 xLong,u16 yLong,u16 Color);

//u16 ssd1289_GetPoint(u16 x,u8 y);
void LCD_Fill_Pic(u16 x, u16 y,u16 pic_H, u16 pic_V, const unsigned char* pic);
//char Tiky_Button(char *filename,u16 x,u16 y);
void LCD_Fast_DrawPoint(u16 x, u16 y, u16 Color);
u16 LCD_ReadPoint(u16 x,u16 y);
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);

void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode);
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size);
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode);
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p);


#define White          0xFFFF
#define Black          0x0000
#define Blue           0x001F
#define Blue2          0x051F
#define Red            0xF800
#define Magenta        0xF81F
#define Green          0x07E0
#define Cyan           0x7FFF
#define Yellow         0xFFE0

#endif






友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。