PCD8544 Driver for an LCD with an PCD8544 controller (e.g. Nokia 3310, 3390)

Dependents:   PCD8544_LCD

Files at this revision

API Documentation at this revision

Comitter:
carlosftm
Date:
Sun Jan 02 11:50:35 2011 +0000
Child:
1:9948e71af151
Commit message:
Library with Text support only (14x6 characters)

Changed in this revision

ascii_table.hpp Show annotated file Show diff for this revision Revisions of this file
pcd8544_drv.cpp Show annotated file Show diff for this revision Revisions of this file
pcd8544_drv.hpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ascii_table.hpp	Sun Jan 02 11:50:35 2011 +0000
@@ -0,0 +1,99 @@
+/* *******************************************
+* Standard ASCII characters in a 5x7 dot format
+* Table taken from Montec webpage.
+* http://www.amontec.com/lcd_nokia_3310.shtml
+********************************************* */
+static const char ascii_table[][5] =
+{
+   { 0x00, 0x00, 0x00, 0x00, 0x00 },  // sp
+   { 0x00, 0x00, 0x2f, 0x00, 0x00 },  // !
+   { 0x00, 0x07, 0x00, 0x07, 0x00 },  // "
+   { 0x14, 0x7f, 0x14, 0x7f, 0x14 },  // #
+   { 0x24, 0x2a, 0x7f, 0x2a, 0x12 },  // $
+   { 0xc4, 0xc8, 0x10, 0x26, 0x46 },  // %
+   { 0x36, 0x49, 0x55, 0x22, 0x50 },  // &
+   { 0x00, 0x05, 0x03, 0x00, 0x00 },  // '
+   { 0x00, 0x1c, 0x22, 0x41, 0x00 },  // (
+   { 0x00, 0x41, 0x22, 0x1c, 0x00 },  // )
+   { 0x14, 0x08, 0x3E, 0x08, 0x14 },  // *
+   { 0x08, 0x08, 0x3E, 0x08, 0x08 },  // +
+   { 0x00, 0x00, 0x50, 0x30, 0x00 },  // ,
+   { 0x10, 0x10, 0x10, 0x10, 0x10 },  // -
+   { 0x00, 0x60, 0x60, 0x00, 0x00 },  // .
+   { 0x20, 0x10, 0x08, 0x04, 0x02 },  // /
+   { 0x3E, 0x51, 0x49, 0x45, 0x3E },  // 0
+   { 0x00, 0x42, 0x7F, 0x40, 0x00 },  // 1
+   { 0x42, 0x61, 0x51, 0x49, 0x46 },  // 2
+   { 0x21, 0x41, 0x45, 0x4B, 0x31 },  // 3
+   { 0x18, 0x14, 0x12, 0x7F, 0x10 },  // 4
+   { 0x27, 0x45, 0x45, 0x45, 0x39 },  // 5
+   { 0x3C, 0x4A, 0x49, 0x49, 0x30 },  // 6
+   { 0x01, 0x71, 0x09, 0x05, 0x03 },  // 7
+   { 0x36, 0x49, 0x49, 0x49, 0x36 },  // 8
+   { 0x06, 0x49, 0x49, 0x29, 0x1E },  // 9
+   { 0x00, 0x36, 0x36, 0x00, 0x00 },  // :
+   { 0x00, 0x56, 0x36, 0x00, 0x00 },  // ;
+   { 0x08, 0x14, 0x22, 0x41, 0x00 },  // <
+   { 0x14, 0x14, 0x14, 0x14, 0x14 },  // =
+   { 0x00, 0x41, 0x22, 0x14, 0x08 },  // >
+   { 0x02, 0x01, 0x51, 0x09, 0x06 },  // ?
+   { 0x32, 0x49, 0x59, 0x51, 0x3E },  // @
+   { 0x7E, 0x11, 0x11, 0x11, 0x7E },  // A
+   { 0x7F, 0x49, 0x49, 0x49, 0x36 },  // B
+   { 0x3E, 0x41, 0x41, 0x41, 0x22 },  // C
+   { 0x7F, 0x41, 0x41, 0x22, 0x1C },  // D
+   { 0x7F, 0x49, 0x49, 0x49, 0x41 },  // E
+   { 0x7F, 0x09, 0x09, 0x09, 0x01 },  // F
+   { 0x3E, 0x41, 0x49, 0x49, 0x7A },  // G
+   { 0x7F, 0x08, 0x08, 0x08, 0x7F },  // H
+   { 0x00, 0x41, 0x7F, 0x41, 0x00 },  // I
+   { 0x20, 0x40, 0x41, 0x3F, 0x01 },  // J
+   { 0x7F, 0x08, 0x14, 0x22, 0x41 },  // K
+   { 0x7F, 0x40, 0x40, 0x40, 0x40 },  // L
+   { 0x7F, 0x02, 0x0C, 0x02, 0x7F },  // M
+   { 0x7F, 0x04, 0x08, 0x10, 0x7F },  // N
+   { 0x3E, 0x41, 0x41, 0x41, 0x3E },  // O
+   { 0x7F, 0x09, 0x09, 0x09, 0x06 },  // P
+   { 0x3E, 0x41, 0x51, 0x21, 0x5E },  // Q
+   { 0x7F, 0x09, 0x19, 0x29, 0x46 },  // R
+   { 0x46, 0x49, 0x49, 0x49, 0x31 },  // S
+   { 0x01, 0x01, 0x7F, 0x01, 0x01 },  // T
+   { 0x3F, 0x40, 0x40, 0x40, 0x3F },  // U
+   { 0x1F, 0x20, 0x40, 0x20, 0x1F },  // V
+   { 0x3F, 0x40, 0x38, 0x40, 0x3F },  // W
+   { 0x63, 0x14, 0x08, 0x14, 0x63 },  // X
+   { 0x07, 0x08, 0x70, 0x08, 0x07 },  // Y
+   { 0x61, 0x51, 0x49, 0x45, 0x43 },  // Z
+   { 0x00, 0x7F, 0x41, 0x41, 0x00 },  // [
+   { 0x55, 0x2A, 0x55, 0x2A, 0x55 },  // 55
+   { 0x00, 0x41, 0x41, 0x7F, 0x00 },  // ]
+   { 0x04, 0x02, 0x01, 0x02, 0x04 },  // ^
+   { 0x40, 0x40, 0x40, 0x40, 0x40 },  // _
+   { 0x00, 0x01, 0x02, 0x04, 0x00 },  // '
+   { 0x20, 0x54, 0x54, 0x54, 0x78 },  // a
+   { 0x7F, 0x48, 0x44, 0x44, 0x38 },  // b
+   { 0x38, 0x44, 0x44, 0x44, 0x20 },  // c
+   { 0x38, 0x44, 0x44, 0x48, 0x7F },  // d
+   { 0x38, 0x54, 0x54, 0x54, 0x18 },  // e
+   { 0x08, 0x7E, 0x09, 0x01, 0x02 },  // f
+   { 0x0C, 0x52, 0x52, 0x52, 0x3E },  // g
+   { 0x7F, 0x08, 0x04, 0x04, 0x78 },  // h
+   { 0x00, 0x44, 0x7D, 0x40, 0x00 },  // i
+   { 0x20, 0x40, 0x44, 0x3D, 0x00 },  // j
+   { 0x7F, 0x10, 0x28, 0x44, 0x00 },  // k
+   { 0x00, 0x41, 0x7F, 0x40, 0x00 },  // l
+   { 0x7C, 0x04, 0x18, 0x04, 0x78 },  // m
+   { 0x7C, 0x08, 0x04, 0x04, 0x78 },  // n
+   { 0x38, 0x44, 0x44, 0x44, 0x38 },  // o
+   { 0x7C, 0x14, 0x14, 0x14, 0x08 },  // p
+   { 0x08, 0x14, 0x14, 0x18, 0x7C },  // q
+   { 0x7C, 0x08, 0x04, 0x04, 0x08 },  // r
+   { 0x48, 0x54, 0x54, 0x54, 0x20 },  // s
+   { 0x04, 0x3F, 0x44, 0x40, 0x20 },  // t
+   { 0x3C, 0x40, 0x40, 0x20, 0x7C },  // u
+   { 0x1C, 0x20, 0x40, 0x20, 0x1C },  // v
+   { 0x3C, 0x40, 0x30, 0x40, 0x3C },  // w
+   { 0x44, 0x28, 0x10, 0x28, 0x44 },  // x
+   { 0x0C, 0x50, 0x50, 0x50, 0x3C },  // y
+   { 0x44, 0x64, 0x54, 0x4C, 0x44 }   // z
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pcd8544_drv.cpp	Sun Jan 02 11:50:35 2011 +0000
@@ -0,0 +1,144 @@
+/* ********************************************
+* PCD8544 Driver for an LCD with an PCD8544
+* controller.
+* Note: Text mode supported only.
+*
+* Created on: 12/31/2010 at 19:48
+* Created by: CarlosFTM
+********************************************** */
+
+#include "mbed.h"
+#include "pcd8544_drv.hpp"
+
+pcd8544::pcd8544(PinName pin_sclk, PinName pin_mosi, PinName pin_dc, PinName pin_sce, PinName pin_reset) :  _sclk(pin_sclk),
+                                                                                                            _mosi(pin_mosi),
+                                                                                                            _dc(pin_dc),
+                                                                                                            _sce(pin_sce),
+                                                                                                            _reset(pin_reset)
+{
+  /* Set all pins to initial state */
+  _sce   = HIGH;
+  _reset = HIGH;
+  _sclk  = LOW;
+}
+
+/* Transmits a single byte to the LCD */
+void pcd8544::sendByte(char byte, bool command)
+{
+  int loop;
+  _dc  = !command;
+  _sce = LOW;
+  for (loop = 0; loop < 8; loop++)
+  {
+    _mosi = ((byte << loop) & 0x80); // TX starts from MSB
+    clockTick(TICK);
+  }
+  _sce = HIGH;
+}
+
+/* Writes a data byte into LCD RAM*/
+void pcd8544::writeData(char data)
+{
+  sendByte(data, false);
+}
+
+/* Sends a command to the LCD */
+void pcd8544::writeCmd(char cmd)
+{
+  sendByte(cmd, true);
+}
+
+/* Writes a ASCII character into LCD RAM */
+void pcd8544::writeChar(char character)
+{
+  char loop = 0;
+
+  if ((character >= 32) && (character <= 122))
+  {
+    character = character - 32;
+  }
+  else
+  {
+    character = 0x00;
+  }
+
+  for (loop = 0; loop < 5; loop++)
+  {
+    sendByte(ascii_table[character][loop], false);
+  }
+  sendByte(0x00, false);
+}
+
+/* Writes a string of characters into LCD RAM */
+void pcd8544::writeString(char* character)
+{
+  while (*character)
+  {
+    writeChar(char(*character));
+    character++;
+  }
+}
+
+/* Resets the LCD*/
+void pcd8544::resetLCD()
+{
+  int loop;
+  _sce   = LOW;
+  wait_us(TICK);
+  _reset = LOW;
+  for (loop = 0; loop < RESET_TICKS; loop++)
+  {
+    clockTick(TICK);
+  }
+  _reset = HIGH;
+  wait_us(TICK);
+  _sce = HIGH;
+}
+
+/* Clear the LCD RAM*/
+void pcd8544::clearLCD()
+{
+  writeCmd(0x80); // Set X ram-address to 0x00
+  writeCmd(0x40); // Set Y ram-address to 0x00
+
+  int loop = 0;
+  
+  for (loop = 0; loop < (MAX_PIX_X * CHAR_PIX_X); loop++)
+  {
+    writeData(0x00); // Write empty character
+  }
+  /* Set cursor to position 0,0 */
+  writeCmd(0x80); // Set X ram-address to 0x00
+  writeCmd(0x40); // Set Y ram-address to 0x00
+}
+
+/* Initialize the LCD with default values */
+void pcd8544::initLCD(void)
+{
+  writeCmd(0x90);  // Set Vop as in PCD8544 specs example
+  writeCmd(0x20);  // Normal instruction set. Horizontal addressing.
+  writeCmd(0x0C);  // display in normal mode
+
+  /* Set cursor to position 0,0 */
+  writeCmd(0x80); // Set X ram-address to 0x00
+  writeCmd(0x40); // Set Y ram-address to 0x00
+}
+
+
+/* Sends a clock tick to the LCD */
+inline void pcd8544::clockTick(unsigned short useg)
+{  
+    _sclk = LOW;
+    wait_us(useg);
+    _sclk = HIGH;
+    wait_us(useg);
+}
+
+/* Set the cursor position on specific character position x,y*/
+void pcd8544::setCursorXY(char x, char y)
+{
+  x = (((x % MAX_CHAR_X) * CHAR_PIX_X) | SET_ADDRES_X);
+  y = ((y % MAX_CHAR_Y)  | SET_ADDRES_Y);
+  writeCmd(x); // Set X ram-address to x
+  writeCmd(y); // Set Y ram-address to y
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pcd8544_drv.hpp	Sun Jan 02 11:50:35 2011 +0000
@@ -0,0 +1,132 @@
+/**
+ * @file pcd8544_drv.hpp
+ * PCD8544 Driver for an LCD with an PCD8544 controller.
+ * Note: Text mode supported only.
+ *
+ * Created on: 12/31/2010 at 19:48
+ * @author: CarlosFTM
+ */
+
+#include "mbed.h"
+#include "ascii_table.hpp"
+
+/* Number of pixels on the LCD */
+#define MAX_PIX_X  (84)
+#define MAX_PIX_Y  (48)
+
+/* Size of a caracter displayed on the LCD */
+#define CHAR_PIX_X (6)
+#define CHAR_PIX_Y (8)
+
+/* Maximum number of character displayed on the LCD*/
+#define MAX_CHAR_X (MAX_PIX_X / CHAR_PIX_X)
+#define MAX_CHAR_Y (MAX_PIX_Y / CHAR_PIX_Y)
+
+/* Timming constants*/
+#define TICK        (1) // Clock pulse width in useg
+#define RESET_TICKS (8) // number of ticks for reset
+
+/* Digital output assignament*/
+#define pin_sclk    (p21)
+#define pin_mosi    (p22)
+#define pin_dc      (p23)
+#define pin_sce     (p24)
+#define pin_reset   (p25)
+
+/* Digital output logicla level*/
+#define HIGH (1)
+#define LOW  (0)
+
+/* Display control command */
+#define DISPLAY_BLANK (0x08)
+#define NORMAL_MODE   (0x0C)
+#define ALL_SEG_ON    (0x09)
+#define INVERSE_MODE  (0x0D)
+
+#define SET_ADDRES_X  (0x80)
+#define SET_ADDRES_Y  (0x40)
+
+
+/** Creates an interface to the PCD8544 LCD controller
+ *
+ */
+class pcd8544
+{
+  private:
+    DigitalOut _sclk;
+    DigitalOut _mosi;
+    DigitalOut _dc;
+    DigitalOut _sce;
+    DigitalOut _reset;
+    /** Sends a raw byte to the LCD controller
+    *
+    * @param byte to send, boolean to indicate if it is a coomand (Command = TRUE / Data = FALSE).
+    */
+    void sendByte(char byte, bool command);
+    
+    /** Generates a clock tick
+    *
+    * @param pulse width in useg
+    */
+    inline void clockTick(unsigned short useg);
+
+  public:
+  
+    /** Creates an interface to the LCD
+    *
+    * @param PinName for SCLK
+    * @param PinName for MOSI
+    * @param PinName for DC
+    * @param PinName for SCE
+    * @param PinName for RESET
+    */
+    pcd8544(PinName pin_sclk, PinName pin_mosi, PinName pin_dc, PinName pin_sce, PinName pin_reset);
+
+    /** Writes data into the LCD controller
+    *
+    * @param data to be transmited in byte
+    */
+    void writeData(char data);
+
+    /** Writes a command into the LCD controller
+    *
+    * @param command in byte
+    */
+    void writeCmd(char cmd);
+
+    /** Writes a character into the LCD controller
+    *
+    * @param Character to be written in byte
+    */
+    void writeChar(char character);
+
+    /** Writes a string into LCD
+    *
+    * @param pointer to a character string
+    */
+    void writeString(char* character);
+
+    /** Reset the LCD
+    *
+    * @param none
+    */
+    void resetLCD(void);
+
+    /** Initialize the LCD
+    *
+    * @param none
+    */
+    void initLCD(void);
+
+    /** Clear the LCD screen
+    *
+    * @param none
+    */
+    void clearLCD(void);
+
+    /** Set the cursor to a specific position
+    *
+    * @param X and Y position in characters
+    */
+    void setCursorXY(char x, char y);
+};
\ No newline at end of file