JavaScript開發單片機:I/O篇 -- 在LCD1602上顯示字符串

用來測試外圍不錯,不用每次都燒F/W。相當於把單片機I/O當個並口用。缺點就是速度慢沒有實際板上跑得快。

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

/**<Port select.
 *              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)
{
  lcd_init();
  lcd_print('abcdefghijk1234567890');
  uclose(usbio);
}

function ioset(data)
{
  ///< Reads the value of port.
  if (typeof data != 'string')
  {
    if (typeof data == 'number')
      ///< Reads a specified port.
      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 lcd_init()
{
  /**< clear P0.
   * RS  RW  EP  D7  D6  D5  D4  D3  D2  D1  D0
   * *   *   *   0   0   0   0   0   0   0   0
   */
  ioset('P1:0');

  /**< BF cannot be checked before this instruction.
   * RS  RW  EP  D7  D6  D5  D4  D3  D2  D1  D0
   * 0   0   *   0   0   1   1   *   *   *   *
   */
  //lcd_write_cmd(0x38);
  ioset('P1:x38,P2:x03');
  ioset('P1:x38,P2:x03');
  ioset('P1:x38,P2:x03');

  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;
  /**<
   *  bus_type:
	 *    BUS4BIT 0x00    high 4bit only.
	 *    BUS8BIT 0x10    full 8bit.
   *
   *  lines:
	 *    single  0x00
	 *    dual    0x08
   *
   *  font:
	 *    5*8     0x00
	 *    5*10    0x04    work with single line only.
   *
   *  lcd_write_cmd(0x20 | bus_type | lines | font);
	 */
  lcd_write_cmd(0x20 | 0x10 | 0x08 | 0x00);

  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;
  lcd_write_cmd(0x08);

  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;
  lcd_write_cmd(0x01);

  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;
  lcd_write_cmd(0x06);

  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;
  lcd_write_cmd(0x0c);
}

function lcd_write_cmd(cmd)
{
  /**<
   * RS  RW  EP  D7  D6  D5  D4  D3  D2  D1  D0
   * 0   1   1   0   0   0   0   0   0   0   0
   */
  ioset('P1:' + (cmd & 0xff).toString() + ',P2:0');
  ioset('P2:|4');
  ioset('P2:&xfb');
}

function lcd_read_status()
{
  /**<
   * RS  RW  EP  D7  D6  D5  D4  D3  D2  D1  D0
   * 0   1   1   0   0   0   0   0   0   0   0
   */
  ioset('P1:0, P2:6');
  ioset('P2:&xfb');

  ///< Returns the value of the P1 port.
  return ioset(0x01);
}

function lcd_read_data()
{
  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;

  /**<
   * RS  RW  EP  D7  D6  D5  D4  D3  D2  D1  D0
   * 0   1   1   0   0   0   0   0   0   0   0
   */
}

function lcd_write_data(data)
{
  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;

  /**<
   * RS  RW  EP  D7  D6  D5  D4  D3  D2  D1  D0
   * 0   1   1   0   0   0   0   0   0   0   0
   */
  ioset('P1:' + (data & 0xff).toString() + ',P2:1');
  ioset('P2:|4');
  ioset('P2:&xfb');
}

function lcd_display_char(x, y, c)
{
  ///< Check whether should change the display line.
  if (y == 0x01)
    x |= 0x40;

  ///< Sets CGRAM address command.
  x |= 0x80;

  ///< BF flag checking. if BF is set, wait a few times unitl BF is clear.
  while (lcd_read_status() & 0x80)
    ;

  ///< Writes address set command and then writes data.
  lcd_write_cmd(x);
  lcd_write_data(c);
}

function lcd_display_string(x, y, s)
{
  ///< The LCD1602 can only display two line.
  y &= 0x01;

  ///< and up to 16 characters for each line.
  x &= 0x0f;
  for (var i = 0; i < s.length; i++)
    lcd_display_char(x++, y, s.charCodeAt(i));
}

function lcd_print(s)
{
  for (var i = 0; i < s.length; i++)
    lcd_display_char(i & 0x0f, i < 0x10 ? 0:1, s.charCodeAt(i));
}


 

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