jinglixixi 发表于 2023-3-15 23:06

基于N76E003的16*64点阵屏的滚动显示及混排显示

#申请原创#@21小跑堂

前面曾介绍过点阵模块的静态显示模式,但毕竟在不把多个点阵模块进行级联的情况下,其显示的的信息量是有限的。当然你也可以采用多屏切换的方式来增加信息的显示量,但它会使人产生断断续续的感觉,为此最好是能以滚动显示的方式来显示更多的信息,其形式见图1所示。
图1 显示效果 在原连接的方式不变的情况下,通过程序的修改来实现滚动显示的效果。其具体的连接关系为:A --- P1.0 B --- P1.1C --- P1.2D--- P1.3EN --- P1.4R1 --- P1.5STB--- P1.6CLK--- P1.7 为此在程序中所做的定义如下:sbitR1=P1^5;            // 红色数据sbitSTCP=P1^6;       // 595锁存端口sbitSHCP=P1^7;       // 595时钟端口sbitSHOW_OE=P1^4;   // 74HC138使能(低有效)unsignedchar k=0, row =0; w=0;uchar BUFF ; 短延时函数的内容为:void delay(UINT16 z)
{
        while(z--);
}

实现字节合并与位置交换的处理函数为:unsigned char Combine (unsigned char H, unsigned char L)
{
      unsigned char dat,temp;
      temp=w;
      dat=(H>>temp)|(L<<(8-temp));
      return dat;
}

装载点阵数据的函数为:void Load (void)                                  // 将显示内容装入缓存数组
{
         unsigned char i;
      for(i=0;i<16;i++)
      {
         BUFF =Table;    // 装载点阵数据
      }
}

发送一行点阵数据的函数为:void Send(void)
{
      unsigned char s;
      unsigned char temp,i,j,inc;
      if(j<8)             inc=0;
      if(8<=j&&j<16)   inc=1;
      for(s=0+inc;s<=8+inc;s++)
      {
                temp=Combine(BUFF ,BUFF );
                for(i=0;i<8;i++)
                {
                        R1=~(temp>>i)&0x01;// 取最低位的值
                        SHCP =0;
                        SHCP =1;               // 产生移位时钟
                }
      }
}

实现滚动显示的函数为:voidMOVE()
{
      unsigned char i,j;
      for(j=0;j<16;j++)            // 循环16次,点亮并移动一个汉字,步进是一位
      {
                j=j%8;            // 一个字节移动位数
                for(i=0;i<16;i++)      // 扫描16行
                {
               row=i;
               Load();          // 装载一行点阵数据
               Send();          // 发送一行点阵数据
               SHOW_OE =1;
                     STCP =1;             // 输出锁存
                     STCP =0;
               P1=i ;            // 行扫描
                  SHOW_OE =0;
                }
      }
      delay(500);
      k=(k+1)%11;                // 限定汉字的显示数量,可视字库的大小来酌情扩展。
}

实现显示效果的主函数为:void main (void)
{
        Set_All_GPIO_Quasi_Mode;
        set_CLOEN;
        while(1)
        {
               MOVE();
        }
}

那该如何获取显示内容的字模呢?
显示内容的字模可由软件来提取,见图2所示,其提取格式如图3所示。图2 工具软件
图3 提取格式
在提取字模后,是将字模存放到数组中以供读取,其格式如下:unsigned char code Table[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0xFC,0x1F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x7F,0x80,0x00,
0x40,0x01,0x40,0x01,0x20,0x02,0x20,0x02,0x10,0x04,0x08,0x08,0x04,0x10,0x03,0x60,

0x00,0x02,0x04,0x02,0xC8,0x1F,0x08,0x12,0xE1,0x7F,0x02,0x12,0xD2,0x1F,0x10,0x02,
0x08,0x02,0xC8,0x1F,0x07,0x02,0x04,0x02,0xE4,0x3F,0x04,0x02,0x04,0x02,0x00,0x02,

0x00,0x00,0x80,0x3F,0xBF,0x24,0x88,0x24,0x88,0x3F,0x88,0x24,0x88,0x24,0xBE,0x3F,
0x08,0x04,0x08,0x04,0x88,0x3F,0x08,0x04,0x38,0x04,0x07,0x04,0xC2,0x7F,0x00,0x00,

0x00,0x00,0x00,0x00,0xFE,0x3F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,
0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x7F,0x00,0x00,0x00,0x00,

0x00,0x01,0x00,0x01,0x3F,0x01,0x20,0x3F,0xA0,0x20,0x92,0x10,0x54,0x02,0x28,0x02,
0x08,0x02,0x14,0x05,0x24,0x05,0xA2,0x08,0x81,0x08,0x40,0x10,0x20,0x20,0x10,0x40,

0x00,0x00,0x04,0x01,0xC8,0x3C,0x48,0x24,0x40,0x24,0x40,0x24,0x4F,0x24,0x48,0x24,
0x48,0x24,0x48,0x2D,0xC8,0x14,0x48,0x04,0x08,0x04,0x14,0x04,0xE2,0x7F,0x00,0x00,

0x10,0x01,0x10,0x01,0x10,0x01,0x88,0x7F,0x88,0x40,0x4C,0x20,0x2C,0x04,0x0A,0x04,
0x89,0x14,0x88,0x24,0x48,0x24,0x48,0x44,0x28,0x44,0x08,0x04,0x08,0x05,0x08,0x02,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

通过以上的数值,其显示的效果如图4所示。仿此使用者可根据自己的需要来提取相应的字模,在修改限定显示汉字个数的情况下就可完成自己的显示目标。图4 滚动显示效果 有了向左滚动显示的功能,那如何来实现向上的滚动显示呢?
以显示“远上寒山石径斜,白云深处有人家,停车坐爱枫林晚,霜叶红于二月花。”这首诗为例,可按图5所示的方式来提取字模。图5 提取格式
图6 滚动显示效果
在提取字模后,其存储格式如下:unsigned char code Table[]={
0x00,0x00,0xF8,0x23,0x00,0x10,0x00,0x10,0x00,0x00,0xFC,0x07,0x20,0xF1,0x20,0x11,
0x20,0x11,0x20,0x11,0x24,0x11,0x24,0x12,0x24,0x12,0x1C,0x14,0x00,0x28,0xFE,0x47,/*"?",0*/
0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0xF8,0x03,0x00,0x02,
0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0xFE,0xFF,0x00,0x00,/*"?",1*/
...
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x24,0x00,0x24,0x00,0x18,0x00,0x00,0x00,0x00,/*"?",31*/
}

显示向上滚动显示的主程序为:void main (void)
{
        unsigned char i;
    unsigned int k,m;
    char j;
        Set_All_GPIO_Quasi_Mode;
        set_CLOEN;        
    m=sizeof(Table);
    while(1)
    {
         for(k=0;k<m;k=k+2)      // 显示长度限定
         {
                for(i=0;i<16;i++)// 显示16行
                {
                                          STCP_HIGH;
                      for(j=0;j<=3;j++)   // 每行4个汉字宽度
                      {
                           HC595_write (Table[(32*j+2*i+1+k)%m]);
                           HC595_write(Table[(32*j+2*i+k)%m]);
                      }
                                          SHOW_OE =1;
                      temp=ADDR;
                      ADDR=(temp&0xe1|t);                 // ABCD =P1.0 - P1.3
                      STCP_LOW;
                      _nop_();
                      STCP_HIGH;;
                                          SHOW_OE =0;
                                          delay(100);
               }
         }
   }
}

此外,在显示过程中还常会遇到中英文混排的情况,由于两者所用的字库结构不同,那又该如何解决这个问题呢?
这就需要在编码方面做些文章,例如可以将待显示的汉字编号高位置1来区分汉字和英文字符,然后再根据编码的不同来调用相应的显示函数进行处理。图7 混排显示效果
实现混排显示的函数为:void SCREEN_SHOW()
{
        UINT8 i,j,t=0,temp,p,n,f,u;       
        UINT8 ch={0x10,0x11,0x12,0x03,0x02,0x13,0x10,0x10};
        SHOW_OE=0;
        for(i=0;i<16;i++)
        {
                STCP_HIGH;
      n=0;
      p=0;
                for(j=0;j<8;j++)
                {
                        if(ch>0x0b)   // 可视字符库的规模来酌情增大限定值
                        {
                                  f=1;
                        }
            else
            {
                                  f=0;
            }
                        if(f)
                        {
                                  if(p==0)
                                  {
                                                u=ch-0x10;
                                  }
                                  HC595_write(table1);// 显示汉字
                  p=(p+1)%2;
                                  if(p==0)n=n+1;
                        }
                        else
                        {
                                  u=ch;
                               HC595_write(table2);   // 显示字符
                        n=n+1;
                        p=0;
                        }
               }
               temp=ADDR;
             ADDR=(temp&0xe1|t);                        // ABCD =P1.0 - P1.3
               STCP_LOW;
               STCP_HIGH;
               t++;
               delay(100);
       }
}

这样我们就使点阵模块的显示效能又提高了一个层次,也更符合实际应用的需要。
后面我们会继续探索全彩屏的驱动方法,它会给我们一个更加多彩的效果和感受!

OKAKAKO 发表于 2023-3-16 17:16

确实这样看要顺畅要顺眼,还考虑到英文

chenjun89 发表于 2023-3-21 08:46

爱枫林晚

jinglixixi 发表于 2023-3-21 16:50

chenjun89 发表于 2023-3-21 08:46
爱枫林晚

哈哈,由于是向上滚动,“停车坐爱枫林晚” 就截了这4个字。
页: [1]
查看完整版本: 基于N76E003的16*64点阵屏的滚动显示及混排显示