Last active
December 24, 2018 13:56
-
-
Save DmitryMyadzelets/83b6e1384a1ee35a7f5f to your computer and use it in GitHub Desktop.
MSP430 + PCD8544-based LCD (like Nokia 5110)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//*************************************************************************************** | |
// MSP430 + PCD8544-based LCD (like Nokia 5110) | |
// | |
// MSP430x2xx Family User's Guide : http://www.ti.com/lit/ug/slau144j/slau144j.pdf | |
// MSP430G2x53 Data Sheet : http://www.ti.com/lit/ds/symlink/msp430g2553.pdf | |
// PCD8544 Data Sheet (Nokia 5110 MCU) : https://www.sparkfun.com/datasheets/LCD/Monochrome/Nokia5110.pdf | |
// | |
// My setup: | |
// | |
// NOKIA 5110 LCD MSP-EXP430G2 | |
// ----------------- ------------------- | |
// | GND|<-- Ground ------------------------------|J6 GND | | |
// | BL|<-- Back-light (not connected) | |
// | VCC|<-- Vcc +3..5V --------------------------|J1.1 VCC | | |
// | | | |
// | CLC|<-- Clock -------------------------------|J1.7 P1.5 | | |
// | DIN|<-- Data Input --------------------------|J2.15 P1.7 | | |
// | DC|<-- Data/Command (high/low) -------------|J1.3 P1.1 | | |
// | CE|<-- Chip Enable (active low) ------------|J1.2 P1.0 | | |
// | RST|<-- Reset -------------------------------|J2.16 RST | |
// | |
// | |
// This example is based on the RobG's example : http://forum.43oh.com/topic/1312-nokia-5110-display | |
// Changes: | |
// - Removed graphics function | |
// - Removed unused functions | |
// + LCD test runs in the loop | |
// + Added some bars animation | |
// | |
//*************************************************************************************** | |
#include <msp430g2553.h> | |
#include "PCD8544.h" | |
#define LCD5110_SCLK_PIN BIT5 | |
#define LCD5110_DN_PIN BIT7 | |
#define LCD5110_SCE_PIN BIT0 | |
#define LCD5110_DC_PIN BIT1 | |
#define LCD5110_SELECT P1OUT &= ~LCD5110_SCE_PIN | |
#define LCD5110_DESELECT P1OUT |= LCD5110_SCE_PIN | |
#define LCD5110_SET_COMMAND P1OUT &= ~LCD5110_DC_PIN | |
#define LCD5110_SET_DATA P1OUT |= LCD5110_DC_PIN | |
#define LCD5110_COMMAND 0 | |
#define LCD5110_DATA 1 | |
// LCD functions declaration | |
// Sets LCD address (x = 0..83, y = 0..5) | |
void setAddr(unsigned char xAddr, unsigned char yAddr); | |
void writeToLCD(unsigned char dataCommand, unsigned char data); | |
void writeCharToLCD(char c); | |
void writeStringToLCD(const char *string); | |
void initLCD(); | |
void clearLCD(); | |
void clearBank(unsigned char bank); | |
void main(void) { | |
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer | |
/* Default settings after reset: | |
* | |
* Source of the Main system clock (MCLK) and sub-main system clock (SMCLK) is | |
* Internal Digitally Controlled Oscillator Clock (DCO). | |
* MCLK is about 1 MHz. | |
* VLO is about 12 kHz. | |
* | |
* Code execution begins in less then 2 us. | |
* | |
*/ | |
P1OUT |= LCD5110_SCE_PIN | LCD5110_DC_PIN; // Disable LCD, set Data mode | |
P1DIR |= LCD5110_SCE_PIN | LCD5110_DC_PIN; // Set pins to output direction | |
// Setup USIB | |
P1SEL |= LCD5110_SCLK_PIN | LCD5110_DN_PIN; | |
P1SEL2 |= LCD5110_SCLK_PIN | LCD5110_DN_PIN; | |
UCB0CTL0 |= UCCKPH | UCMSB | UCMST | UCSYNC; // 3-pin, 8-bit SPI master | |
UCB0CTL1 |= UCSSEL_2; // SMCLK | |
UCB0BR0 |= 0x01; // 1:1 | |
UCB0BR1 = 0; | |
UCB0CTL1 &= ~UCSWRST; // clear SW | |
__delay_cycles(500000); | |
initLCD(); | |
int c; | |
while(1) { | |
clearLCD(); | |
setAddr(10, 2); | |
writeStringToLCD("Nokia 5110"); | |
__delay_cycles(2000000); | |
setAddr(0, 0); | |
// First half of the font | |
c = 0x20; | |
while(c < (65 + 0x20)) { | |
writeCharToLCD(c); | |
c++; | |
} | |
__delay_cycles(2000000); | |
clearLCD(); | |
// Second half of the font | |
c = 65 + 0x20; | |
while(c < (96 + 0x20)) { | |
writeCharToLCD(c); | |
c++; | |
} | |
// Horizontal bars | |
// Bar length can be 0..83 | |
// Fill the bar left to right | |
clearBank(3); | |
for(c = 0; c < 84; c++) { | |
writeToLCD(LCD5110_DATA, 0xFF); | |
__delay_cycles(20000); | |
} | |
// Fill the bar left to right, then clear it backward | |
clearBank(4); | |
for(c = 0; c < 50; c++) { | |
writeToLCD(LCD5110_DATA, 0xFF); | |
__delay_cycles(20000); | |
} | |
for(; c-- > 0;) { | |
setAddr(c, 4); | |
writeToLCD(LCD5110_DATA, 0); | |
__delay_cycles(20000); | |
} | |
// Fill the bar left to right, then clear it left to right | |
clearBank(5); | |
for(c = 0; c < 80; c++) { | |
writeToLCD(LCD5110_DATA, 0xFF); | |
__delay_cycles(20000); | |
} | |
setAddr(0, 5); | |
for(c = 0; c < 80; c++) { | |
writeToLCD(LCD5110_DATA, 0); | |
__delay_cycles(20000); | |
} | |
} // eof while() | |
} // eof main | |
// LCD functions implementation | |
void setAddr(unsigned char xAddr, unsigned char yAddr) { | |
writeToLCD(LCD5110_COMMAND, PCD8544_SETXADDR | xAddr); | |
writeToLCD(LCD5110_COMMAND, PCD8544_SETYADDR | yAddr); | |
} | |
void writeToLCD(unsigned char dataCommand, unsigned char data) { | |
LCD5110_SELECT; | |
if(dataCommand) { | |
LCD5110_SET_DATA; | |
} else { | |
LCD5110_SET_COMMAND; | |
} | |
UCB0TXBUF = data; | |
while(!(IFG2 & UCB0TXIFG)); | |
LCD5110_DESELECT; | |
} | |
void initLCD() { | |
writeToLCD(LCD5110_COMMAND, PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION); | |
writeToLCD(LCD5110_COMMAND, PCD8544_SETVOP | 0x3F); | |
writeToLCD(LCD5110_COMMAND, PCD8544_SETTEMP | 0x02); | |
writeToLCD(LCD5110_COMMAND, PCD8544_SETBIAS | 0x03); | |
writeToLCD(LCD5110_COMMAND, PCD8544_FUNCTIONSET); | |
writeToLCD(LCD5110_COMMAND, PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL); | |
} | |
void writeCharToLCD(char c) { | |
unsigned char i; | |
for(i = 0; i < 5; i++) { | |
writeToLCD(LCD5110_DATA, font[c - 0x20][i]); | |
} | |
writeToLCD(LCD5110_DATA, 0); | |
} | |
void writeStringToLCD(const char *string) { | |
while(*string) { | |
writeCharToLCD(*string++); | |
} | |
} | |
void clearLCD() { | |
setAddr(0, 0); | |
int i = 0; | |
while(i < PCD8544_MAXBYTES) { | |
writeToLCD(LCD5110_DATA, 0); | |
i++; | |
} | |
setAddr(0, 0); | |
} | |
void clearBank(unsigned char bank) { | |
setAddr(0, bank); | |
int i = 0; | |
while(i < PCD8544_HPIXELS) { | |
writeToLCD(LCD5110_DATA, 0); | |
i++; | |
} | |
setAddr(0, bank); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PCD8544_H_ | |
#define PCD8544_H_ | |
#define PCD8544_POWERDOWN 0x04 | |
#define PCD8544_ENTRYMODE 0x02 | |
#define PCD8544_EXTENDEDINSTRUCTION 0x01 | |
#define PCD8544_DISPLAYBLANK 0x0 | |
#define PCD8544_DISPLAYNORMAL 0x4 | |
#define PCD8544_DISPLAYALLON 0x1 | |
#define PCD8544_DISPLAYINVERTED 0x5 | |
// H = 0 | |
#define PCD8544_FUNCTIONSET 0x20 | |
#define PCD8544_DISPLAYCONTROL 0x08 | |
#define PCD8544_SETYADDR 0x40 | |
#define PCD8544_SETXADDR 0x80 | |
#define PCD8544_HPIXELS 84 | |
#define PCD8544_VBANKS 6 | |
#define PCD8544_MAXBYTES 504 // PCD8544_HPIXELS * PCD8544_VBANKS | |
// H = 1 | |
#define PCD8544_SETTEMP 0x04 | |
#define PCD8544_SETBIAS 0x10 | |
#define PCD8544_SETVOP 0x80 | |
static const char font[][5] = { // basic font | |
{0x00, 0x00, 0x00, 0x00, 0x00} // 20 | |
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 ! | |
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 " | |
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 # | |
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $ | |
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 % | |
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 & | |
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ' | |
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 ( | |
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 ) | |
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a * | |
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b + | |
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c , | |
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d - | |
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e . | |
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f / | |
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0 | |
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1 | |
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2 | |
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3 | |
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4 | |
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5 | |
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6 | |
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7 | |
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8 | |
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9 | |
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a : | |
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ; | |
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c < | |
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d = | |
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e > | |
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ? | |
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @ | |
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A | |
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B | |
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C | |
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D | |
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E | |
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F | |
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G | |
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H | |
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I | |
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J | |
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K | |
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L | |
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M | |
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N | |
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O | |
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P | |
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q | |
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R | |
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S | |
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T | |
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U | |
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V | |
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W | |
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X | |
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y | |
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z | |
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [ | |
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥ | |
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ] | |
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^ | |
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _ | |
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 ` | |
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a | |
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b | |
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c | |
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d | |
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e | |
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f | |
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g | |
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h | |
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i | |
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j | |
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k | |
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l | |
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m | |
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n | |
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o | |
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p | |
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q | |
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r | |
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s | |
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t | |
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u | |
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v | |
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w | |
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x | |
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y | |
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z | |
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b { | |
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c | | |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d } | |
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ~ | |
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f Deg Symbol | |
}; | |
#endif /*PCD8544_H_*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment