JavaScript開發單片機:I/O篇 -- 驅動LED鍵盤控制IC-FD620K1.

手頭上有一臺壞掉的衛星接收機,拆下面板上的顯示鍵盤小板,使用單片機I/O驅動成功。

var usbio = uopen(0x0908, 0xa, 0x100);
/**
 * CLK = P1.5
 * DIO = P1.6
 * STB = P1.7
 *
 * \fn uwrite
 * \param 1 Device handle.
 * \param 2 Port selector.
 * \param 2 Write mode.
 * \param 4 P0 port.
 * \param 5 P1 port.
 * \param 6 P2 port.
 * \param 7 P3 port.
 * uwrite(device, Port selector, P0, P1, P2, P3);
 */

/**<Port selector.
 *              b00 00 00 00, Doesn't write any data, read only.
 *              b00 00 00 01, Writes P0 only.
 *              b00 00 00 10, Writes P1 only.
 *              b00 00 01 00, Writes P2 only.
 *              b00 00 10 00, Writes P3 only.
 *              b00 11 11 11, Writes all ports.
 *  Write mode.
 *              b** ** ** **
 *               || || || ||
 *               P3 P2 P1 P0
 *               || || || ||
 *               00 = Write data directly.
 *               01 = And wirte.
 *               10 = Or wirte.
 *               11 = Xor wirte.
 *  P0 = P0 data.
 *  P1 = P1 data.
 *  P2 = P2 data.
 *  P3 = P3 data.
 */

if (usbio)
{
  var seq = [],
        str;

  for (var i = 0; i < 72; i++)
  {
    if (seq.length < 4)
    {
      str = Math.random().toString();
      str = str.replace(/[^\d]/g, '');
      for (var j = str.length; j > 0; j--)
        seq.push(parseInt(str.substr(j - 1, 1)));
    }

    led_display_seq(seq);
  }
}

function led_display_seq(s)
{
  set_led_display(s[0], s[1], s[2]);
  s.shift()
}

function led_set_number(n)
{
  var a1 = n % 10,
        a2 = (n - a1) / 10,
        a3 = (a2 - a2 % 10) / 10;

  set_led_display(a3, a2, a1);
}

function led_num_to_7seg(n)
{
  /**<
   * 0 0 0 0 0 0 0 0
   *    g f  e d c b  a
   */
  var seg = [0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f];

  return seg[n % 10];
}

function set_led_display()
{
  set_display_mode(0);
  set_io(0);
  set_addr(0);
  write_byte(led_num_to_7seg(arguments[0]));

  if (typeof arguments[1] == 'number')
  {
    write_byte(0);
    write_byte(led_num_to_7seg(arguments[1]));
  }

  if (typeof arguments[2] == 'number')
  {
    write_byte(0);
    write_byte(led_num_to_7seg(arguments[2]));
  }

  set_display_ctrl(1, 0);

  // Sets STB to high.
  ioset('P1:|x80');
}

function ioset(data)
{
  ///< Reads the values of port.
  if (typeof data != 'string')
  {
    if (typeof data == 'number')
      ///< Reads a specified port value.
      return uread(usbio, data);
    ///< Reads all ports, return a DWORD value.
    return uread(usbio);
  }

  var
    ports = 0,
    modes = 0,
    values = [0, 0, 0, 0];

  data.replace(/P([0123]):([=&^\|])?(0?x)?([\da-f]+)/gi, function(r1, r2, r3, r4, r5)
  {
    ports |= 1 << r2;
    modes |= '=&|^'.indexOf(r3) << (r2 * 2);
    values[r2] = parseInt(r5, r4.search(/x$/gi) != -1 ? 0x10 : 0x0a);
  });

  uwrite(usbio, ports, modes, values[0], values[1], values[2], values[3]);
}

function write_byte(c)
{
  for (var i = 0; i < 8; i++)
  {
    ioset(c & 1 ? 'P1:x40' : 'P1:x00');
    ioset('P1:|x20');
    c >>= 1;
  }
}

function read_byte()
{
  var temp = 0;

  for (var i = 0; i < 8; i++)
  {
    ioset('P1:|x20');
    ioset('P1:&x4f');

    temp >>= 1;
    if (ioset(0x01) & 0x40)
      temp |= 0x80;
  }
  
  return temp;
}

/**< display mode
 * 00 = 4位,9段
 * 01 = 5位,8段
 * 10 = 6位,7段
 * 11 = 7位,6段
 */
function set_display_mode(m)
{
  // Sets STB to high.
  ioset('P1:|x80');

  // Sets STB to low.
  ioset('P1:&x7f');
  write_byte(m & 0x03);
}

/**<
 * s = display switch
 * 0 = close
 * 1 = open
 * g = display gray
 * 000:   設置脈衝寬度爲1/16
 * 001:      設置脈衝寬度爲2/16
 * 010:      設置脈衝寬度爲4/16
 * 011:      設置脈衝寬度爲10/16
 * 100:      設置脈衝寬度爲11/16
 * 101:      設置脈衝寬度爲12/16
 * 110:      設置脈衝寬度爲13/16
 * 111:      設置脈衝寬度爲14/16
 */
function set_display_ctrl(s, g)
{
  // Sets STB to high.
  ioset('P1:|x80');

  // Sets STB to low.
  ioset('P1:&x7f');
  write_byte(0x80 | (s ? 0x08:0) | (g & 0x07));
}

/**<
 * 數據讀寫模式設定:
 * 00:寫數據到顯示寄存器
 * 10:讀鍵掃數據
 */
function set_io(m)
{
  // Sets STB to high.
  ioset('P1:|x80');

  // Sets STB to low.
  ioset('P1:&x7f');
  write_byte(0x40 | (m & 0x03));
}

function set_addr(a)
{
  // Sets STB to high.
  ioset('P1:|x80');

  // Sets STB to low.
  ioset('P1:&x7f');
  write_byte(0xc0 | (a & 0x08));
}


 

發佈了148 篇原創文章 · 獲贊 6 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章