1 | #include "msp430.h"
|
2 |
|
3 | #define LCM_DIR P2DIR
|
4 | #define LCM_OUT P2OUT
|
5 |
|
6 | //
|
7 |
|
8 | #define LCM_PIN_RS BIT0 // P2.0
|
9 | #define LCM_PIN_EN BIT1 // P2.1
|
10 | #define LCM_PIN_D7 BIT5 // P2.5
|
11 | #define LCM_PIN_D6 BIT4 // P2.4
|
12 | #define LCM_PIN_D5 BIT3 // P2.3
|
13 | #define LCM_PIN_D4 BIT2 // P2.2
|
14 |
|
15 |
|
16 |
|
17 | #define LCM_PIN_MASK ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 |
|
18 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4))
|
19 |
|
20 | #define FALSE 0
|
21 | #define TRUE 1
|
22 |
|
23 | //
|
24 | // Routine Desc:
|
25 | //
|
26 | // This is the function that must be called
|
27 | // whenever the LCM needs to be told to
|
28 | // scan it's data bus.
|
29 | //
|
30 | // Parameters:
|
31 | //
|
32 | // void.
|
33 | //
|
34 | // Return
|
35 | //
|
36 | // void.
|
37 | //
|
38 | void PulseLcm()
|
39 | {
|
40 | //
|
41 | // pull EN bit low
|
42 | //
|
43 | LCM_OUT &= ~LCM_PIN_EN;
|
44 | __delay_cycles(200);
|
45 |
|
46 | //
|
47 | // pull EN bit high
|
48 | //
|
49 | LCM_OUT |= LCM_PIN_EN;
|
50 | __delay_cycles(200);
|
51 |
|
52 | //
|
53 | // pull EN bit low again
|
54 | //
|
55 | LCM_OUT &= (~LCM_PIN_EN);
|
56 | __delay_cycles(200);
|
57 | }
|
58 |
|
59 |
|
60 |
|
61 | //
|
62 | // Routine Desc:
|
63 | //
|
64 | // Send a byte on the data bus in the 4 bit mode
|
65 | // This requires sending the data in two chunks.
|
66 | // The high nibble first and then the low nible
|
67 | //
|
68 | // Parameters:
|
69 | //
|
70 | // ByteToSend - the single byte to send
|
71 | //
|
72 | // IsData - set to TRUE if the byte is character data
|
73 | // FALSE if its a command
|
74 | //
|
75 | // Return
|
76 | //
|
77 | // void.
|
78 | //
|
79 | void SendByte(char ByteToSend, int IsData)
|
80 | {
|
81 | //
|
82 | // clear out all pins
|
83 | //
|
84 | LCM_OUT &= (~LCM_PIN_MASK);
|
85 | //
|
86 | // set High Nibble (HN) -
|
87 | // usefulness of the identity mapping
|
88 | // apparent here. We can set the
|
89 | // DB7 - DB4 just by setting P1.7 - P1.4
|
90 | // using a simple assignment
|
91 | //
|
92 | LCM_OUT |= (ByteToSend & 0x3C);
|
93 |
|
94 | if (IsData == TRUE)
|
95 | {
|
96 | LCM_OUT |= LCM_PIN_RS;
|
97 | }
|
98 | else
|
99 | {
|
100 | LCM_OUT &= ~LCM_PIN_RS;
|
101 | }
|
102 |
|
103 | //
|
104 | // we've set up the input voltages to the LCM.
|
105 | // Now tell it to read them.
|
106 | //
|
107 | PulseLcm();
|
108 | //
|
109 | // set Low Nibble (LN) -
|
110 | // usefulness of the identity mapping
|
111 | // apparent here. We can set the
|
112 | // DB7 - DB4 just by setting P1.7 - P1.4
|
113 | // using a simple assignment
|
114 | //
|
115 | LCM_OUT &= (~LCM_PIN_MASK);
|
116 | LCM_OUT |= ((ByteToSend & 0x0F) << 4);
|
117 |
|
118 | if (IsData == TRUE)
|
119 | {
|
120 | LCM_OUT |= LCM_PIN_RS;
|
121 | }
|
122 | else
|
123 | {
|
124 | LCM_OUT &= ~LCM_PIN_RS;
|
125 | }
|
126 |
|
127 | //
|
128 | // we've set up the input voltages to the LCM.
|
129 | // Now tell it to read them.
|
130 | //
|
131 | PulseLcm();
|
132 | }
|
133 |
|
134 |
|
135 | //
|
136 | // Routine Desc:
|
137 | //
|
138 | // Set the position of the cursor on the screen
|
139 | //
|
140 | // Parameters:
|
141 | //
|
142 | // Row - zero based row number
|
143 | //
|
144 | // Col - zero based col number
|
145 | //
|
146 | // Return
|
147 | //
|
148 | // void.
|
149 | //
|
150 | void LcmSetCursorPosition(char Row, char Col)
|
151 | {
|
152 | char address;
|
153 |
|
154 | //
|
155 | // construct address from (Row, Col) pair
|
156 | //
|
157 | if (Row == 0)
|
158 | {
|
159 | address = 0;
|
160 | }
|
161 | else
|
162 | {
|
163 | address = 0x40;
|
164 | }
|
165 |
|
166 | address |= Col;
|
167 |
|
168 | SendByte(0x80 | address, FALSE);
|
169 | }
|
170 |
|
171 |
|
172 | //
|
173 | // Routine Desc:
|
174 | //
|
175 | // Clear the screen data and return the
|
176 | // cursor to home position
|
177 | //
|
178 | // Parameters:
|
179 | //
|
180 | // void.
|
181 | //
|
182 | // Return
|
183 | //
|
184 | // void.
|
185 | //
|
186 | void ClearLcmScreen()
|
187 | {
|
188 | //
|
189 | // Clear display, return home
|
190 | //
|
191 | SendByte(0x01, FALSE);
|
192 | SendByte(0x02, FALSE);
|
193 | }
|
194 |
|
195 |
|
196 | //
|
197 | // Routine Desc:
|
198 | //
|
199 | // Initialize the LCM after power-up.
|
200 | //
|
201 | // Note: This routine must not be called twice on the
|
202 | // LCM. This is not so uncommon when the power
|
203 | // for the MCU and LCM are separate.
|
204 | //
|
205 | // Parameters:
|
206 | //
|
207 | // void.
|
208 | //
|
209 | // Return
|
210 | //
|
211 | // void.
|
212 | //
|
213 | void InitializeLcm(void)
|
214 | {
|
215 | //
|
216 | // set the MSP pin configurations
|
217 | // and bring them to low
|
218 | //
|
219 | LCM_DIR |= LCM_PIN_MASK;
|
220 | LCM_OUT &= ~(LCM_PIN_MASK);
|
221 |
|
222 |
|
223 | //
|
224 | // wait for the LCM to warm up and reach
|
225 | // active regions. Remember MSPs can power
|
226 | // up much faster than the LCM.
|
227 | //
|
228 | __delay_cycles(100000);
|
229 |
|
230 |
|
231 | //
|
232 | // initialize the LCM module
|
233 | //
|
234 | // 1. Set 4-bit input
|
235 | //
|
236 | LCM_OUT &= ~LCM_PIN_RS;
|
237 | LCM_OUT &= ~LCM_PIN_EN;
|
238 |
|
239 | LCM_OUT = 0x20;
|
240 | PulseLcm();
|
241 |
|
242 | //
|
243 | // set 4-bit input - second time.
|
244 | // (as reqd by the spec.)
|
245 | //
|
246 | SendByte(0x28, FALSE);
|
247 |
|
248 | //
|
249 | // 2. Display on, cursor on, blink cursor
|
250 | //
|
251 | SendByte(0x0E, FALSE);
|
252 |
|
253 | //
|
254 | // 3. Cursor move auto-increment
|
255 | //
|
256 | SendByte(0x06, FALSE);
|
257 | }
|
258 |
|
259 |
|
260 | //
|
261 | // Routine Desc
|
262 | //
|
263 | // Print a string of characters to the screen
|
264 | //
|
265 | // Parameters:
|
266 | //
|
267 | // Text - null terminated string of chars
|
268 | //
|
269 | // Returns
|
270 | //
|
271 | // void.
|
272 | //
|
273 | void PrintStr(char *Text)
|
274 | {
|
275 | char *c;
|
276 |
|
277 | c = Text;
|
278 |
|
279 | while ((c != 0) && (*c != 0))
|
280 | {
|
281 | SendByte(*c, TRUE);
|
282 | c++;
|
283 | }
|
284 | }
|
285 |
|
286 |
|
287 | //
|
288 | // Routine Desc
|
289 | //
|
290 | // main entry point to the sketch
|
291 | //
|
292 | // Parameters
|
293 | //
|
294 | // void.
|
295 | //
|
296 | // Returns
|
297 | //
|
298 | // void.
|
299 | //
|
300 | void main(void)
|
301 | {
|
302 | WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
303 |
|
304 | InitializeLcm();
|
305 |
|
306 | ClearLcmScreen();
|
307 |
|
308 | PrintStr("Hello World!");
|
309 |
|
310 | while (1)
|
311 | {
|
312 | __delay_cycles(1000);
|
313 | }
|
314 |
|
315 | }
|