标题: 求教STC8H8K64S开通DMA_SPI传输模式驱动TFT屏 [打印本页]

作者: 大石头    时间: 2025-4-12 11:57
标题: 求教STC8H8K64S开通DMA_SPI传输模式驱动TFT屏
   一块晶联讯3.5吋TFT屏,用STC8H8K64S开通了SPI模式驱动成功。速度比晶联讯公司提供的模拟SPI驱动快很多,想要再提高刷新率,就要开通DMA
模式了。手册上说STC8H8K64S支持DMA_SPI传输模式。但是我是小白不会弄,网上也少有可直接引用的例程(大多是STM32的)。所以肯请高手大佬帮我完善下面的程序。谢谢。


/*  开通SPI模式驱动TFT屏的串行程序:
  型号:JLX350-01901-BN、横屏;
  驱动 IC:ST7796S;

  解决Keil的OxFD_BUG
  1.使用HexEditor编辑Keil安装目录下的/keil/c51/bin/c51.exe文件,
      搜索80FBFD改成80FBFF,如果使用汇编则修改A51.exe.
  2.使用晓奇工作室出品的补丁程序ccKeilVxx.exe。下载后放在/keil/c51/bin/目录下运行即可。
  KeilC51 0xFD BUG补丁 ccKeilVxx.exe下载
*/
#include <STC8H.H>
#include "string.h"

#define    ulong  unsigned long
#define    uint  unsigned int
#define    uchar  unsigned char

//液晶屏IC 所需要的信号线的接口定义
sbit  C_S     =  P2^2;//液晶片选CS,P1.4为单片机SPI总线的SS引脚,通过MSTR位配置为IO模式
sbit  R_ESET =  P0^3; //液晶RESET引脚,接单片机IO引脚
sbit  C_D    =  P0^4;//液晶D/CX引脚,数据/命令控制,接单片机IO引脚
  //以下2个引脚的连接。因接单片机默认硬件SPI引脚,只需要在SPCTL中使能即可,不需程序中定义
//sbit        SDI        =        P2^3; 液晶SDI引脚,主机写到液晶,接单片机MOSI引脚P1.5
//sbit        SCL = P2^5; 液晶SCL时钟引脚,接单片机SCLK时钟引脚P1.7

#define red    0xf800  //定义红色
#define blue   0x001f  //定义蓝色
#define green  0x07e0   //定义绿色
#define white  0xffff   //定义白色

struct typFNT_GBK16
{
  char Index[2];//记录汉字的编码
        uchar Msk[32];//记录汉字的字模
}typFNT_GBK16;//字表结构体,16*16的汉字库

struct typFNT_GBK16 code F16x16[]= //逐行式,顺向

{
  "产",0x02,0x00,0x01,0x00,0x7f,0xfc,0x00,0x00,0x08,0x20,0x04,0x20,0x04,0x40,0x3f,0xfe, /* 116 */
       0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x80,0x00,
  "全",0x01,0x00,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x10,0x10,0x2f,0xe8,0xc1,0x06, /* 129 */
       0x01,0x00,0x01,0x00,0x1f,0xf0,0x01,0x00,0x01,0x00,0x01,0x00,0x7f,0xfc,0x00,0x00,
  "面",0x00,0x00,0xff,0xfe,0x02,0x00,0x02,0x00,0x04,0x00,0x3f,0xf8,0x24,0x48,0x24,0x48, /* 130 */
       0x27,0xc8,0x24,0x48,0x24,0x48,0x27,0xc8,0x24,0x48,0x24,0x48,0x3f,0xf8,0x20,0x08,
  "提",0x10,0x00,0x11,0xfc,0x11,0x04,0x11,0x04,0xfd,0xfc,0x11,0x04,0x11,0x04,0x15,0xfc, /* 131 */
       0x18,0x00,0x33,0xfe,0xd0,0x20,0x11,0x20,0x11,0x3c,0x11,0x20,0x52,0xa0,0x24,0x7e,
  "升",0x01,0x20,0x07,0xa0,0x3c,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0xff,0xfe, /* 132 */
       0x04,0x20,0x04,0x20,0x04,0x20,0x08,0x20,0x08,0x20,0x10,0x20,0x20,0x20,0x40,0x20,
  "新",0x10,0x00,0x08,0x04,0x7f,0x78,0x00,0x40,0x22,0x40,0x14,0x40,0xff,0x7e,0x08,0x48, /* 134 */
       0x08,0x48,0x7f,0x48,0x08,0x48,0x2a,0x48,0x49,0x48,0x88,0x88,0x28,0x88,0x11,0x08,
  "质",0x00,0x7c,0x3f,0xc0,0x20,0x40,0x20,0x40,0x3f,0xfe,0x20,0x40,0x20,0x40,0x27,0xfc, /* 135 */
       0x24,0x04,0x24,0x44,0x24,0x44,0x24,0x44,0x24,0xb4,0x41,0x08,0x46,0x04,0x98,0x02,
  "生",0x01,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x3f,0xfc,0x21,0x00,0x41,0x00,0x81,0x00, /* 136 */
       0x01,0x00,0x3f,0xf8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xff,0xfe,0x00,0x00,
  "力",0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x7f,0xf8,0x02,0x08,0x02,0x08,0x02,0x08, /* 137 */
       0x02,0x08,0x04,0x08,0x04,0x08,0x08,0x08,0x08,0x08,0x10,0x88,0x20,0x50,0x40,0x20,

};

//函数
void Delay_us(int value)////延时函数_us
  {
  while (value)
  value--;
  }

void Delay_ms(int value)////延时函数_ms
  {
  while (value--){
    Delay_us(999);
    value--;
    }
  }

void SPI_Init()
{
  P_SW1 = (P_SW1 & ~0x0c) | 0x04;    //SPI: SS(P2.2), MOSI(P2.3), MISO(P2.4), SCLK(P2.5)

  //SPI初始化
  SPDAT = 0;
  SPCTL = 0xd0;  //设置1101,0000;  SPI控制寄存器
  SPSTAT = 0xc0;  //标志位写1清零 (SPSTAT)SPI状态寄存器           //   
}

void LCD_Writ_Bus(char a)
{   //数据写入函数 8位
      C_S = 0;
      SPDAT = a;//开始传输
    while(!(SPSTAT&0x80));  // 等待SPIF = 1,传输完成  
    SPSTAT = 0xc0;   
      C_S = 1;
}  


void transfer_command(char cmd)//8 bit
{
      C_D = 0;
      LCD_Writ_Bus(cmd);
}

void transfer_data(char com_data)//8 bit
{
      C_D = 1;
      LCD_Writ_Bus(com_data);
}

void transfer_data_16(int a)//16位数据,分两次,每次送8位
{
      C_D = 1;
      LCD_Writ_Bus(a>>8);
    LCD_Writ_Bus(a);
}

void lcd_initial()
{
R_ESET=1;
Delay_ms(100);
R_ESET=0;
Delay_ms(200);
R_ESET=1;
Delay_ms(50);   
//************* Start Initial Sequence **********//  
transfer_command(0x11);    //Sleep Out
Delay_ms(200);
transfer_command(0xf0);   //
transfer_data(0xc3);      //enable command 2 part 1  
transfer_command(0xf0);
transfer_data(0x96);      //enable command 2 part 2
transfer_command(0x36);  //内存数据访问控制
transfer_data(0x28);     //0x28横屏显示,0x48竖屏显示; 0xe8,颠倒顺序
// transfer_data(0xe8); //
transfer_command(0x3a);  //16bit pixel
transfer_data(0x55);

transfer_command(0xb4);
transfer_data(0x01);

transfer_command(0xb7);
transfer_data(0xc6);

transfer_command(0xf0);
transfer_data(0x69);
Delay_ms(120);
  //transfer_command(0x21);       //IPS必须加这条指令  
transfer_command(0x29);  //Display ON   
transfer_command(0x2c);      // 写数据开始
}

//定义窗口坐标:开始坐标(XS,YS)以及窗口大小(x_total,y_total)
void lcd_address(int XS,int YS,int x_total,int y_total)
{
int XE,YE;  
XE=XS+x_total-1;
YE=YS+y_total-1;  
transfer_command(0x2a);   // 设置 X 开始及结束的地址
transfer_data_16(XS); // X 开始地址(16位)
transfer_data_16(XE); // X 结束地址(16位)

transfer_command(0x2b);   // 设置 Y 开始及结束的地址   
transfer_data_16(YS); // Y 开始地址(16位)
transfer_data_16(YE); // Y 结束地址(16位)

transfer_command(0x2c);      // 写数据开始
}

void mono_transfer_data_16(int mono_data,int font_color,int back_color)
{
int i;
for(i=0;i<8;i++)
{
   if(mono_data&0x80)
  {
   transfer_data_16(font_color); //当数据是1时,显示字体颜色
  }
  else
  {
   transfer_data_16(back_color); //当数据是0时,显示底色
  }
  mono_data<<=1;
}
}

//全屏显示一种颜色
void display_color(uint color_data)
{   
int i,j;
lcd_address(0,0,480,320);
for(i=0;i<480;i++)
   {
    for(j=0;j<320;j++)
      {
       transfer_data_16(color_data);     
      }
   }
}


// //显示结构体字库的16x16纯汉字
void display_hanzi_16x16(int x,int y,uchar *text,int font_color,int back_color)
{
uint j,k,m;// i,
uint address;
uint WordNum;//记录字表的字数
j = 0;
WordNum=sizeof(F16x16)/sizeof(typFNT_GBK16);//算出数组汉字的数量
while(text[j]>128)     // >0x7f即说明不是 ASCII 码字符 //'\0' 字符串结束标志
{

   address = 1;
    for(m=0;m<WordNum;m++)//遍历查表,寻出字模
    {
      if((F16x16[m].Index[0]==*(text))&&(F16x16[m].Index[1]==*(text+1)))//Index[0]指汉字的GBK编码的低8位,Index[1]是高8位  
        {
         address = j * 16;
         break;  
         }
    }
   if(address != 1)// 显示汉字                    
    {
      lcd_address(x,y,16,16);  

        for(k = 0; k <32; k++)               
          {         
            mono_transfer_data_16(F16x16[m].Msk[k],font_color,back_color);
            address++;
          }
       text+=2;         
    }
  else              //显示空白字符            
    {
      lcd_address(x,y,16,16);

       for(k = 0; k < 32; k++)               
        {
          mono_transfer_data_16(0x00,font_color,back_color);   
        }

      text+=2;
    }        
  x=x+16;
  if(x > 480-16)
    {
     x=0;  
     y+=18;
    }
}
}


void main(void)
{

  P0M0=0; P0M1=0; P1M0=0; P1M1=0;P2M0=0x00; P2M1=0x00;
  SPI_Init();//
  lcd_initial();
  display_color(blue);


    while(1)
      {
       display_hanzi_16x16(58, 6,"全面提升新质生产力", white, blue);
      }

  }  

作者: coody_sz    时间: 2025-4-12 14:19
STC论坛有例子的,都能读FLASH送TFT刷视频了。
作者: 大石头    时间: 2025-4-13 08:51
coody_sz 发表于 2025-4-12 14:19
STC论坛有例子的,都能读FLASH送TFT刷视频了。

谢谢指路。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1