最容易扩展的光立方程序设计

光立方的设计有很多不同思路,在此讲述一下我的光立方程序设计思路
对象:一个8x8x8的光立方
光立方实体图片:
这里写图片描述

底层由64个发光二极管排列成8x8方阵,总共8层,每一层所有发光二极管的阴极连在一起引出,每竖条的发光二极管阳极依次焊接在一起,显示原理类似数码管的动态扫描!

程序中构造一个空间立方体,每个发光二极管都可看做是空间中的一个坐标点。就以一个数组表示,该数组为全局变量,如下:
光立方数组

该光立方数组管理512个LED,共64字节大小,512位,每一位代表一个LED,当相应二进制位为1时代表LED亮,为0时代表相应LED灭。建立此光立方数组后很容易想到只要单独写一个处理器中断中或者操作系统线程,其中按一定频率将该数组数据动态扫描到实体上(这部分涉及到I/O口的操作,不同的处理器这部分操作不同),而其他处理图形或数字的函数放在其他线程中即可(这部分函数完全脱离硬件),这样硬件扫描部分和软件控制部分完全分离互不干扰,思路清晰,也利于后面程序扩展。
在ucos-ii中单独创建一个线程执行扫描函数:

OSTaskCreate(Display,NULL,
               (OS_STK *)&DisplayStk[TASK_STK_SIZE-1],
               (INT8U)5);

void Display(void *p_arg)
{
  p_arg = p_arg;

  while(1)
  {
    DisplayPix();
    OSTimeDlyHMSM(0,0,0,4);//根据实际效果调节延时时间
  }
}

DisplayPix()函数需要根据实际I/O口编写,作用是将光立方数组里的数据扫描到实体上。为了保证在处理底层I/O时不被其他线程干扰,我将该线程优先级提到最高,这样也能保证扫描效果的流畅性。如果你要保证其他任务的实时性,将该线程的优先级调低也可,但是此处就要编写不可重入代码或者加互斥锁。

接下来考虑软件部分,有两个函数必须实现,这两个函数是以后扩展其它函数的基础。写好这两个函数后,加入一些必要的算法可以让光立方充满生命,如果要显示字母或图形可以用取模软件生成对应字母的字模数组,以备显示。
1.设置空间坐标点LED的亮灭状态SetPix函数

/**************
函数:SetPix
参数:(x,y,z)待动作的LED,color,1-点亮,0-熄灭,其他值-无操作
说明:开关空间坐标点LED
****************/  
void SetPix(INT8S x,INT8S y,INT8S z,INT8S color)
{
    INT8S Pix;
    Pix = z*8 + y;   
    switch(color)
    {
    case 0:
      LED8x8x8[Pix] &= ~(1<<x);  //熄灭位置灯
      break;
    case 1:
      LED8x8x8[Pix] |= 1<<x;    //点亮位置灯
      break;
    default://其他值,保持该点LED状态,无操作
      break;     
    }
}  

2.读取空间坐标点的亮灭状态GetPix函数

/**************
函数:GetPix
参数:(x,y,z)待动作的LED
输出:LED状态
说明:读取对应坐标点LED的状态
****************/
INT8S GetPix(INT8S x,INT8S y,INT8S z)
{
  INT8S Pix;
  Pix = LED8x8x8[z*8+y];
  Pix &= 1<<x;
  if(Pix==0)
    return 0;
  else
    return 1;
}

以上函数并没有对参数范围进行检查,不算严格,实际需小心谨慎,确保传入的参数范围在实际范围内,或者最好在函数中对参数进行检查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值