OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6802|回复: 18

想在LCD上显示较大的数字,这个函数应怎么修改才行?

[复制链接]

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
发表于 2018-2-9 14:23:11 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 rjx007 于 2018-2-10 13:04 编辑

想在LCD上显示尺寸较大的数字,但经试验,这个函数最大只能显示24*12的数字,现在想显示如48*24,64*32的数字,该怎么修改这个函数才能行?或能提供一个能显示大字符的函数也可。


//显示数字,高位为0,则不显示
//x,y :起点坐标         
//len :数字的位数
//size:字体大小
//color:颜色
//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);
        }
}


最佳答案

查看完整内容[请看2#楼]

LCD_ShowChar的u8定义改为u16即可。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-2-9 14:23:12 | 显示全部楼层
LCD_ShowChar的u8定义改为u16即可。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

462

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2017-12-15
在线时间
111 小时
发表于 2018-2-9 16:00:23 | 显示全部楼层
玄机在 LCD_ShowChar里面,而不是在这里。。。。
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-2-9 16:22:59 | 显示全部楼层
LCD_ShowChar这个函数我也试了,最大也是只能显示24x12的数字,我自己取模分别做了几个0~9这十个数字的32x16,64x32的数组做实验,均不能正常显示,不知是怎么回事,楼上能指导一下吗?谢谢啊!
回复

使用道具 举报

8

主题

571

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2922
金钱
2922
注册时间
2016-5-13
在线时间
185 小时
发表于 2018-2-9 16:55:20 | 显示全部楼层
用画点函数呀。不过显示有点慢。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-2-9 17:06:38 | 显示全部楼层
能给个例子吗?
回复

使用道具 举报

6

主题

462

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2017-12-15
在线时间
111 小时
发表于 2018-2-9 17:10:36 | 显示全部楼层
电脑小白 发表于 2018-2-9 16:55
用画点函数呀。不过显示有点慢。

虽然不明白你在说什么,但感觉很厉害的样子。

就算画点,也得用现有的字符取模结果呀。
回复

使用道具 举报

6

主题

462

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2017-12-15
在线时间
111 小时
发表于 2018-2-9 17:11:50 | 显示全部楼层
rjx007 发表于 2018-2-9 16:22
LCD_ShowChar这个函数我也试了,最大也是只能显示24x12的数字,我自己取模分别做了几个0~9这十个数字的32x1 ...

我的意思是,修改LCD_ShowChar使他能够正确显示大尺寸的字符。
由于不知道你的代码是怎样的思路,所以,,
请自行努力。
回复

使用道具 举报

32

主题

300

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2012-3-30
在线时间
321 小时
发表于 2018-2-9 18:46:15 | 显示全部楼层

给你一个写汉字过程自己分析

/***写汉字 同步显示0-32字节写过程程序测试***/
/***2018 1 28 21:15 L217 CODE 220340*********/
                      #include <stm32f10x_lib.h>
                          #include "sys.h"  
                          #include "stdio.h"
                          #include "usart.h"               
                          #include "delay.h"       
                          #include "led.h"
                          #include "flash.h"
                            #include "lcd.h"          
                          #include "text.h"
                          #include "fat.h"
                          #include "fontupd.h"
                          #include "mmc_sd.h"
                          const unsigned char Hz1[32]=   
                     {
                      0x10,0x00,0x10,0x00,0x3D,0xFC,0x20,0x20,
                      0x40,0x20,0xBC,0x20,0x10,0x20,0x10,0x20,
              0xFD,0xFC,0x10,0x20,0x10,0x28,0x10,0x24,
                      0x14,0x24,0x18,0x20,0x13,0xFE,0x00,0x00
                          };/*"钰"*/
                  const unsigned char Hz2[32]=
                      {
                          0X01,0XFF,0X01,0XFF,0X01,0XFF,0X01,0XFF,
                      0X01,0XFF,0X01,0XFF,0X01,0XFF,0X01,0XFF,
                      0X01,0XFF,0X01,0XFF,0X01,0XFF,0X01,0XFF,
                      0X01,0XFF,0X01,0XFF,0X01,0XFF,0X01,0XFF
                      };/*"竖条"*/
                      const unsigned char Hz3[32]=       
                      {
                      0X00,0X01,0X00,0X03,0X00,0X07,0X00,0X0F,
                      0X00,0X1F,0X00,0X3F,0X00,0X7F,0X00,0XFF,
                      0X01,0XFF,0X03,0XFF,0X07,0XFF,0X0F,0XFF,
                      0X1F,0XFF,0X3F,0XFF,0X7F,0XFF,0XFF,0XFF
                       };/*三角形*/
                      const u8 disdt[]={48,49,50,51,52,53,54,55,56,57};
/**************写汉字字节数显示*********/
              void  dispvavel(u8 vel)
                      {
                      u8        l,m,n;
                  l=vel/100;
                      m=(vel-l*100)/10;
                         n=vel-l*100-m*10;
                      POINT_COLOR=RED;//设置字体为红色
                      LCD_ShowChar(10,32,disdt[l],16,0); //10横向 90纵向disdt[]
                         POINT_COLOR=BLUE;//设置字体为蓝色
                      LCD_ShowChar(18,32,disdt[m],16,0); //18横向 90纵向disdt[]
                      POINT_COLOR=BROWN;//设置字体为棕色
                      LCD_ShowChar(26,32,disdt[n],16,0); //26横向 90纵向disdt[]
                  }        
/**************写一个“沁”字***********Hz1************/
              void LcdShowHz1(u16 x,u16 y)
                      {
                      u8 temp,t1,t,k;                         //数据缓冲 一个字节循环 汉字字节总数
                      u8 x0,s=0;                             //数据缓冲 一个字节循环 汉字字节总数
                       for(t=0;t<16;t++)                 //共16个字节
                       {
                       x0=x;                                                         //汉字左边缘等于实参
                        for(k=0;k<2;k++)                                   //两行等于两字节,左右结构
                        {
                        dispvavel(s);                                         //临时函数,写汉字字节显示
                        temp=Hz1[s];                                         //取字符表代码
                         for(t1=0;t1<8;t1++)             //一个字节左移8次 读每移动一次后0或1
                         {
                          if(temp&0x80)
                              {
                              LCD_DrawPoint(x0,y);           //如为1在XY地址写显示
                              }
                             temp<<=1;                       //左移一位
                         x0++;                           //水平位置加1共0--15计16个点
                         }
                         s++;                                                          // 写完1字节八个点 字符表位置加1
                         delay_ms(600);
                        }
                       y++;                                                             //两个字节换一行
               }
                      }               
/**************画一个竖条 左部00H 右部FFH***Hz2*************/
                  void LcdShowHz2(u16 x,u16 y)
                      {
                      u8 temp,t1,t,k;                         //数据缓冲 一个字节循环 汉字字节总数
                      u8 x0,s=0;                             //数据缓冲 一个字节循环 汉字字节总数
                       for(t=0;t<16;t++)                 //共16个字节
                       {
                       x0=x;                                                     //汉字左边缘等于实参
                        for(k=0;k<2;k++)                               //两行等于两字节,左右结构
                        {
                        dispvavel(s);                                     //临时函数,写汉字字节显示
                        temp=Hz2[s];                                     //取字符表代码
                         for(t1=0;t1<8;t1++)             //一个字节左移8次 读每移动一次后0或1
                         {
                          if(temp&0x80)
                              {
                              LCD_DrawPoint(x0,y);           //如为1在XY地址写显示
                              }
                             temp<<=1;                       //左移一位
                         x0++;                           //水平位置加1共0--15计16个点
                         }
                         s++;                                                      // 写完1字节八个点 字符表位置加1
                         delay_ms(600);
                         }
                        y++;                                                     //两个字节换一行
               }
                      }               
/***************画一个三角形****Hz3******************/
                  void LcdShowHz3(u16 x,u16 y)
                      {
                       u8 temp,t1,t,k;                         //数据缓冲 一个字节循环 汉字字节总数
                      u8 x0,s=0;                             //数据缓冲 一个字节循环 汉字字节总数
                       for(t=0;t<16;t++)                 //共16个字节
                       {
                       x0=x;                                                 //汉字左边缘等于实参
                        for(k=0;k<2;k++)                               //两行等于两字节,左右结构
                        {
                        dispvavel(s);                                     //临时函数,写汉字字节显示
                        temp=Hz3[s];                                     //取字符表代码
                         for(t1=0;t1<8;t1++)             //一个字节左移8次 读每移动一次后0或1
                         {
                          if(temp&0x80)
                              {
                              LCD_DrawPoint(x0,y);           //如为1在XY地址写显示
                              }
                             temp<<=1;                       //左移一位
                         x0++;                           //水平位置加1共0--15计16个点
                         }
                         s++;                                                  // 写完1字节八个点 字符表位置加1
                         delay_ms(600);
                         }
                        y++;                                                     //两个字节换一行
               }
                      }               
/*************************************/
                      int main(void)
                      {                 
                           u8 i;
                             Stm32_Clock_Init(9);              //系统时钟设置
                           delay_init(72);                             //延时初始化
                           uart_init(72,9600);               //串口1初始化            
                           LCD_Init();                                     //初始化液晶                  
                              LED_Init();                       //LED初始化       
                           SPI_Flash_Init();                     //SPI FLASH初始化
                    if(Font_Init())                  //字库不存在,则更新字库
                    {       
                POINT_COLOR=RED;      
                    LCD_Clear(WHITE);
                    LCD_ShowString(60,50,"Mini STM32");       
                    LCD_ShowString(60,70,"Font Updating...");                   
//字体更新
                    SD_Initialize();                        //初始化SD卡                                               
                     while(FAT_Init())                        //FAT 错误
                     {
                              LCD_ShowString(60,90,"FAT SYS ERROR");  
                              i=SD_Initialize();
                             if(i)//SD卡初始化
                             {                                                  
                                 LCD_ShowString(60,110,"SD_CARD ERROR");
                             }          
                             delay_ms(500);
                             LCD_Fill(60,90,240,126,WHITE);//清除显示                          
                             delay_ms(500);
                             LED0=!LED0;          
                         }         
                        LCD_Fill(60,90,240,126,WHITE);//清除显示                          
                         while(Update_Font()!=0)//字体更新出错
                        {                                                  
                             LCD_ShowString(60,90,"SYSTEM FILE LOST");                  
                             delay_ms(500);   
                             LCD_ShowString(60,90,"Please Check....");
                             delay_ms(500);   
                             LED0=!LED0;       
                        };                         
                        LCD_Clear(WHITE);
                   }  
                       while(1)
                           {       
                           POINT_COLOR=BLUE;     
                            Show_Str(60,50,"2016 10 5",16,0);                                             
                           Show_Str(10,70,"蔡沁钰 常州市北实验中学",16,0);                                             
                           Show_Str(60,90,"八(8)班",16,0);
                           delay_ms(5000);
                           delay_ms(5000);
                           LCD_Clear(WHITE);                                 //清除显示       
                           delay_ms(5000);                                     
                       POINT_COLOR=RED;  
                           Show_Str(60,32,"1",16,0);         //1
                           LcdShowHz1(00,00);                                 //画横线         已实现
                            for(i=0;i<20;i++)                                  
                            {
                               delay_ms(200);
                            LED0=!LED0;
                            LED1=!LED1;
                            }                        
                            LCD_Clear(WHITE);                                 //清除显示
                            for(i=0;i<50;i++)                                 //已实现
                            {
                            delay_ms(20);
                            LED1=!LED1;
                            }
                                Show_Str(60,32,"2",16,0);        //2
                              LcdShowHz2(00,00);                                 //画横线         已实现
                            for(i=0;i<20;i++)                                  
                            {
                            delay_ms(200);
                            LED0=!LED0;
                            LED1=!LED1;
                            }                        
                            LCD_Clear(WHITE);                                 //清除显示
                            Show_Str(60,32,"3",16,0);        //3
                            LcdShowHz3(00,00);                                 //画横线         已实现
                            for(i=0;i<20;i++)                                  
                            {
                            delay_ms(200);
                            LED0=!LED0;
                            LED1=!LED1;
                            }                                                          
                           }
                      }
回复

使用道具 举报

6

主题

462

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2017-12-15
在线时间
111 小时
发表于 2018-2-9 20:25:57 | 显示全部楼层
czhaii 发表于 2018-2-9 18:46
给你一个写汉字过程自己分析

/***写汉字 同步显示0-32字节写过程程序测试***/

你有毒吧。。。

你倒是显示个大的呀,你这不也是小的吗。才16x16的。。。然后你那个钰呀沁呀的是女朋友名字吧hhhhh
回复

使用道具 举报

32

主题

300

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2012-3-30
在线时间
321 小时
发表于 2018-2-9 21:04:35 | 显示全部楼层
a496298685 发表于 2018-2-9 20:25
你有毒吧。。。

你倒是显示个大的呀,你这不也是小的吗。才16x16的。。。然后你那个钰呀沁呀的是女朋 ...

自己动一点点脑子很难么?
回复

使用道具 举报

6

主题

315

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1669
金钱
1669
注册时间
2018-1-29
在线时间
160 小时
发表于 2018-2-10 08:26:50 | 显示全部楼层
大多数的函数都是基于字库方式显示。例如有一个8*16点阵ASCII码字库。只能显示8*16的。如下例子中的ascii_8x16数组用法。
void LCD_PutChar(u16 x,u16 y,u8 c,u16 charColor,u16 bkColor)
{
  u16 i=0;
  u16 j=0;
  
  u8 tmp_char=0;

  for (i=0;i<16;i++)
  {
    tmp_char=ascii_8x16[((c-0x20)*16)+i];
    for (j=0;j<8;j++)
    {
      if ( (tmp_char >> 7-j) & 0x01 == 0x01)
        {
          LCD_SetPoint(x+j,y+i,charColor); // 字符颜色
        }
        else
        {
          LCD_SetPoint(x+j,y+i,bkColor); // 背景颜色
        }
    }
  }
}
要想显示24*48的,需要有24*48点阵字库。这样的字库会很大!占用大量ROM空间,所以没有人用!
你可以按比例放大,例如以8x16点阵为基础,显示16*32点阵的。 把原来每个点在x,y方向绘制2两次,注意坐标控制。
不过显示出来的字符可能锯齿很明显!

回复

使用道具 举报

6

主题

315

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1669
金钱
1669
注册时间
2018-1-29
在线时间
160 小时
发表于 2018-2-10 08:27:52 | 显示全部楼层
电脑上有任意点阵字符生成软件。原子哥的光盘里应该有!
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-2-10 11:15:45 | 显示全部楼层
本帖最后由 rjx007 于 2018-2-10 11:16 编辑

下面这个显示字符的函数,发现一个奇怪的问题:就是对于形参 u8 num,在实际使用时,并不是要显示字符在字库数组中的顺序号,而是要输入实际的字符加单引号,如要显示字符A,在形参u8 num处要输入‘A’才行,或是要按ASCII码表的顺序号。想不通是为什么。一般情况下,都是输入该字符在数组中的顺序号就行了。

另外,函数中红色的一行是我加上去的,想显示32x16大小的字符,且已自己取模做好了32x16的字库(一个二维数组),但不能正常显示。求教如何搞?


//在指定位置显示一个字符
//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=ascii_1206[num][t];                  //调用1206字体
                else if(size==16)temp=ascii_1608[num][t];        //调用1608字体
                else if(size==24)temp=ascii_2412[num][t];        //调用2412字体
                else if(size==32)temp=ascii_3216[num][t];
                else return;                                                                //没有的字库
                for(t1=0;t1<8;t1++)
                {                           
                        if(temp&0x80)LCD_DrawFRONT_COLOR(x,y,FRONT_COLOR);
                        else if(mode==0)LCD_DrawFRONT_COLOR(x,y,BACK_COLOR);
                        temp<<=1;
                        y++;
                        if(y>=tftlcd_data.height)return;                //超区域了
                        if((y-y0)==size)
                        {
                                y=y0;
                                x++;
                                if(x>=tftlcd_data.width)return;        //超区域了
                                break;
                        }
                }           
        }                                            
}   
回复

使用道具 举报

0

主题

64

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
249
金钱
249
注册时间
2018-1-19
在线时间
28 小时
发表于 2018-2-10 14:35:33 | 显示全部楼层
可以吧  我以前做的是8x16的 后来自己改到了12x24  我用的是  1.3寸的OLED  自己先看懂程序  在慢慢修改
回复

使用道具 举报

32

主题

300

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2012-3-30
在线时间
321 小时
发表于 2018-2-10 15:26:12 | 显示全部楼层
可以把LCD_DrawFRONT_COLOR(x,y,FRONT_COLOR);函数改成串口数据输出仿真。
循环一下看看就知道了。
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-2-10 16:11:23 | 显示全部楼层
本帖最后由 rjx007 于 2018-2-10 16:58 编辑

经仔细实验,可以正常显示32*16,48*24大小的字符,但64*32的仍然不行,不知是什么原因。
另外还有个不明白的,就是形参u8 num必须是标准的ASCII码表的顺序号,输入自己取模字库的顺序号是不对的。
如在我自己取模的字库中,字符"0"排在第一位,可输入0是不行的,要输入33(注意要屏蔽掉函数中的num=num-'  ';这条语句,否则输入32),因为字符“0”在ASCII码表中排位在33。
图片是48*24的

66.jpg
回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2018-2-6
在线时间
6 小时
发表于 2019-1-8 11:33:33 | 显示全部楼层
rjx007 发表于 2018-2-9 16:22
LCD_ShowChar这个函数我也试了,最大也是只能显示24x12的数字,我自己取模分别做了几个0~9这十个数字的32x1 ...

您好,我最近也在做显示32*32的数字,而不是中文,中文自己取模可以显示,数字就乱码了,您解决了吗,可以分享一下吗
回复

使用道具 举报

2

主题

9

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2018-2-6
在线时间
6 小时
发表于 2019-1-8 15:39:47 | 显示全部楼层
哪个爸爸给讲解一下
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 00:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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