cliechti | 8864126 | 2002-07-29 02:09:04 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # character LCD example for pyparallel |
| 3 | # |
| 4 | #(C) 2002 Chris Liechti <cliechti@gmx.net> |
| 5 | # this is distributed under a free software license, see license.txt |
| 6 | |
| 7 | import sys, time |
| 8 | sys.path.append('..') |
| 9 | import parallel |
| 10 | |
| 11 | LCDON = 0x01 #0x00000001 Switch on display |
| 12 | LCDOFF = 0x08 #0x00001000 Switch off display |
| 13 | LCDCLEAR = 0x01 #0x00000001 |
| 14 | LCDLINE1 = 0x80 #0x10000000 |
| 15 | LCDLINE2 = 0xc0 #0x11000000 |
| 16 | LCDCURSORON = 0x0f #0x00001111 turn on cursor blinking |
| 17 | LCDCURSOROFF = 0x0c #0x00001100 Disable cursor blinking. The cursor is hidden. |
| 18 | LCDCGADRSET = 0x40 #0b01000000 |
| 19 | LCDDDADRSET = 0x80 #0b10000000 |
| 20 | LCD2LINES = 0x28 #0b00101000 Set display mode to two lines. |
| 21 | LCD8BITS = 0x30 #0b00110000 select 8 Bit interface |
| 22 | LCD4BITS = 0x20 #0b00100000 select 4 Bit interface |
| 23 | LCD_DATA_OFF = 0x05 #0x00000101 mask used to clear the data lines |
| 24 | |
| 25 | LCD_RS = 1<<1 |
| 26 | LCD_RW = 1<<2 |
| 27 | LCD_E = 1<<3 |
| 28 | LCD_D4 = 1<<4 |
| 29 | LCD_D5 = 1<<5 |
| 30 | LCD_D6 = 1<<6 |
| 31 | LCD_D7 = 1<<7 |
| 32 | |
| 33 | |
| 34 | class LCD: |
| 35 | def __init__(self): |
| 36 | self.p = parallel.Parallel() |
| 37 | self.data = 0 |
| 38 | |
| 39 | self.out(0) #reset pins |
| 40 | time.sleep(0.050) #wait more than 30ms |
| 41 | #send the reset sequece (3 times the same pattern) |
| 42 | self.out(LCD8BITS) #set 8 bit interface |
| 43 | self.toggleE() #toggle LCD_E, the enable pin |
| 44 | time.sleep(0.005) #wait a bit |
| 45 | self.toggleE() #toggle LCD_E, the enable pin |
| 46 | time.sleep(0.005) #wait a bit |
| 47 | self.toggleE() #toggle LCD_E, the enable pin |
| 48 | time.sleep(0.005) #wait a bit |
| 49 | |
| 50 | self.out(LCD4BITS) #now set up the 4 bit interface |
| 51 | self.toggleE() #toggle LCD_E, the enable pin |
| 52 | time.sleep(0.002) #wait until instr is finished |
| 53 | self.instr(LCD2LINES) #set 2 lines display |
| 54 | self.instr(LCDCURSOROFF) #hide cursor |
| 55 | self.instr(LCDCLEAR) #clear display |
| 56 | |
| 57 | #my connector has the wrong pinorder.... |
| 58 | #better swap them in software than to solder ;-) |
| 59 | def reveseout(self, x): |
| 60 | r = ((x & (1<<0) and 1) << 7) |\ |
| 61 | ((x & (1<<1) and 1) << 6) |\ |
| 62 | ((x & (1<<2) and 1) << 5) |\ |
| 63 | ((x & (1<<3) and 1) << 4) |\ |
| 64 | ((x & (1<<4) and 1) << 3) |\ |
| 65 | ((x & (1<<5) and 1) << 2) |\ |
| 66 | ((x & (1<<6) and 1) << 1) |\ |
| 67 | ((x & (1<<7) and 1) << 0) |
| 68 | #print "%02x" % r, "%02x" %x |
| 69 | self.p.setData(r) |
| 70 | |
| 71 | def toggleE(self): |
| 72 | """toggle enable pin""" |
| 73 | self.data |= LCD_E; #toggle LCD_E, the enable pin |
| 74 | self.reveseout(self.data) |
| 75 | self.data &= ~LCD_E; #back to inactive position |
| 76 | self.reveseout(self.data) |
| 77 | |
| 78 | def out(self, data): |
| 79 | """set data to LCD port""" |
| 80 | self.data = data |
| 81 | self.reveseout(self.data) |
| 82 | |
| 83 | def instr(self, cmd): |
| 84 | """send instruction byte to LCD""" |
| 85 | self.out(cmd & 0xf0) #output upper nibble |
| 86 | self.toggleE() #toggle LCD_E, the enable pin |
| 87 | self.out((cmd << 4) & 0xf0) #and then the lower nibble |
| 88 | self.toggleE() #toggle LCD_E, the enable pin |
| 89 | time.sleep(0.001) #wait until instr is finished |
| 90 | |
| 91 | def putc(self, c): |
| 92 | """send a data byte to the LCD""" |
| 93 | c = ord(c) |
| 94 | self.out((c & 0xf0) | LCD_RS) #output upper nibble |
| 95 | self.toggleE() #toggle LCD_E, the enable pin |
| 96 | self.out(((c << 4) & 0xf0) | LCD_RS) #and then the lower nibble |
| 97 | self.toggleE() #toggle LCD_E, the enable pin |
| 98 | time.sleep(0.001) #wait until instr is finished |
| 99 | |
| 100 | def write(self, str): |
| 101 | """write a string to the LCD""" |
| 102 | for c in str: |
| 103 | self.putc(c) #write each character |
| 104 | |
| 105 | def downloadFont(self, fontdata): |
| 106 | """Set the memory pointer and download a font""" |
| 107 | self.instr(LCDCGADRSET); |
| 108 | self.write(fontdata) |
| 109 | self.instr(LCDLINE1) #just in case, set cursor to a visible pos |
| 110 | |
| 111 | if __name__ == '__main__': |
| 112 | lcd = LCD() |
| 113 | lcd.write("Hello World") |
| 114 | lcd.instr(LCDLINE2) |
| 115 | lcd.write("from Python") |
| 116 | ## for c in map(chr,range(256)): |
| 117 | ## lcd.instr(LCDLINE1) |
| 118 | ## lcd.write(c) |
| 119 | |
| 120 | |