📄 lcdinterface.lst
字号:
187 1 SYSCLK_Init(); // initialize the oscillator
188 1 Port_IO_Init(); // initialize the ports
189 1 Timer2_Init (SYSCLK / TIMER2_RATE); // enable timer to interrupt at some Hz
190 1 Timer3_Init (SYSCLK / TIMER3_RATE); // enable timer to overflow at some Hz
191 1
192 1 // We first configure the COM ports to analog inputs. This allows us
193 1 // to set them to high impedance if we write a 1 to the COM port. Along with
194 1 // some external resistors, we can then create a VDD/2 voltage. When it is
195 1 // time for the corresponding COM cycle, we can set the pin to push-pull and
196 1 // drive the output to VDD or GND. These 3 levels (VDD, VDD/2, GND) are
197 1 // necessary only for the backplane (Common) pins on the LCD
198 1
199 1 COM1 = 1; // high impedance
200 1 COM2 = 1; // high impedance
201 1 COM3 = 1; // high impedance
202 1 COM4 = 1; // high impedance
203 1 RCLK = 0; // don't output anything to LCD
204 1 SRCLK = 0; // don't shift anything to registers yet
205 1
206 1 EA = 1; // enable global interrupts
207 1
208 1 while (1)
209 1 {
210 2 printf ("\nHELLO");
211 2
212 2 wait_one_ms (1000);
213 2
214 2 printf ("\n");
215 2
216 2 wait_one_ms (1000);
217 2 }
218 1 }
219
220
221 //-----------------------------------------------------------------------------
222 // Init Functions
223 //-----------------------------------------------------------------------------
224
225 //-----------------------------------------------------------------------------
226 // SYSCLK_Init
227 //-----------------------------------------------------------------------------
228 //
229 // This routine initializes the system clock to use the internal 24.5MHz
230 // oscillator as its clock source. Also enables missing clock detector reset.
231 //
232 void SYSCLK_Init (void)
233 {
234 1 OSCICN |= 0x03; // Configure internal osc to max freq
235 1 RSTSRC = 0x04; // Enable missing clock detector
236 1 }
237
238
239 //-----------------------------------------------------------------------------
240 // Port_IO_init
241 //-----------------------------------------------------------------------------
C51 COMPILER V8.02 LCDINTERFACE 03/15/2009 20:48:19 PAGE 5
242 //
243 // This routine initializes the ports and enables the crossbar
244 //
245 void Port_IO_Init(void)
246 {
247 1 // P0.0 - Unassigned, Open-Drain, Digital
248 1 // P0.1 - Unassigned, Open-Drain, Digital
249 1 // P0.2 - Unassigned, Open-Drain, Digital
250 1 // P0.3 - Unassigned, Open-Drain, Digital
251 1 // P0.4 - Unassigned, Open-Drain, Digital
252 1 // P0.5 - Unassigned, Open-Drain, Digital
253 1 // P0.6 - Unassigned, Open-Drain, Digital
254 1 // P0.7 - Unassigned, Open-Drain, Digital
255 1
256 1 // P1.0 - Unassigned, Open-Drain, Digital
257 1 // P1.1 - Skipped, Push-Pull, Digital SRCLK for 74HC595
258 1 // P1.2 - Skipped, Push-Pull, Digital RCLK for 74HC595
259 1 // P1.3 - Skipped, Push-Pull, Digital SER for 74HC595
260 1 // P1.4 - Skipped, Open-Drain, Digital COM1 for LCD
261 1 // P1.5 - Skipped, Open-Drain, Digital COM2 for LCD
262 1 // P1.6 - Skipped, Open-Drain, Digital COM3 for LCD
263 1 // P1.7 - Skipped, Open-Drain, Digital COM4 for LCD
264 1
265 1 P0MDOUT = 0x80;
266 1 P1MDOUT = 0x0E; // configure above pins to Push-Pull
267 1 P1MDIN = 0x0F; // configure Pins 1.4 - 1.7 to analog in
268 1 P1SKIP = 0xFE; // skip pins 1.1 to 1.7
269 1 XBR1 = 0x40; // enable crossbar
270 1
271 1 }
272
273 //-----------------------------------------------------------------------------
274 // Timer2_Init
275 //-----------------------------------------------------------------------------
276 //
277 // The timer overflows at a rate of TIMER2_RATE times a second
278 // The interrupt generated in handled by the LCD_refresh ISR
279 //
280 void Timer2_Init (int counts)
281 {
282 1 TMR2CN = 0x00; // STOP Timer2; Clear TF2H and TF2L;
283 1 // disable low-byte interrupt; disable
284 1 // split mode; select internal timebase
285 1 CKCON |= 0x10; // Timer2 uses SYSCLK as its timebase
286 1
287 1 TMR2RL = -counts; // Init reload values
288 1 TMR2 = TMR2RL; // Init Timer2 with reload value
289 1 ET2 = 1; // enable Timer2 interrupts
290 1 TR2 = 1; // start Timer2
291 1 }
292
293 //------------------------------------------------------------------------------------
294 // Timer3_Init
295 //------------------------------------------------------------------------------------
296 //
297 // Configure the Timer to overflow without interrupts
298 // The overflow will be used in the wait function
299 //
300 void Timer3_Init (int count)
301 {
302 1 TMR3CN = 0x00; // STOP Timer3; Clear TF3H and TF3L;
303 1 // disable low-byte interrupt; disable
C51 COMPILER V8.02 LCDINTERFACE 03/15/2009 20:48:19 PAGE 6
304 1 // split mode; select internal timebase
305 1
306 1 CKCON |= 0x40; // Timer3 uses SYSCLK as its timebase
307 1
308 1 TMR3RL = -count; // Init reload values
309 1 TMR3 = TMR3RL; // Init Timer3 with reload value
310 1 EIE1 &= 0x7F; // disable Timer3 interrupts
311 1
312 1 TMR3CN |= 0x01; // start Timer3
313 1 }
314
315 //-----------------------------------------------------------------------------
316 // Interrupt Service Routines
317 //-----------------------------------------------------------------------------
318
319 // LCDrefresh is triggered on a Timer2 Overflow
320
321 // Takes what is in the LCD bar bits and shift them into the two 74HC595
322 // shift registers depending on the COM cycle; The most signficant
323 // LCD pin (pin 16) gets shifted out first; Only 15 bits get shifted each
324 // COM cycle;
325
326 void LCDrefresh_ISR (void) interrupt 5
327 {
328 1 int i = 0;
329 1
330 1 if (com_cycle == 1)
331 1 {
332 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
333 2 SER = D6A ^ com_invert; Strobe();
334 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
335 2 SER = D5A ^ com_invert; Strobe();
336 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
337 2 SER = D4A ^ com_invert; Strobe();
338 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
339 2 SER = D3A ^ com_invert; Strobe();
340 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
341 2 SER = D2A ^ com_invert; Strobe();
342 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
343 2 SER = D1A ^ com_invert; Strobe();
344 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
345 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
346 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
347 2
348 2 RCLK = 1; // put shifted data to LCD - rising edge
349 2 for (i=0; i<PULSE_LENGTH; i++); // keep clock high for a while
350 2 RCLK = 0; // turn off clock
351 2
352 2 P1MDIN &= ~0x80; // configure COM4 to ANALOG_IN;
353 2 P1MDIN |= 0x10; // and COM1 to digital
354 2
355 2 P1MDOUT &= ~0x80; // make COM4 an open-drain
356 2 P1MDOUT |= 0x10; // make COM1 a push-pull
357 2 COM4 = 1; // set COM4 to high impedance
358 2 COM1 = 1 ^ com_invert; // start the COM1 cycle
359 2 com_cycle = 2; // next state
360 2 }
361 1
362 1 else if (com_cycle == 2)
363 1 {
364 2 SER = D6B ^ com_invert; Strobe();
365 2 SER = D6F ^ com_invert; Strobe();
C51 COMPILER V8.02 LCDINTERFACE 03/15/2009 20:48:19 PAGE 7
366 2 SER = D5B ^ com_invert; Strobe();
367 2 SER = D5F ^ com_invert; Strobe();
368 2 SER = D4B ^ com_invert; Strobe();
369 2 SER = D4F ^ com_invert; Strobe();
370 2 SER = D3B ^ com_invert; Strobe();
371 2 SER = D3F ^ com_invert; Strobe();
372 2 SER = D2B ^ com_invert; Strobe();
373 2 SER = D2F ^ com_invert; Strobe();
374 2 SER = D1B ^ com_invert; Strobe();
375 2 SER = D1F ^ com_invert; Strobe();
376 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
377 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
378 2 SER = 1 ^ com_invert; Strobe(); // non-existent segment
379 2
380 2 RCLK = 1; // put shifted data to LCD - rising edge
381 2 for (i=0; i<PULSE_LENGTH; i++); // keep clock high for a while
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -