找回密码
 立即注册
楼主: 浦江一水

基于 32G12K128实验箱V9.62_实验之TFT彩屏驱动, ILI9341

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:195
  • 最近打卡:2026-03-03 09:06:50
已绑定手机

1

主题

6

回帖

661

积分

高级会员

积分
661
发表于 2025-1-23 13:08:11 | 显示全部楼层
学习一下大佬的杰作!
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2026-03-03 15:33:30

52

主题

50

回帖

754

积分

高级会员

积分
754
发表于 2026-1-1 16:34:27 | 显示全部楼层
你好,又来麻烦你了,我看了你的画正弦波曲线,有点疑问咨询一下
n=0;y0=SIN[n++];
    for(i=0;i<150;i++)
    { //画正弦波形曲线
      y1=SIN[n];
      LCD_Line(10+i*2,y0,10+i*2+3,y1,14);
      y0=y1;
      n=n<49?n+1:0;
    }

一、  LCD_Line(10+i*2,y0,10+i*2+3,y1,14);语句里X1为什么是X0+3,不应该是+1吗?
二、n=0;y0=SIN[n++];执行完这个语句,n=1,进了for循环中第一个循环,y1=SIN[n];  ,第一个循环y1与y0都是一个数值SIN[1],这样做有具体意义吗,也就是第一个语句 n=0;y0=SIN[n];的时候是不是一样呢、
最后祝你2026年新年快乐

点评

首先这位朋友新年好! 很高兴你关注浏览本帖,并深入思考和提问. 简答一下,供参考: 一, +3是基于i*2考虑的,水平方向位移的宽度, 以确保每条线段首尾相接. 如果改为+1. 画线就会断开成虚线了. 二, n=0;y0=SIN[n  详情 回复 发表于 2026-1-2 08:59
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:780
  • 最近打卡:2026-03-07 08:12:52

31

主题

402

回帖

4861

积分

荣誉版主

积分
4861
发表于 2026-1-2 08:59:59 | 显示全部楼层
dong*** 发表于 2026-1-1 16:34
你好,又来麻烦你了,我看了你的画正弦波曲线,有点疑问咨询一下
n=0;y0=SIN[n++];
    for(i=0;i ...

首先这位朋友新年好!
很高兴你关注浏览本帖,并深入思考和提问.
简答一下,供参考:
一, +3是基于i*2考虑的,水平方向位移的宽度, 以确保每条线段首尾相接.
      如果改为+1. 画线就会断开成虚线了.
二, n=0;y0=SIN[n++], 就是y0=SIN[0], n是在执行此句之后再+1的,所以实际是:
y0=SIN[0],y1=SIN[1], ....  y0和y1是不相同的. 仔细想想,是不是?
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2026-03-03 15:33:30

52

主题

50

回帖

754

积分

高级会员

积分
754
发表于 2026-1-2 14:31:01 | 显示全部楼层
浦江*** 发表于 2026-1-2 08:59
首先这位朋友新年好!
很高兴你关注浏览本帖,并深入思考和提问.
简答一下,供参考:

非常感谢你的解答,以前stc单片机彩屏驱动是个短板,使用STC单片机驱动的例子很少,你的这两个例子,对普及STC单片机彩屏驱动非常大推动作用,而且一个IL9341,一个ST7789,非常好,非常好,非常感谢

点评

感谢你的认可. 也愿你学习实验顺利愉快. 有问题可随时交流,互相学习.  详情 回复 发表于 2026-1-2 16:31
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:780
  • 最近打卡:2026-03-07 08:12:52

31

主题

402

回帖

4861

积分

荣誉版主

积分
4861
发表于 2026-1-2 16:31:59 | 显示全部楼层
dong*** 发表于 2026-1-2 14:31
非常感谢你的解答,以前stc单片机彩屏驱动是个短板,使用STC单片机驱动的例子很少,你的这两个例子,对普 ...

感谢你的认可.
也愿你学习实验顺利愉快.
有问题可随时交流,互相学习.
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2026-03-03 15:33:30

52

主题

50

回帖

754

积分

高级会员

积分
754
发表于 2026-2-23 10:56:34 | 显示全部楼层
首先祝贺老师新年快乐,我在STM32单片机想显示32*32汉字,模仿你的24*24汉字显示函数,出现汉字显示不全,百思不得其解,函数如下:

void LCD_H32(unsigned int X,unsigned int Y, char *str,unsigned char Fcolor,unsigned char Bcolor)
{
  unsigned char C[3];
  uint16_t i,j,l,m,n,p,ZM;
  unsigned long HZM;
  l=strlen(str);       //strlen()求字符串长度函数
  for(i=0;i<l;i++)
  { /* 逐个显示字符串 */
    C[0]=str;C[1]=str[i+1];   //取汉字内码
    if(C[0]>160)                 //是汉字...
    { m=1;p=0;
      while(m!=0&&p<TotalHZ32)   /* 搜索汉字,若找到返m=0和指针p ,TotalHZ24定义汉字的数量*/
      { m=strncmp(C,HZ32M[p],2);//strncmp()比较两个字符串是否相等;
        if(m)p=p+1;
      }
{ if((HZM&0x800000)==0x800000) TFT_SEND_DATA16(COLOR[Fcolor]);/* 字模点为1显示前景色 */
      for(j=0;j<32;j++)
      { /* 循环写32行 */
        HZM = HZ32[p][j*4];           /* 取字模码 */
        HZM = HZM*256+(unsigned char)HZ32[p][j*4+1];
        HZM = HZM*256+(unsigned char)HZ32[p][j*4+2];
                                HZM = HZM*256+(unsigned char)HZ32[p][j*4+3];
        LCD_MoveTo(X+i*16,Y+j);       /* 字符左上角显示地址 */
        for(n=0;n<32;n++)             /* 汉字横向显示32点   */
        { if((HZM&0x800000)==0x800000) TFT_SEND_DATA16(COLOR[Fcolor]);/* 字模点为1显示前景色 */
          else                                                 /* 字模点为0显示原底色或背景色 */
          { if(Bcolor==80){ LCD_MoveTo(X+i*16+n,Y+j); }        /* 透明显示模式:仅做地址+1定位 */
            else  TFT_SEND_DATA16(COLOR[Bcolor]);                      /* 正常显示模式:背景色 */
          }
          HZM = HZM << 1;
        }                             /* 水平32点显示完毕 */
      }
      i++;
    }
    else
    { for(j=0;j<32;j++)
      { /* 写32行 */
        ZM=ASC32[C[0]-32][j*2];          /* 取字模码1 */
        ZM=ZM*256+ASC32[C[0]-32][j*2+1]; /* 取字模码2 */
        LCD_MoveTo(X+i*16,Y+j);          /* 定位左上角 */
        for(n=0;n<16;n++)
        { if((ZM&0x8000)==0x8000) TFT_SEND_DATA16(COLOR[Fcolor]);/* 字模点为1显示前景色 */
          else                                              /* 字模点为0显示原底色或背景色 */
          { if(Bcolor==80) { LCD_MoveTo(X+i*16+n,Y+j); }         /* 透明显示模式: 仅地址+1定位 */
            else TFT_SEND_DATA16(COLOR[Bcolor]);                 /* 正常显示模式:背景色 */
          }
          ZM = ZM << 1;
        } /* 水平12点显示完毕 */
      } /* 一个12*24点阵字符显示完毕  */
    } /* else_if */  
  }  /* 循环逐个显示字符串 */
}  /* H24()   */

再就是编译出现警告,显示这个函数strncmp(C,HZ32M[p],2);比较的不同类型数据,我将 unsigned char C[3];改成char C[3],虽然告警没了,但在这个语句if(C[0]>160)  前面有一个黄色警告,我百度一下因为C[0]是char型的最大127,这里永远为假,这个在怎么处理,前面加一个强制数据类型转换?虽然有警告,但能正常显示汉字,下图是32*32显示不全图片我找不到原因:问题找到了,这个语句的原因
{ if((HZM&0x800000)==0x800000) TFT_SEND_DATA16(COLOR[Fcolor]);/* 字模点为1显示前景色 */      这个800000是24位的,改成32位就行了
微信图片_20260223103308_12_6.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2026-03-03 15:33:30

52

主题

50

回帖

754

积分

高级会员

积分
754
发表于 2026-2-23 20:10:48 | 显示全部楼层
又来问你 一个问题,

/*****************************************************************************
* 函数:void LCD_LineV(u16 X, u16 Y,u16 W,u8 Color)
* 参数: 0原始 1:转90度 2:转180 3:转270度 (实验箱V9.62)
******************************************************************************/
void LCD_LineV(u16 X, u16 Y,u16 H,u8 Color) //画垂直线
{ u16 i;
  LCD_SetWindow(X,Y,X,Y+H);
  for(i=0;i<H;i++)LCD_WR_DAT_16Bit(COLOR[Color]); //连续画色点
  LCD_SetWindow(X,Y,LCD_W,LCD_H);  
}
这个函数是画垂直线函数,移植后只能画水平线,分析后,也只能画水平线,


我修改后,可以画垂线,(里面的子函数名有所修改),

/*****************************************************************************
* 函数:void LCD_LineV(u16 X, u16 Y,u16 W,u8 Color)画竖线
* 参数: X,Y:坐标,W:线高,Color:颜色
******************************************************************************/
void TFT_LineV(u16 X, u16 Y,u16 H,u8 Color)//画竖线
{ u16 i;
  TFT_SET_ADD(X,Y,X,Y+H);
  for(i=0;i<H;i++)
        {
                LCD_MoveTo(X,Y+i) ;
                TFT_SEND_DATA16(COLOR[Color]);  //连续画色点
        }
}

我不明白你的那个函数我什么可以画垂直线 ?

点评

这位朋友好! 好的,再来交流讨论一下: 上面的LCD_LineV()函数是一个画垂直线的函数,比较简单,一共三行: 第一行 LCD_SetWindow(X,Y,X,Y+H); 这是设置显示窗口区域. 这个区域水平方向只有一个点像素,垂直方向有H点像素  详情 回复 发表于 2026-2-24 10:02
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:780
  • 最近打卡:2026-03-07 08:12:52

31

主题

402

回帖

4861

积分

荣誉版主

积分
4861
发表于 2026-2-24 10:02:41 | 显示全部楼层
dong*** 发表于 2026-2-23 20:10
又来问你 一个问题,

/*****************************************************************************

这位朋友好! 好的,再来交流讨论一下:

上面的LCD_LineV()函数是一个画垂直线的函数,比较简单,一共三行:
第一行 LCD_SetWindow(X,Y,X,Y+H);
这是设置显示窗口区域. 这个区域水平方向只有一个点像素,垂直方向有H点像素,所以后继写入的数据只能沿垂直方向落点,因此只能画一条垂直线.
第二行 for(i=0;i<H;i++)LCD_WR_DAT_16Bit(COLOR[Color]); //连续画色点
这就是当显示窗口区域设定后,连续写入数据,画出H个点的.
第三行 这是将显示区域恢复到全屏,确保后续语句执行不限于此前的设置区域.(如果后续语句有重新设置显示区域的话,那么本句可省略)

如果说,你的移植后只能显示画水平线,可能是方向的设置问题了.

再来看看下面你修改后的函数:
第一行 TFT_SET_ADD(X,Y,X,Y+H);
顾名思义,是设置地址, 好像是在设置一个坐标点,但是参数好像是设置一个区域.(不知TFT_SET_ADD()函数是如何写的)
第二行,LCD_MoveTo(X,Y+i);是定坐标点, 如果你确定要每写入一个点时,都要先确定一下坐标点,那么第一行语句就是多余的了.
第三行,TFT_SEND_DATA16(COLOR[Color]);写入点数据, 这没问题.
总体看, 因为Y+i变化点是在垂直方向的,这也是一个画垂直线的函数,只是效率可能低了一点点.

最后一句话,"我什么可以画垂直线?", 大概是"我怎么可以画垂直线?"吧,
估计你遇到的问题是用垂直线函数仅画出了水平线,而没有真正画出垂直线. 注意一下有关屏幕初始化.
建议理解一下SetDIR()函数,结合实际使用屏的资料,弄清楚设置显示方向(实际是地址自动递增的方向)的具体数据(屏可能有差异).


另外,本贴给出的源码:有画水平线函数和垂直线函数两种, 都可以实验比较一下.
注意水平线函数是X+W, 垂直线函数是Y+H,方向有所不同.

/*****************************************************************************
* 函数:void LCD_LineH(u16 X, u16 Y,u16 W,u8 Color)   画水平线
* 参数: X,Y 起始坐标点. W 水平宽度, Color 点颜色号
******************************************************************************/
void LCD_LineH(u16 X, u16 Y,u16 W,u8 Color)
{ u16 i;
  LCD_SetWindow(X,Y,X+W,Y);  
  for(i=0;i<W;i++)LCD_WR_DAT_16Bit(COLOR[Color]); //连续画色点
  LCD_SetWindow(X,Y,LCD_W,LCD_H);  
}
/*****************************************************************************
* 函数:void LCD_LineV(u16 X, u16 Y,u16 H,u8 Color)  画垂直线
* 参数: X,Y 起始坐标点. H 垂直高度, Color 点颜色号
******************************************************************************/
void LCD_LineV(u16 X, u16 Y,u16 H,u8 Color)
{ u16 i;
  LCD_SetWindow(X,Y,X,Y+H);
  for(i=0;i<H;i++)LCD_WR_DAT_16Bit(COLOR[Color]); //连续画色点
  LCD_SetWindow(X,Y,LCD_W,LCD_H);  
}

祝你实验顺利愉快!
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:115
  • 最近打卡:2026-03-03 15:33:30

52

主题

50

回帖

754

积分

高级会员

积分
754
发表于 2026-2-24 12:34:10 | 显示全部楼层
浦江*** 发表于 2026-2-24 10:02
这位朋友好! 好的,再来交流讨论一下:

上面的LCD_LineV()函数是一个画垂直线的函数,比较简单,一共三行:

你好,我理解的意思是,第一行 LCD_SetWindow(X,Y,X,Y+H);设置显示区域是一条竖线,
第二行 for(i=0;i<H;i++)LCD_WR_DAT_16Bit(COLOR[Color]); 的连续画点,
只能在这个区域,超过这个区域坐标Y值是可以自动加1的,

这样的话,我看看LCD_SetWindow(X,Y,X,Y+H);与TFT_SET_ADD(X,Y,X,Y+H);有什么不同,为什么你的Y可以加,我的却不能自加。



刚才我看了看问题找到了,我的TFT_SET_ADD(X,Y,X,Y+H)函数

void TFT_SET_ADD(unsigned int X,unsigned  int Y,unsigned int X_END,unsigned int Y_END)
{       
                TFT_SEND_CMD(0x2A);     //窗口地址横向                        
    TFT_SEND_DATA16(X);//start column   
    TFT_SEND_DATA(X_END);//start column
                TFT_SEND_CMD(0x2B);     //窗口地址纵向                     
    TFT_SEND_DATA16(Y);                //start row   
    TFT_SEND_DATA16(Y_END);                //start row
    TFT_SEND_CMD(0x2C);     //写入数据   
}第三行TFT_SEND_DATA少写个16,变成只传送8位,非常感谢你的解答

点评

第一行理解为"设置显示区域是一条竖线"也是对的. 其实质是设置一个矩形区域,因为X水平方向的宽度是1, 那么就相当于,区域就是垂直的一条线了. "只能在这个区域,超过这个区域坐标Y值是可以自动加1的", 我的理解是,  详情 回复 发表于 2026-2-24 13:19
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:780
  • 最近打卡:2026-03-07 08:12:52

31

主题

402

回帖

4861

积分

荣誉版主

积分
4861
发表于 2026-2-24 13:19:23 | 显示全部楼层
dong*** 发表于 2026-2-24 12:34
你好,我理解的意思是,第一行 LCD_SetWindow(X,Y,X,Y+H);设置显示区域是一条竖线,
第二行 for(i=0;i ...

第一行理解为"设置显示区域是一条竖线"也是对的.
其实质是设置一个矩形区域,因为X水平方向的宽度是1, 那么就相当于,区域就是垂直的一条线了.
"只能在这个区域,超过这个区域坐标Y值是可以自动加1的",
我的理解是, 在X水平方向地址是自动加一的, 但是到设置X的边界了, 要换行了,Y才被迫加1.

画垂直线,两种方法都可以的:

一种是我所写的原函数, 先定一个宽度为1的区域,高度就是线的长度, 设定后的初始坐标是在左上角,也就是顶端了, 然后后面连续写入色点数据, (因为写入一个色点数据后,宽度就到了,被迫换行,好像是Y自动加1),这样效率比较高.

另一种就入你修改的函数, 每次要写入一个色点数据时,先MoveTo, 就是定一个坐标点, 只要你定坐标的函数是正确有效的, 那么每一个点都是落在你指定的位置上, X没变,Y+i在变, 那么就是一条垂直线了. 这种方法,效率稍稍低一些, 而且前面的TFT_SET_ADD(X,Y,X,Y+H)是不需要的.
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-7 17:04 , Processed in 0.122310 second(s), 97 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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