MSP430 2013 with 3310 Nokia LCD

I’ve started playing with the Nokia 3310 LCD. It’s similar to the LCD I used in my watch project but is black and white only. It’s a little clearer to read, and hopefully consumes less power.

I’d ordered a pack of 7 nokia 3310 LCDs from the internet. However after I disassembled the nokia packaging I noticed there were actually 3 different LCD types present:

One didn’t have metal contacts, only glass ones. The other, with the smaller IC I spent a long time fiddling with, and couldn’t get anything to display on. It could be that my wiring was dodgy but I’ve also known LCDs for the same phone to behave differently. Nokia have been known to use different LCDs in their phones and include detection logic to figure out how to drive it. Anyway… the LCD with the larger controller worked, and if you are considering using a 3310 display I’d recommend you try and find this type.

I used the code from here as my basis. I removed a lot of his project specific logic and added my own simple test code.

Here’s the setup:

That cap does seem to be required. The 3510i LCD works without one, I might do some more experimentation with this.

And here’s what the code outputs:

And here’s the code! Again, largely due to TopHatHacker, with some trimming down and a few modifications:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#define F_CPU 1000000UL
 
#include <io.h>
#include <signal.h>
 
#define SEND_CMD                   0
#define SEND_CHR                   1
 
#define LCD_X_RES                  84
#define LCD_Y_RES                  48
 
#define COUNTDOWN          1
 
// defines for 4250 pin connections to Nokia 3310
#define SCEPORT P1OUT
#define SDINPORT P1OUT
#define DCPORT P1OUT
#define SCKPORT P1OUT
#define RESPORT P1OUT
#define SCE  BIT5 // LCD pin 5 (enable)
#define SDIN BIT3 // LCD pin 3 (data)
#define DC   BIT4 // LCD pin 4 (Data enabled)
#define SCK  BIT1 // LCD pin 2 (Data clock)
#define RES  BIT2 // LCD pin 8 (reset)
 
void LCDSend(unsigned char,unsigned char);
void LCDClear(void);
void LCDInit(void);
void LCDBlack(void);
void LCDCurs(unsigned char,unsigned char);
 
void LCDSend(unsigned char data, unsigned char cd) {
 
  volatile unsigned char bits;
  unsigned short cnt=8;
  // assume clk is hi
  // Enable display controller (active low).
  SCEPORT &amp;amp;amp;amp;= ~SCE;  //RESET SCE
 
  // command or data
  if(cd == SEND_CHR) {
    DCPORT |= DC;  //set to send data
  }
  else // reset to send command
    DCPORT &amp;amp;amp;amp;= ~DC;
  }
 
  ///// SEND SPI /////
  bits=0x80; // bits is mask to select bit to send. select bit msb first
  
  //send data
  while (0<cnt--)
  {
    // put bit on line
    // cycle clock
    SCKPORT &amp;amp;amp;amp;= ~SCK;
    if ((data &amp;amp;amp;amp; bits)>0) SDINPORT |= SDIN; else SDINPORT &amp;amp;amp;amp;= ~SDIN;
    //Delay(1);
    SCKPORT |= SCK;
    //Delay(2);
    // SHIFT BIT MASK 1 right
    bits >>= 1;
  }
    
  // Disable display controller.
  SCEPORT |= SCE;
 
}
 
void LCDClear(void) {
  int i,j;
       
  LCDSend(0x80, SEND_CMD );
  LCDSend(0x40, SEND_CMD );
   
  for (i=0;i<6;i++)  // number of rows
    for (j=0;j<LCD_X_RES;j++)  // number of columns
      LCDSend(0x00, SEND_CHR);
}
 
void LCDInit(void)
{ // assume ports set up and initialized to output
 
  // Reset LCD
  SCEPORT &amp;amp;amp;amp;= ~SCE;          // RESET SCE to enable
  // toggle RES
  RESPORT |= RES;           // Set RES
  char l;
  for(l=0;l<100;l++)
    l=l;
  RESPORT &amp;amp;amp;amp;= ~RES;          // reset RES
  for(l=0;l<100;l++)
    l=l;
  RESPORT |= RES;           // Set RES
   
  // Cycle Clock
  SCKPORT &amp;amp;amp;amp;= ~SCK;
  SCKPORT |= SCK;
  
 // Disable display controller.
  SCEPORT |= SCE;           // bring high to disable
   
  for(l=0;l<100;l++)
    l=l;
 
  // Send sequence of command
  LCDSend( 0x21, SEND_CMD );  // LCD Extended Commands.
  LCDSend( 0xC8, SEND_CMD );  // Set LCD Vop (Contrast).
  LCDSend( 0x06, SEND_CMD );  // Set Temp coefficent to 2.
  LCDSend( 0x13, SEND_CMD );  // LCD bias mode 1:100.
  LCDSend( 0x20, SEND_CMD );  // LCD Standard Commands, Horizontal addressing mode.
  LCDSend( 0x08, SEND_CMD );  // LCD blank
  LCDSend( 0x0C, SEND_CMD );  // LCD in inverse mode.
   
  LCDClear();
 
}
 
void lcdcontrast(char c) {
  LCDSend( 0x21, SEND_CMD );  // LCD Extended Commands.
  LCDSend( c, SEND_CMD );  // Set LCD Vop (Contrast).
  LCDSend( 0x20, SEND_CMD );  // LCD Standard Commands, Horizontal addressing mode.
}
 
void LCDCurs(unsigned char x, unsigned char y)
{
  LCDSend(0x80|x,SEND_CMD);
  LCDSend(0x40|y,SEND_CMD);
}
 
void LCDDot()
{
  int lm;
  LCDSend(0x00,SEND_CHR);
  LCDSend(0x00,SEND_CHR);
  LCDSend(0x00,SEND_CHR);
  for(lm=0;lm<3;lm++)
    LCDSend(0xFF,SEND_CHR);
}
 
int main(void)
{
  WDTCTL = WDTPW + WDTHOLD; // Stop WDT
  P1DIR = 0xFF;
   
  BCSCTL1 = CALBC1_1MHZ;                   // Set range
  DCOCTL = CALDCO_1MHZ;                    // Set DCO step + modulation
   
  BCSCTL2 = 0xF8;
  BCSCTL3 = LFXT1S_0 + XCAP_3;
   
  CCTL0 = CCIE;
  CCR0 = 0;
  TACCR0 = 0x3FF;
  TACTL = 0x0211;
   
  LCDInit();
   
  _BIS_SR(GIE);
 
  // draw cross pattern
  char v = 0xAA;
  for(int x=0;x<((84*48)/8);x++) {
    LCDSend(v,SEND_CHR);
    v = v ^ 0xFF;
  }
  for(;;);
}
&#91;/sourcecode&#93;
 
<h2>Notes</h2>
 
MSP430 pinout:
 
<a href="http://41j.com/blog/wp-content/uploads/2011/09/MSP430F2011-pinout.jpg"><img src="http://41j.com/blog/wp-content/uploads/2011/09/MSP430F2011-pinout.jpg" alt="" title="MSP430F2011-pinout" width="398" height="129" class="aligncenter size-full wp-image-241" /></a>
 
LCD pinout and AVR code <a href="http://www.quantumtorque.com/content/view/32/37/">here</a>.
 
Other 3310 projects:
 
With a larger MSP430: <a href="http://tophathacker.com/?p=40">here</a> and <a href="http://320volt.com/msp430-nokia-3310-lcd-direnc-hesaplayici-yeniden/">here</a>
 
Various nokia LCD pinouts <a href="http://www.module.ro/nokia_3510.html">here</a>
 
The code is compiled as:
 
[sourcecode language="bash"]
~/msp430/bin/msp430-gcc -Os -Wall -mmcu=msp430x2013 -std=gnu99 -o main.elf main.o

MSPDebug is used to program the device. run as:

1
mspdebug uif -d /dev/ttyUSB0

MSPDebug is launched type: prog main.elf to program, run to run.

One Comment

  1. Anonymous says:

    hola disculpa me podrias explicar como van conectados los cables por ejemplo:
    el pin 6 de la pantalla ca conectado en el Pin14 del Msp430.. gracias asta luego espero tu respuesta
    mi correo es jassut_13@hotmail.com

Leave a Reply