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 |
cliechti | 85ca4ee | 2005-11-02 18:54:21 +0000 | [diff] [blame] | 8 | sys.path.insert(0, '..') |
cliechti | 8864126 | 2002-07-29 02:09:04 +0000 | [diff] [blame] | 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 | |
cliechti | 85ca4ee | 2005-11-02 18:54:21 +0000 | [diff] [blame] | 34 | class FourBitIO(object): |
cliechti | 8864126 | 2002-07-29 02:09:04 +0000 | [diff] [blame] | 35 | def __init__(self): |
cliechti | 8864126 | 2002-07-29 02:09:04 +0000 | [diff] [blame] | 36 | self.data = 0 |
| 37 | |
| 38 | self.out(0) #reset pins |
| 39 | time.sleep(0.050) #wait more than 30ms |
| 40 | #send the reset sequece (3 times the same pattern) |
| 41 | self.out(LCD8BITS) #set 8 bit interface |
| 42 | self.toggleE() #toggle LCD_E, the enable pin |
| 43 | time.sleep(0.005) #wait a bit |
| 44 | self.toggleE() #toggle LCD_E, the enable pin |
| 45 | time.sleep(0.005) #wait a bit |
| 46 | self.toggleE() #toggle LCD_E, the enable pin |
| 47 | time.sleep(0.005) #wait a bit |
| 48 | |
| 49 | self.out(LCD4BITS) #now set up the 4 bit interface |
| 50 | self.toggleE() #toggle LCD_E, the enable pin |
| 51 | time.sleep(0.002) #wait until instr is finished |
| 52 | self.instr(LCD2LINES) #set 2 lines display |
| 53 | self.instr(LCDCURSOROFF) #hide cursor |
| 54 | self.instr(LCDCLEAR) #clear display |
| 55 | |
| 56 | #my connector has the wrong pinorder.... |
| 57 | #better swap them in software than to solder ;-) |
| 58 | def reveseout(self, x): |
| 59 | r = ((x & (1<<0) and 1) << 7) |\ |
| 60 | ((x & (1<<1) and 1) << 6) |\ |
| 61 | ((x & (1<<2) and 1) << 5) |\ |
| 62 | ((x & (1<<3) and 1) << 4) |\ |
| 63 | ((x & (1<<4) and 1) << 3) |\ |
| 64 | ((x & (1<<5) and 1) << 2) |\ |
| 65 | ((x & (1<<6) and 1) << 1) |\ |
| 66 | ((x & (1<<7) and 1) << 0) |
| 67 | #print "%02x" % r, "%02x" %x |
| 68 | self.p.setData(r) |
| 69 | |
| 70 | def toggleE(self): |
| 71 | """toggle enable pin""" |
| 72 | self.data |= LCD_E; #toggle LCD_E, the enable pin |
| 73 | self.reveseout(self.data) |
| 74 | self.data &= ~LCD_E; #back to inactive position |
| 75 | self.reveseout(self.data) |
| 76 | |
| 77 | def out(self, data): |
| 78 | """set data to LCD port""" |
| 79 | self.data = data |
| 80 | self.reveseout(self.data) |
| 81 | |
| 82 | def instr(self, cmd): |
| 83 | """send instruction byte to LCD""" |
| 84 | self.out(cmd & 0xf0) #output upper nibble |
| 85 | self.toggleE() #toggle LCD_E, the enable pin |
| 86 | self.out((cmd << 4) & 0xf0) #and then the lower nibble |
| 87 | self.toggleE() #toggle LCD_E, the enable pin |
| 88 | time.sleep(0.001) #wait until instr is finished |
| 89 | |
| 90 | def putc(self, c): |
| 91 | """send a data byte to the LCD""" |
| 92 | c = ord(c) |
| 93 | self.out((c & 0xf0) | LCD_RS) #output upper nibble |
| 94 | self.toggleE() #toggle LCD_E, the enable pin |
| 95 | self.out(((c << 4) & 0xf0) | LCD_RS) #and then the lower nibble |
| 96 | self.toggleE() #toggle LCD_E, the enable pin |
| 97 | time.sleep(0.001) #wait until instr is finished |
| 98 | |
cliechti | 85ca4ee | 2005-11-02 18:54:21 +0000 | [diff] [blame] | 99 | |
| 100 | class EightBitIO(object): |
| 101 | def __init__(self): |
| 102 | self.data = 0 |
| 103 | |
| 104 | self.setRS(0) |
| 105 | self.setRW(0) |
| 106 | self.out(0) #reset pins |
| 107 | time.sleep(0.050) #wait more than 30ms |
| 108 | #send the reset sequece (3 times the same pattern) |
| 109 | self.out(LCD8BITS) #set 8 bit interface |
| 110 | self.toggleE() #toggle LCD_E, the enable pin |
| 111 | time.sleep(0.005) #wait a bit |
| 112 | self.toggleE() #toggle LCD_E, the enable pin |
| 113 | time.sleep(0.005) #wait a bit |
| 114 | self.toggleE() #toggle LCD_E, the enable pin |
| 115 | time.sleep(0.005) #wait a bit |
| 116 | |
| 117 | #~ self.instr(LCD2LINES) #set 2 lines display |
| 118 | self.instr(LCDCURSOROFF) #hide cursor |
| 119 | self.instr(LCDCLEAR) #clear display |
| 120 | |
| 121 | def setRW(self, state): |
| 122 | self.p.setAutoFeed(state) |
| 123 | |
| 124 | def setRS(self, state): |
| 125 | self.p.setInitOut(state) |
| 126 | |
| 127 | def toggleE(self): |
| 128 | """toggle enable pin""" |
| 129 | self.p.setDataStrobe(1) #toggle LCD_E, the enable pin |
| 130 | #~ time.sleep(0.001) |
| 131 | self.p.setDataStrobe(0) #back to inactive position |
| 132 | #~ time.sleep(0.001) |
| 133 | |
| 134 | def out(self, data): |
| 135 | """set data to LCD port""" |
| 136 | self.data = data |
| 137 | self.p.setData(self.data) |
| 138 | |
| 139 | def instr(self, cmd): |
| 140 | """send instruction byte to LCD""" |
| 141 | self.setRS(0) |
| 142 | self.setRW(0) |
| 143 | self.out(cmd) |
| 144 | self.toggleE() #toggle LCD_E, the enable pin |
| 145 | time.sleep(0.005) #wait until instr is finished |
| 146 | |
| 147 | def putc(self, c): |
| 148 | """send a data byte to the LCD""" |
| 149 | self.setRS(1) |
| 150 | self.setRW(0) |
| 151 | self.out(ord(c)) |
| 152 | self.toggleE() #toggle LCD_E, the enable pin |
| 153 | time.sleep(0.001) #wait until instr is finished |
| 154 | |
| 155 | |
| 156 | #~ class HD44780(FourBitIO): |
| 157 | class HD44780(EightBitIO): |
| 158 | def __init__(self): |
| 159 | self.p = parallel.Parallel() |
| 160 | super(HD44780, self).__init__() |
| 161 | |
cliechti | 8864126 | 2002-07-29 02:09:04 +0000 | [diff] [blame] | 162 | def write(self, str): |
| 163 | """write a string to the LCD""" |
| 164 | for c in str: |
| 165 | self.putc(c) #write each character |
| 166 | |
| 167 | def downloadFont(self, fontdata): |
| 168 | """Set the memory pointer and download a font""" |
| 169 | self.instr(LCDCGADRSET); |
| 170 | self.write(fontdata) |
| 171 | self.instr(LCDLINE1) #just in case, set cursor to a visible pos |
| 172 | |
| 173 | if __name__ == '__main__': |
cliechti | 85ca4ee | 2005-11-02 18:54:21 +0000 | [diff] [blame] | 174 | lcd = HD44780() |
cliechti | 8864126 | 2002-07-29 02:09:04 +0000 | [diff] [blame] | 175 | lcd.write("Hello World") |
| 176 | lcd.instr(LCDLINE2) |
| 177 | lcd.write("from Python") |
| 178 | ## for c in map(chr,range(256)): |
| 179 | ## lcd.instr(LCDLINE1) |
| 180 | ## lcd.write(c) |
| 181 | |
| 182 | |