极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 17533|回复: 2

一个关于16X16点阵屏动画移动汉字的程序

[复制链接]
发表于 2016-4-15 20:12:43 | 显示全部楼层 |阅读模式
本帖最后由 fullmous 于 2016-4-15 20:14 编辑

本文仅就在Arduino环境下不借助任何附加的逻辑芯片,就用Atmega48,仅凭端口的处理方式操控16X16点阵屏,完成文字移动等动画效果。

水平移动一个汉字
        我们取中国象棋里的“帅”字为例,实现一个字自左至右移动的效果。
16 X 16是能够比较清晰地显示大部分汉字的最小分辨率,也是计算机屏幕上能够显示汉字最早采用的制式。
提取一个汉字的点阵并非难事。画一个16 X 16个格子的表格。将欲显示汉字正楷形式写出,按笔画所占的格子,转换成32个字节即可。

//水平向右移动“帅”字
//数据存贮在flash存储器中
//“帅”字点阵
const unsigned char table[] = {
  0x0F,0xF0,0x30,0x0C,0x44,0x22,0x44,0x22,
  0x95,0xFD,0x95,0x25,0x95,0x25,0x95,0x25,
  0x95,0x25,0x95,0x25,0x85,0x25,0x89,0x2D,
  0x50,0x22,0x40,0x22,0x30,0x0C,0x0F,0xF0
};

unsigned char A_array[16][4];                //装点阵的数组

void setup()
{
  PORTB = 0x00;    //初始化端口B,C,D功能为输出,端口状态为0
  DDRB  = 0xFF;
  PORTC = 0x00;
  DDRC  = 0x0F;
  PORTD = 0x00;
  DDRD  = 0xFF;
}
//初始化数组,将数据装入数组
void A_arr_prepare()
{
  int i,j;
  for (i = 0;i < 16;i++)
  {
    j = i * 2;
    A_array[3] = table[j];     
    A_array[2] = table[j+1];
    A_array[1] = 0;
    A_array[0] = 0;
  }
}

void loop()
{
  int i,L;
  char m0,m1,m2,m3;

  A_arr_prepare();                        //初始化数组

  while(1)
  {
    for (L = 0;L < 10;L++)                //滚屏速度控制
    {
      for (i = 0;i < 16;i++)                //显示一屏
      {
        PORTD = A_array[1];
        PORTB = A_array[0];
        PORTC = i;
        delay(1);                  //行扫间隔
      }
    }
    //数组A是一个16X4共64字节的结构,可以将数组想象成四列、十六行。
    //我们将这四列以0,1,2,3标注,其中1,2两列直接对应点阵屏上的左右两列8X8 LED模块
    //其中每个字节里的每位,即每个bit对应点阵的一个LED,即一个光点
    //要想造成向右移动的效果,就将最左侧字节数组列即标注为0的那一列的最低位移入第1列的字节的最高位
    //再将第1列的最低位移入第2列的最高位,而第2列的最低位移入第0列的最高位
    //依次将16行都移动,就完成了整屏向右移动一列的效果,连续起来,
    //就造成整屏右移的效果。
    for (i = 0;i < 16;i++)                                //右移一列
    {
      if ((A_array[0] & 0x01) == 1)
        m0 = 0x80;
      else
        m0 = 0;
      if ((A_array[1] & 0x01) == 1)
        m1 = 0x80;
      else
        m1 = 0;
      if ((A_array[2] & 0x01) == 1)
        m2 = 0x80;
      else
        m2 = 0;
      if ((A_array[3] & 0x01) == 1)
        m3 = 0x80;
      else
        m3 = 0;

      A_array[3] = A_array[3] >> 1;
      A_array[3] = A_array[3] | m0;

      A_array[2] = A_array[2] >> 1;
      A_array[2] = A_array[2] | m3;

      A_array[1] = A_array[1] >> 1;
      A_array[1] = A_array[1] | m2;

      A_array[0] = A_array[0] >> 1;
      A_array[0] = A_array[0] | m1;

    }
  }

}

向上连续移动6个汉字
        前面的例子告诉我们,在16 X 16点阵屏上显示一个汉字,要占用32个字节的存储空间。光靠SRAM是显示不了几个字的,我们可以利用片上的EEPROM。下面的例子是利用EEPROM存储汉字点阵数据,连续显示六个汉字自下向上移动的程序。我们知道Atmega48具有片上256个字节的EEPROM空间,最多可以存储8个汉字的点阵,要想再多,就要换芯片了。

//16X16点阵屏,六字向上移动
//六个汉字点阵字模存在EEPROM中

#include <EEPROM.h>
//六个汉字的数据存贮在EEPROM存储器中
//Arduino不具备向FLASH下载程序代码的同时写入EEPROM数据的功能,
//本程序所用EEPROM数据要借助其他工具写入。

void setup()
{
  PORTB = 0x00;        //初始化端口B,C,D功能为输出,端口状态为0
  DDRB  = 0xFF;
  PORTC = 0x00;
  DDRC  = 0x0F;
  PORTD = 0x00;
  DDRD  = 0xFF;
}

void loop()
{
  unsigned char B_port[32];      //汉字点阵数组
  int I;
  int J;
  int K;
  int L;

  for (K = 0;K < 32;K++)        //初始化数组
  {
    B_port[K] = EEPROM.read(K);  //从EEPROM中读出第一个字的点阵
  }

  K = 0;          //EEPROM地址计数指针从0开始,六个字连续计数
  do
  {
    for (L = 0;L < 10;L++)      //刷屏移动速度,也就是每帧画面保留的时间
    {
      J = 0;
      for (I = 0;I < 16;I++)
      {
        PORTD = B_port[J];                                 
        PORTB = B_port[J+1];                              
        PORTC = I;
        delay(1);               //行扫间隔
        J = J + 2;
      }
    }

    I = 0;                ////开始移动数组,由后向前
    while (I < 30)
    {
      B_port[I] = B_port[I + 2];   //例如,数组元素2、3移至0、1
      B_port[I + 1] = B_port[I + 3];
      I = I + 2;                  //指针递增
    }
    B_port[30] = EEPROM.read(K);  //最后,从EEPROM取字节两个,填入数组元素30和31
    K++;
    B_port[31] = EEPROM.read(K);
    K++;
    if (K > 191)
      K = 0;
  }
  while(1);
}

        请读者注意,Arduino不具备下载程序代码的同时下载EEPROM数据的功能(笔者未能找到),EEPROM数据只有通过其他渠道写入芯片,比如,很好用的一款下载工具:AVR_Fighter。

        以上两个关于16X16点阵屏的例子仅用一片Atmega48就跑起来,充分调动了单片机自己的资源,说明硬件结构对一个系统的影响。可能非常繁琐复杂,也可以很简单。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2016-4-15 21:20:12 | 显示全部楼层
不错,学习一下。
回复 支持 反对

使用道具 举报

发表于 2016-4-16 16:47:01 | 显示全部楼层
不错,学习了
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-15 18:21 , Processed in 0.036885 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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