请选择 进入手机版 | 继续访问电脑版
搜索
查看: 2709|回复: 5

[分享] 【STM32G491试用】+LC驱动240*240LCD

[复制链接]

该用户从未签到

14

主题

237

帖子

3

蝴蝶豆

金牌会员

最后登录
2023-1-28
发表于 2021-3-13 10:50:41 | 显示全部楼层 |阅读模式
之前那个G491的SDK没下好,然后我们就中断了LCD的显示。今天我们重新拾起来,点亮第一个LCD!
240*240的LCD在智能穿戴设备上用,还是很不错的。而且由于屏幕尺寸小,看起来细腻些,颗粒感少了许多!
我们这款LCD的芯片是ST7789,无触摸,仅1.3寸。Nucleo 有ardunio接口及引出所以引脚的排针,但是多位这、个懒人来说,我还是喜欢,直接把LCD插座ardunio的座子上。ST7789支持2种驱动方式:8080、RGB、3线制SPI、4线制SPI.我们采用模拟4线制SPI的方式来驱动。
我们来看下LCD与板子的连接:

A1.png

STM32CUBEMX 对应LCD驱动引脚的配置:
A2.png
其中用于VCC 和GND的2个引脚,我分别加了上拉和下拉!
函数中,模拟SPI写LCD,这里没用到读取,硬件上也未连接:
我们看下它的必要引脚及时序图:
A3.png
A4png.png

单个写入函数:
  1. /******************************************************************************
  2.       函数说明:LCD串行数据写入函数
  3.       入口数据:dat  要写入的串行数据
  4.       返回值:  无
  5. ******************************************************************************/
  6. void LCD_Writ_Bus(u8 dat)
  7. {       
  8.         u8 i;
  9.         for(i=0;i<8;i++)
  10.         {                          
  11.                 LCD_SCLK_Clr();
  12.                 if(dat&0x80)
  13.                 {
  14.                    LCD_MOSI_Set();
  15.                 }
  16.                 else
  17.                 {
  18.                    LCD_MOSI_Clr();
  19.                 }
  20.                 LCD_SCLK_Set();
  21.                 dat<<=1;
  22.         }       
  23. }
复制代码
写命令及写数据函数(默认状态为写数据,也就是DC引脚一直为高,当写命令是置低,写完后再置高):
  1. /******************************************************************************
  2.       函数说明:LCD写入数据
  3.       入口数据:dat 写入的数据
  4.       返回值:  无
  5. ******************************************************************************/
  6. void LCD_WR_DATA8(u8 dat)
  7. {
  8.         LCD_Writ_Bus(dat);
  9. }


  10. /******************************************************************************
  11.       函数说明:LCD写入数据
  12.       入口数据:dat 写入的数据
  13.       返回值:  无
  14. ******************************************************************************/
  15. void LCD_WR_DATA(u16 dat)
  16. {
  17.         LCD_Writ_Bus(dat>>8);
  18.         LCD_Writ_Bus(dat);
  19. }


  20. /******************************************************************************
  21.       函数说明:LCD写入命令
  22.       入口数据:dat 写入的命令
  23.       返回值:  无
  24. ******************************************************************************/
  25. void LCD_WR_REG(u8 dat)
  26. {
  27.         LCD_DC_Clr();//写命令
  28.         LCD_Writ_Bus(dat);
  29.         LCD_DC_Set();//写数据
  30. }
复制代码



由于LCD电源也是引脚模拟的,为了稳定运行,上电后要延时一会:
  1. void LCD_GPIO_Init(void)
  2. {
  3.         //其余全部置高
  4.         LCD_SCLK_Set();
  5.         LCD_MOSI_Set();
  6.         LCD_RES_Set();
  7.         LCD_DC_Set();
  8.         LCD_BLK_Set();
  9.         //初始化打开电源
  10.         LCD_VCC_Set();
  11.         LCD_GND_Clr();
  12.         //延时,保证充分上电
  13.         delay_ms(1000);
  14. }
复制代码
其余的LCD操作相关函数:
  1. /******************************************************************************
  2.       函数说明:设置起始和结束地址
  3.       入口数据:x1,x2 设置列的起始和结束地址
  4.                 y1,y2 设置行的起始和结束地址
  5.       返回值:  无
  6. ******************************************************************************/
  7. void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
  8. {
  9.         if(USE_HORIZONTAL==0)
  10.         {
  11.                 LCD_WR_REG(0x2a);//列地址设置
  12.                 LCD_WR_DATA(x1);
  13.                 LCD_WR_DATA(x2);
  14.                 LCD_WR_REG(0x2b);//行地址设置
  15.                 LCD_WR_DATA(y1);
  16.                 LCD_WR_DATA(y2);
  17.                 LCD_WR_REG(0x2c);//储存器写
  18.         }
  19.         else if(USE_HORIZONTAL==1)
  20.         {
  21.                 LCD_WR_REG(0x2a);//列地址设置
  22.                 LCD_WR_DATA(x1);
  23.                 LCD_WR_DATA(x2);
  24.                 LCD_WR_REG(0x2b);//行地址设置
  25.                 LCD_WR_DATA(y1+80);
  26.                 LCD_WR_DATA(y2+80);
  27.                 LCD_WR_REG(0x2c);//储存器写
  28.         }
  29.         else if(USE_HORIZONTAL==2)
  30.         {
  31.                 LCD_WR_REG(0x2a);//列地址设置
  32.                 LCD_WR_DATA(x1);
  33.                 LCD_WR_DATA(x2);
  34.                 LCD_WR_REG(0x2b);//行地址设置
  35.                 LCD_WR_DATA(y1);
  36.                 LCD_WR_DATA(y2);
  37.                 LCD_WR_REG(0x2c);//储存器写
  38.         }
  39.         else
  40.         {
  41.                 LCD_WR_REG(0x2a);//列地址设置
  42.                 LCD_WR_DATA(x1+80);
  43.                 LCD_WR_DATA(x2+80);
  44.                 LCD_WR_REG(0x2b);//行地址设置
  45.                 LCD_WR_DATA(y1);
  46.                 LCD_WR_DATA(y2);
  47.                 LCD_WR_REG(0x2c);//储存器写
  48.         }
  49. }

  50. void LCD_Init(void)
  51. {
  52.         LCD_GPIO_Init();//初始化GPIO
  53.        
  54.         LCD_RES_Clr();//复位
  55.         delay_ms(100);
  56.         LCD_RES_Set();
  57.         delay_ms(100);
  58.        
  59.         LCD_BLK_Set();//打开背光
  60.   delay_ms(100);
  61.        
  62.         //************* Start Initial Sequence **********//
  63.         LCD_WR_REG(0x11); //Sleep out
  64.         delay_ms(120);              //Delay 120ms
  65.         //************* Start Initial Sequence **********//
  66.         LCD_WR_REG(0x36);
  67.         if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
  68.         else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
  69.         else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
  70.         else LCD_WR_DATA8(0xA0);

  71.         LCD_WR_REG(0x3A);
  72.         LCD_WR_DATA8(0x05);

  73.         LCD_WR_REG(0xB2);
  74.         LCD_WR_DATA8(0x0C);
  75.         LCD_WR_DATA8(0x0C);
  76.         LCD_WR_DATA8(0x00);
  77.         LCD_WR_DATA8(0x33);
  78.         LCD_WR_DATA8(0x33);

  79.         LCD_WR_REG(0xB7);
  80.         LCD_WR_DATA8(0x35);  

  81.         LCD_WR_REG(0xBB);
  82.         LCD_WR_DATA8(0x19);

  83.         LCD_WR_REG(0xC0);
  84.         LCD_WR_DATA8(0x2C);

  85.         LCD_WR_REG(0xC2);
  86.         LCD_WR_DATA8(0x01);

  87.         LCD_WR_REG(0xC3);
  88.         LCD_WR_DATA8(0x12);   

  89.         LCD_WR_REG(0xC4);
  90.         LCD_WR_DATA8(0x20);  

  91.         LCD_WR_REG(0xC6);
  92.         LCD_WR_DATA8(0x0F);   

  93.         LCD_WR_REG(0xD0);
  94.         LCD_WR_DATA8(0xA4);
  95.         LCD_WR_DATA8(0xA1);

  96.         LCD_WR_REG(0xE0);
  97.         LCD_WR_DATA8(0xD0);
  98.         LCD_WR_DATA8(0x04);
  99.         LCD_WR_DATA8(0x0D);
  100.         LCD_WR_DATA8(0x11);
  101.         LCD_WR_DATA8(0x13);
  102.         LCD_WR_DATA8(0x2B);
  103.         LCD_WR_DATA8(0x3F);
  104.         LCD_WR_DATA8(0x54);
  105.         LCD_WR_DATA8(0x4C);
  106.         LCD_WR_DATA8(0x18);
  107.         LCD_WR_DATA8(0x0D);
  108.         LCD_WR_DATA8(0x0B);
  109.         LCD_WR_DATA8(0x1F);
  110.         LCD_WR_DATA8(0x23);

  111.         LCD_WR_REG(0xE1);
  112.         LCD_WR_DATA8(0xD0);
  113.         LCD_WR_DATA8(0x04);
  114.         LCD_WR_DATA8(0x0C);
  115.         LCD_WR_DATA8(0x11);
  116.         LCD_WR_DATA8(0x13);
  117.         LCD_WR_DATA8(0x2C);
  118.         LCD_WR_DATA8(0x3F);
  119.         LCD_WR_DATA8(0x44);
  120.         LCD_WR_DATA8(0x51);
  121.         LCD_WR_DATA8(0x2F);
  122.         LCD_WR_DATA8(0x1F);
  123.         LCD_WR_DATA8(0x1F);
  124.         LCD_WR_DATA8(0x20);
  125.         LCD_WR_DATA8(0x23);
  126.         LCD_WR_REG(0x21);

  127.         LCD_WR_REG(0x29);
  128. }
复制代码
LCD具体应用函数:
  1. /******************************************************************************
  2.       函数说明:在指定区域填充颜色
  3.       入口数据:xsta,ysta   起始坐标
  4.                 xend,yend   终止坐标
  5.                                                                 color       要填充的颜色
  6.       返回值:  无
  7. ******************************************************************************/
  8. void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
  9. {         
  10.         u16 i,j;
  11.         LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
  12.         for(i=ysta;i<yend;i++)
  13.         {                                                                                                                           
  14.                 for(j=xsta;j<xend;j++)
  15.                 {
  16.                         LCD_WR_DATA(color);
  17.                 }
  18.         }                                                       
  19. }

  20. /******************************************************************************
  21.       函数说明:在指定位置画点
  22.       入口数据:x,y 画点坐标
  23.                 color 点的颜色
  24.       返回值:  无
  25. ******************************************************************************/
  26. void LCD_DrawPoint(u16 x,u16 y,u16 color)
  27. {
  28.         LCD_Address_Set(x,y,x,y);//设置光标位置
  29.         LCD_WR_DATA(color);
  30. }


  31. /******************************************************************************
  32.       函数说明:画线
  33.       入口数据:x1,y1   起始坐标
  34.                 x2,y2   终止坐标
  35.                 color   线的颜色
  36.       返回值:  无
  37. ******************************************************************************/
  38. void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
  39. {
  40.         u16 t;
  41.         int xerr=0,yerr=0,delta_x,delta_y,distance;
  42.         int incx,incy,uRow,uCol;
  43.         delta_x=x2-x1; //计算坐标增量
  44.         delta_y=y2-y1;
  45.         uRow=x1;//画线起点坐标
  46.         uCol=y1;
  47.         if(delta_x>0)incx=1; //设置单步方向
  48.         else if (delta_x==0)incx=0;//垂直线
  49.         else {incx=-1;delta_x=-delta_x;}
  50.         if(delta_y>0)incy=1;
  51.         else if (delta_y==0)incy=0;//水平线
  52.         else {incy=-1;delta_y=-delta_x;}
  53.         if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
  54.         else distance=delta_y;
  55.         for(t=0;t<distance+1;t++)
  56.         {
  57.                 LCD_DrawPoint(uRow,uCol,color);//画点
  58.                 xerr+=delta_x;
  59.                 yerr+=delta_y;
  60.                 if(xerr>distance)
  61.                 {
  62.                         xerr-=distance;
  63.                         uRow+=incx;
  64.                 }
  65.                 if(yerr>distance)
  66.                 {
  67.                         yerr-=distance;
  68.                         uCol+=incy;
  69.                 }
  70.         }
  71. }


  72. /******************************************************************************
  73.       函数说明:画矩形
  74.       入口数据:x1,y1   起始坐标
  75.                 x2,y2   终止坐标
  76.                 color   矩形的颜色
  77.       返回值:  无
  78. ******************************************************************************/
  79. void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
  80. {
  81.         LCD_DrawLine(x1,y1,x2,y1,color);
  82.         LCD_DrawLine(x1,y1,x1,y2,color);
  83.         LCD_DrawLine(x1,y2,x2,y2,color);
  84.         LCD_DrawLine(x2,y1,x2,y2,color);
  85. }


  86. /******************************************************************************
  87.       函数说明:画圆
  88.       入口数据:x0,y0   圆心坐标
  89.                 r       半径
  90.                 color   圆的颜色
  91.       返回值:  无
  92. ******************************************************************************/
  93. void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color)
  94. {
  95.         int a,b;
  96.         a=0;b=r;          
  97.         while(a<=b)
  98.         {
  99.                 LCD_DrawPoint(x0-b,y0-a,color);             //3           
  100.                 LCD_DrawPoint(x0+b,y0-a,color);             //0           
  101.                 LCD_DrawPoint(x0-a,y0+b,color);             //1               
  102.                 LCD_DrawPoint(x0-a,y0-b,color);             //2            
  103.                 LCD_DrawPoint(x0+b,y0+a,color);             //4               
  104.                 LCD_DrawPoint(x0+a,y0-b,color);             //5
  105.                 LCD_DrawPoint(x0+a,y0+b,color);             //6
  106.                 LCD_DrawPoint(x0-b,y0+a,color);             //7
  107.                 a++;
  108.                 if((a*a+b*b)>(r*r))//判断要画的点是否过远
  109.                 {
  110.                         b--;
  111.                 }
  112.         }
  113. }

  114. /******************************************************************************
  115.       函数说明:显示汉字串
  116.       入口数据:x,y显示坐标
  117.                 *s 要显示的汉字串
  118.                 fc 字的颜色
  119.                 bc 字的背景色
  120.                 sizey 字号 可选 16 24 32
  121.                 mode:  0非叠加模式  1叠加模式
  122.       返回值:  无
  123. ******************************************************************************/
  124. void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  125. {
  126.         while(*s!=0)
  127.         {
  128.                 if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
  129.                 else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
  130.                 else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
  131.                 else return;
  132.                 s+=2;
  133.                 x+=sizey;
  134.         }
  135. }

  136. /******************************************************************************
  137.       函数说明:显示单个16x16汉字
  138.       入口数据:x,y显示坐标
  139.                 *s 要显示的汉字
  140.                 fc 字的颜色
  141.                 bc 字的背景色
  142.                 sizey 字号
  143.                 mode:  0非叠加模式  1叠加模式
  144.       返回值:  无
  145. ******************************************************************************/
  146. void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  147. {
  148.         u8 i,j;
  149.         u16 k;
  150.         u16 HZnum;//汉字数目
  151.         u16 TypefaceNum;//一个字符所占字节大小
  152.         u16 x0=x;
  153.         TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
  154.                                   //也建议用户使用这样大小的字,否则显示容易出问题!
  155.         HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);        //统计汉字数目
  156.         for(k=0;k<HZnum;k++)
  157.         {
  158.                 if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1)))
  159.                 {        
  160.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  161.                         for(i=0;i<TypefaceNum;i++)
  162.                         {
  163.                                 for(j=0;j<8;j++)
  164.                                 {       
  165.                                         if(!mode)//非叠加方式
  166.                                         {
  167.                                                 if(tfont16[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
  168.                                                 else LCD_WR_DATA(bc);
  169.                                         }
  170.                                         else//叠加方式
  171.                                         {
  172.                                                 if(tfont16[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  173.                                                 x++;
  174.                                                 if((x-x0)==sizey)
  175.                                                 {
  176.                                                         x=x0;
  177.                                                         y++;
  178.                                                         break;
  179.                                                 }
  180.                                         }
  181.                                 }
  182.                         }
  183.                 }                                         
  184.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  185.         }
  186. }


  187. /******************************************************************************
  188.       函数说明:显示单个24x24汉字
  189.       入口数据:x,y显示坐标
  190.                 *s 要显示的汉字
  191.                 fc 字的颜色
  192.                 bc 字的背景色
  193.                 sizey 字号
  194.                 mode:  0非叠加模式  1叠加模式
  195.       返回值:  无
  196. ******************************************************************************/
  197. void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  198. {
  199.         u8 i,j;
  200.         u16 k;
  201.         u16 HZnum;//汉字数目
  202.         u16 TypefaceNum;//一个字符所占字节大小
  203.         u16 x0=x;
  204.         TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
  205.                                   //也建议用户使用这样大小的字,否则显示容易出问题!
  206.         HZnum=sizeof(tfont24)/sizeof(typFNT_GB24);        //统计汉字数目
  207.         for(k=0;k<HZnum;k++)
  208.         {
  209.                 if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1)))
  210.                 {        
  211.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  212.                         for(i=0;i<TypefaceNum;i++)
  213.                         {
  214.                                 for(j=0;j<8;j++)
  215.                                 {       
  216.                                         if(!mode)//非叠加方式
  217.                                         {
  218.                                                 if(tfont24[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
  219.                                                 else LCD_WR_DATA(bc);
  220.                                         }
  221.                                         else//叠加方式
  222.                                         {
  223.                                                 if(tfont24[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  224.                                                 x++;
  225.                                                 if((x-x0)==sizey)
  226.                                                 {
  227.                                                         x=x0;
  228.                                                         y++;
  229.                                                         break;
  230.                                                 }
  231.                                         }
  232.                                 }
  233.                         }
  234.                 }                                         
  235.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  236.         }
  237. }

  238. /******************************************************************************
  239.       函数说明:显示单个32x32汉字
  240.       入口数据:x,y显示坐标
  241.                 *s 要显示的汉字
  242.                 fc 字的颜色
  243.                 bc 字的背景色
  244.                 sizey 字号
  245.                 mode:  0非叠加模式  1叠加模式
  246.       返回值:  无
  247. ******************************************************************************/
  248. void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
  249. {
  250.         u8 i,j;
  251.         u16 k;
  252.         u16 HZnum;//汉字数目
  253.         u16 TypefaceNum;//一个字符所占字节大小
  254.         u16 x0=x;
  255.         TypefaceNum=sizey/8*sizey;//此算法只适用于字宽等于字高,且字高是8的倍数的字,
  256.                                   //也建议用户使用这样大小的字,否则显示容易出问题!
  257.         HZnum=sizeof(tfont32)/sizeof(typFNT_GB32);        //统计汉字数目
  258.         for(k=0;k<HZnum;k++)
  259.         {
  260.                 if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1)))
  261.                 {        
  262.                         LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
  263.                         for(i=0;i<TypefaceNum;i++)
  264.                         {
  265.                                 for(j=0;j<8;j++)
  266.                                 {       
  267.                                         if(!mode)//非叠加方式
  268.                                         {
  269.                                                 if(tfont32[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
  270.                                                 else LCD_WR_DATA(bc);
  271.                                         }
  272.                                         else//叠加方式
  273.                                         {
  274.                                                 if(tfont32[k].Msk[i]&(0x01<<j))        LCD_DrawPoint(x,y,fc);//画一个点
  275.                                                 x++;
  276.                                                 if((x-x0)==sizey)
  277.                                                 {
  278.                                                         x=x0;
  279.                                                         y++;
  280.                                                         break;
  281.                                                 }
  282.                                         }
  283.                                 }
  284.                         }
  285.                 }                                         
  286.                 continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
  287.         }
  288. }


  289. /******************************************************************************
  290.       函数说明:显示单个字符
  291.       入口数据:x,y显示坐标
  292.                 num 要显示的字符
  293.                 fc 字的颜色
  294.                 bc 字的背景色
  295.                 sizey 字号
  296.                 mode:  0非叠加模式  1叠加模式
  297.       返回值:  无
  298. ******************************************************************************/
  299. void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
  300. {
  301.         u8 temp,sizex,t;
  302.         u16 i,TypefaceNum;//一个字符所占字节大小
  303.         u16 x0=x;
  304.         sizex=sizey/2;
  305.         TypefaceNum=sizex/8*sizey;
  306.         num=num-' ';    //得到偏移后的值
  307.         LCD_Address_Set(x,y,x+sizex-1,y+sizey-1);  //设置光标位置
  308.         for(i=0;i<TypefaceNum;i++)
  309.         {
  310.                 if(sizey==16)temp=ascii_1608[num][i];                       //调用8x16字体
  311.                 else if(sizey==32)temp=ascii_3216[num][i];                 //调用16x32字体
  312.                 else return;
  313.                 for(t=0;t<8;t++)
  314.                 {
  315.                         if(!mode)//非叠加模式
  316.                         {
  317.                                 if(temp&(0x01<<t))LCD_WR_DATA(fc);
  318.                                 else LCD_WR_DATA(bc);
  319.                         }
  320.                         else//叠加模式
  321.                         {
  322.                                 if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
  323.                                 x++;
  324.                                 if((x-x0)==sizex)
  325.                                 {
  326.                                         x=x0;
  327.                                         y++;
  328.                                         break;
  329.                                 }
  330.                         }
  331.                 }
  332.         }                      
  333. }


  334. /******************************************************************************
  335.       函数说明:显示字符串
  336.       入口数据:x,y显示坐标
  337.                 *p 要显示的字符串
  338.                 fc 字的颜色
  339.                 bc 字的背景色
  340.                 sizey 字号
  341.                 mode:  0非叠加模式  1叠加模式
  342.       返回值:  无
  343. ******************************************************************************/
  344. void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
  345. {         
  346.         while(*p!='\0')
  347.         {      
  348.                 LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
  349.                 x+=sizey/2;
  350.                 p++;
  351.         }  
  352. }


  353. /******************************************************************************
  354.       函数说明:显示数字
  355.       入口数据:m底数,n指数
  356.       返回值:  无
  357. ******************************************************************************/
  358. u32 mypow(u8 m,u8 n)
  359. {
  360.         u32 result=1;         
  361.         while(n--)result*=m;
  362.         return result;
  363. }


  364. /******************************************************************************
  365.       函数说明:显示整数变量
  366.       入口数据:x,y显示坐标
  367.                 num 要显示整数变量
  368.                 len 要显示的位数
  369.                 fc 字的颜色
  370.                 bc 字的背景色
  371.                 sizey 字号
  372.       返回值:  无
  373. ******************************************************************************/
  374. void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey)
  375. {                
  376.         u8 t,temp;
  377.         u8 enshow=0;
  378.         u8 sizex=sizey/2;
  379.         for(t=0;t<len;t++)
  380.         {
  381.                 temp=(num/mypow(10,len-t-1))%10;
  382.                 if(enshow==0&&t<(len-1))
  383.                 {
  384.                         if(temp==0)
  385.                         {
  386.                                 LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);
  387.                                 continue;
  388.                         }else enshow=1;
  389.                           
  390.                 }
  391.                  LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
  392.         }
  393. }


  394. /******************************************************************************
  395.       函数说明:显示两位小数变量
  396.       入口数据:x,y显示坐标
  397.                 num 要显示小数变量
  398.                 len 要显示的位数
  399.                 fc 字的颜色
  400.                 bc 字的背景色
  401.                 sizey 字号
  402.       返回值:  无
  403. ******************************************************************************/
  404. void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey)
  405. {                
  406.         u8 t,temp,sizex;
  407.         u16 num1;
  408.         sizex=sizey/2;
  409.         num1=num*100;
  410.         for(t=0;t<len;t++)
  411.         {
  412.                 temp=(num1/mypow(10,len-t-1))%10;
  413.                 if(t==(len-2))
  414.                 {
  415.                         LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0);
  416.                         t++;
  417.                         len+=1;
  418.                 }
  419.                  LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
  420.         }
  421. }


  422. /******************************************************************************
  423.       函数说明:显示图片
  424.       入口数据:x,y起点坐标
  425.                 length 图片长度
  426.                 width  图片宽度
  427.                 pic[]  图片数组   
  428.       返回值:  无
  429. ******************************************************************************/
  430. void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
  431. {
  432.         u16 i,j,k=0;
  433.         LCD_Address_Set(x,y,x+length-1,y+width-1);
  434.         for(i=0;i<length;i++)
  435.         {
  436.                 for(j=0;j<width;j++)
  437.                 {
  438.                         LCD_WR_DATA8(pic[k*2]);
  439.                         LCD_WR_DATA8(pic[k*2+1]);
  440.                         k++;
  441.                 }
  442.         }                       
  443. }
复制代码
如何通过取模工具生成字符汉字及图片的数值,这里就不再介绍了。
我们取4张图片,让LCD轮流显示一些汉字,数字及图片。由于G491有512KB FLASH,所以空间是够用的。
编译下载完,我们看下效果:
57.gif
代码:
STM32G491_DEMO.rar (13.05 MB, 下载次数: 16)

评分

参与人数 1ST金币 +12 收起 理由
g921002 + 12 很给力!

查看全部评分

回复

使用道具 举报

该用户从未签到

50

主题

369

帖子

0

蝴蝶豆

金牌会员

最后登录
2021-4-1
发表于 2021-3-14 15:23:57 | 显示全部楼层
楼主,羡慕啊,我的板子还没到,你就2篇了哦
写得不错!
回复 支持 反对

使用道具 举报

该用户从未签到

50

主题

369

帖子

0

蝴蝶豆

金牌会员

最后登录
2021-4-1
发表于 2021-3-14 15:29:52 | 显示全部楼层
我这几天也在研究spi的LCD。
楼主LCD的 DC引脚配置为输出,如果使用硬件SPI, 那么此引脚为 MISO,应该为输入才对,
这似乎是矛盾的,再看楼主的SPI,貌似不是标准的SPI。
一直有疑问没搞明白~
回复 支持 反对

使用道具 举报

该用户从未签到

14

主题

237

帖子

3

蝴蝶豆

金牌会员

最后登录
2023-1-28
 楼主| 发表于 2021-3-14 21:21:16 | 显示全部楼层
caizhiwei 发表于 2021-3-14 15:29
我这几天也在研究spi的LCD。
楼主LCD的 DC引脚配置为输出,如果使用硬件SPI, 那么此引脚为 MISO,应该为输 ...

DC引脚其实对应的是SPI的MISO,但是这个引脚其实并没有配置成SPI的MISO,而是普通输出引脚。
因为这个屏,需要DC引脚上的电平(1:数据 0:命令),来告知LCD,发送的为命令,还是数据。这个SPI其实是仅主机发送的SPI,
没有接收,不是完整的SPI。这个用法很多屏都是的啊,包括常见的OLED12864都是的!
回复 支持 反对

使用道具 举报

该用户从未签到

50

主题

369

帖子

0

蝴蝶豆

金牌会员

最后登录
2021-4-1
发表于 2021-3-15 09:35:22 | 显示全部楼层
胤幻1988 发表于 2021-3-14 21:21
DC引脚其实对应的是SPI的MISO,但是这个引脚其实并没有配置成SPI的MISO,而是普通输出引脚。
因为这个屏 ...

学习了,感谢分享。
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

63

帖子

0

蝴蝶豆

中级会员

最后登录
2021-4-8
发表于 2021-3-15 10:36:05 | 显示全部楼层
学习了
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-16 18:12 , Processed in 0.177604 second(s), 38 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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