character LCD module to I2C adapter http://mbed.org/users/okini3939/notebook/i2c-lcd-library/
Dependents: i2clcd_lib WeatherPlatform_20110408 WeatherPlatform WeatherStation ... more
I2CLCD.cpp@1:bf21aa3f7cdc, 2010-10-19 (annotated)
- Committer:
- okini3939
- Date:
- Tue Oct 19 07:08:54 2010 +0000
- Revision:
- 1:bf21aa3f7cdc
- Parent:
- 0:b069b7027af2
- Child:
- 2:bc4583ce560e
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okini3939 | 0:b069b7027af2 | 1 | /* |
okini3939 | 1:bf21aa3f7cdc | 2 | * mbed library for I2C LCD |
okini3939 | 0:b069b7027af2 | 3 | * Copyright (c) 2010 Hiroshi Suga |
okini3939 | 0:b069b7027af2 | 4 | * Released under the MIT License: http://mbed.org/license/mit |
okini3939 | 1:bf21aa3f7cdc | 5 | * |
okini3939 | 1:bf21aa3f7cdc | 6 | * Using some of the source code: |
okini3939 | 1:bf21aa3f7cdc | 7 | * mbed TextLCD Library, for a 4-bit LCD based on HD44780 |
okini3939 | 1:bf21aa3f7cdc | 8 | * Copyright (c) 2007-2010, sford |
okini3939 | 0:b069b7027af2 | 9 | */ |
okini3939 | 0:b069b7027af2 | 10 | |
okini3939 | 0:b069b7027af2 | 11 | #include "mbed.h" |
okini3939 | 0:b069b7027af2 | 12 | #include "I2CLCD.h" |
okini3939 | 0:b069b7027af2 | 13 | |
okini3939 | 0:b069b7027af2 | 14 | #define I2CLCD_ADDR 0x7c |
okini3939 | 0:b069b7027af2 | 15 | |
okini3939 | 0:b069b7027af2 | 16 | |
okini3939 | 0:b069b7027af2 | 17 | int I2CLCD::_putc (int value) { |
okini3939 | 0:b069b7027af2 | 18 | |
okini3939 | 0:b069b7027af2 | 19 | if (value == '\n') { |
okini3939 | 0:b069b7027af2 | 20 | x = 0; |
okini3939 | 0:b069b7027af2 | 21 | y ++; |
okini3939 | 0:b069b7027af2 | 22 | if (y >= rows()) { |
okini3939 | 0:b069b7027af2 | 23 | y = 0; |
okini3939 | 0:b069b7027af2 | 24 | lcd_out(address(x, y), 0); |
okini3939 | 0:b069b7027af2 | 25 | } |
okini3939 | 0:b069b7027af2 | 26 | |
okini3939 | 0:b069b7027af2 | 27 | } else { |
okini3939 | 0:b069b7027af2 | 28 | |
okini3939 | 0:b069b7027af2 | 29 | lcd_out(address(x, y), 0); |
okini3939 | 0:b069b7027af2 | 30 | lcd_out(value, 1); |
okini3939 | 0:b069b7027af2 | 31 | x ++; |
okini3939 | 0:b069b7027af2 | 32 | if (x >= cols()) { |
okini3939 | 0:b069b7027af2 | 33 | x = 0; |
okini3939 | 0:b069b7027af2 | 34 | y ++; |
okini3939 | 0:b069b7027af2 | 35 | if (y >= rows()) { |
okini3939 | 0:b069b7027af2 | 36 | y = 0; |
okini3939 | 0:b069b7027af2 | 37 | lcd_out(address(x, y), 0); |
okini3939 | 0:b069b7027af2 | 38 | } |
okini3939 | 0:b069b7027af2 | 39 | } |
okini3939 | 0:b069b7027af2 | 40 | } |
okini3939 | 0:b069b7027af2 | 41 | |
okini3939 | 0:b069b7027af2 | 42 | return value; |
okini3939 | 0:b069b7027af2 | 43 | } |
okini3939 | 0:b069b7027af2 | 44 | |
okini3939 | 0:b069b7027af2 | 45 | int I2CLCD::_getc() { |
okini3939 | 0:b069b7027af2 | 46 | return lcd_in(0); |
okini3939 | 0:b069b7027af2 | 47 | } |
okini3939 | 0:b069b7027af2 | 48 | |
okini3939 | 0:b069b7027af2 | 49 | |
okini3939 | 0:b069b7027af2 | 50 | I2CLCD::I2CLCD (PinName p_sda, PinName p_scl, I2CLCDType p_type, I2CLCDConfig p_config) : i2c(p_sda, p_scl) { |
okini3939 | 0:b069b7027af2 | 51 | init(p_type, p_config); |
okini3939 | 0:b069b7027af2 | 52 | } |
okini3939 | 0:b069b7027af2 | 53 | |
okini3939 | 0:b069b7027af2 | 54 | I2CLCD::I2CLCD (I2C& p_i2c, I2CLCDType p_type, I2CLCDConfig p_config) : i2c(p_i2c) { |
okini3939 | 0:b069b7027af2 | 55 | init(p_type, p_config); |
okini3939 | 0:b069b7027af2 | 56 | } |
okini3939 | 0:b069b7027af2 | 57 | |
okini3939 | 0:b069b7027af2 | 58 | void I2CLCD::init (I2CLCDType p_type, I2CLCDConfig p_config) { |
okini3939 | 0:b069b7027af2 | 59 | |
okini3939 | 0:b069b7027af2 | 60 | type = p_type; |
okini3939 | 0:b069b7027af2 | 61 | |
okini3939 | 0:b069b7027af2 | 62 | lcd_cfg(p_config); |
okini3939 | 0:b069b7027af2 | 63 | |
okini3939 | 0:b069b7027af2 | 64 | wait(0.5); |
okini3939 | 0:b069b7027af2 | 65 | lcd_out(0x30, 0); |
okini3939 | 0:b069b7027af2 | 66 | wait(0.005); |
okini3939 | 0:b069b7027af2 | 67 | lcd_out(0x30, 0); |
okini3939 | 0:b069b7027af2 | 68 | wait(0.002); |
okini3939 | 0:b069b7027af2 | 69 | lcd_out(0x30, 0); |
okini3939 | 0:b069b7027af2 | 70 | |
okini3939 | 0:b069b7027af2 | 71 | lcd_out(0x38, 0); // func |
okini3939 | 0:b069b7027af2 | 72 | lcd_out(0x10, 0); // shift |
okini3939 | 0:b069b7027af2 | 73 | lcd_out(0x0c, 0); // display |
okini3939 | 0:b069b7027af2 | 74 | lcd_out(0x06, 0); // entry mode |
okini3939 | 0:b069b7027af2 | 75 | cls(); |
okini3939 | 0:b069b7027af2 | 76 | } |
okini3939 | 0:b069b7027af2 | 77 | |
okini3939 | 0:b069b7027af2 | 78 | void I2CLCD::cls() { |
okini3939 | 0:b069b7027af2 | 79 | lcd_out(0x01, 0); // clear |
okini3939 | 0:b069b7027af2 | 80 | wait(0.002); |
okini3939 | 0:b069b7027af2 | 81 | lcd_out(0x02, 0); // home |
okini3939 | 0:b069b7027af2 | 82 | wait(0.002); |
okini3939 | 0:b069b7027af2 | 83 | locate(0, 0); |
okini3939 | 0:b069b7027af2 | 84 | } |
okini3939 | 0:b069b7027af2 | 85 | |
okini3939 | 0:b069b7027af2 | 86 | void I2CLCD::locate(int col, int row) { |
okini3939 | 0:b069b7027af2 | 87 | x = col; |
okini3939 | 0:b069b7027af2 | 88 | y = row; |
okini3939 | 0:b069b7027af2 | 89 | lcd_out(address(x, y), 0); |
okini3939 | 0:b069b7027af2 | 90 | } |
okini3939 | 0:b069b7027af2 | 91 | |
okini3939 | 0:b069b7027af2 | 92 | int I2CLCD::address(int col, int row) { |
okini3939 | 0:b069b7027af2 | 93 | switch (type) { |
okini3939 | 0:b069b7027af2 | 94 | case LCD16x1: |
okini3939 | 0:b069b7027af2 | 95 | return (col < 8 ? 0x80 : 0xc0) + (col & 0x03); |
okini3939 | 0:b069b7027af2 | 96 | case LCD16x4: |
okini3939 | 0:b069b7027af2 | 97 | case LCD20x4: |
okini3939 | 0:b069b7027af2 | 98 | switch (row) { |
okini3939 | 0:b069b7027af2 | 99 | case 0: |
okini3939 | 0:b069b7027af2 | 100 | return 0x80 + col; |
okini3939 | 0:b069b7027af2 | 101 | case 1: |
okini3939 | 0:b069b7027af2 | 102 | return 0xc0 + col; |
okini3939 | 0:b069b7027af2 | 103 | case 2: |
okini3939 | 0:b069b7027af2 | 104 | return 0x94 + col; |
okini3939 | 0:b069b7027af2 | 105 | case 3: |
okini3939 | 0:b069b7027af2 | 106 | return 0xd4 + col; |
okini3939 | 0:b069b7027af2 | 107 | } |
okini3939 | 0:b069b7027af2 | 108 | case LCD16x2B: |
okini3939 | 0:b069b7027af2 | 109 | return 0x80 + (row * 40) + col; |
okini3939 | 0:b069b7027af2 | 110 | case LCD8x2: |
okini3939 | 0:b069b7027af2 | 111 | case LCD16x2: |
okini3939 | 0:b069b7027af2 | 112 | case LCD20x2: |
okini3939 | 0:b069b7027af2 | 113 | default: |
okini3939 | 0:b069b7027af2 | 114 | return 0x80 + (row * 0x40) + col; |
okini3939 | 0:b069b7027af2 | 115 | } |
okini3939 | 0:b069b7027af2 | 116 | } |
okini3939 | 0:b069b7027af2 | 117 | |
okini3939 | 0:b069b7027af2 | 118 | int I2CLCD::cols() { |
okini3939 | 0:b069b7027af2 | 119 | switch (type) { |
okini3939 | 0:b069b7027af2 | 120 | case LCD8x2: |
okini3939 | 0:b069b7027af2 | 121 | return 8; |
okini3939 | 0:b069b7027af2 | 122 | case LCD20x4: |
okini3939 | 0:b069b7027af2 | 123 | case LCD20x2: |
okini3939 | 0:b069b7027af2 | 124 | return 20; |
okini3939 | 0:b069b7027af2 | 125 | case LCD16x1: |
okini3939 | 0:b069b7027af2 | 126 | case LCD16x2: |
okini3939 | 0:b069b7027af2 | 127 | case LCD16x2B: |
okini3939 | 0:b069b7027af2 | 128 | case LCD16x4: |
okini3939 | 0:b069b7027af2 | 129 | default: |
okini3939 | 0:b069b7027af2 | 130 | return 16; |
okini3939 | 0:b069b7027af2 | 131 | } |
okini3939 | 0:b069b7027af2 | 132 | } |
okini3939 | 0:b069b7027af2 | 133 | |
okini3939 | 0:b069b7027af2 | 134 | int I2CLCD::rows() { |
okini3939 | 0:b069b7027af2 | 135 | switch (type) { |
okini3939 | 0:b069b7027af2 | 136 | case LCD16x1: |
okini3939 | 0:b069b7027af2 | 137 | return 1; |
okini3939 | 0:b069b7027af2 | 138 | case LCD16x4: |
okini3939 | 0:b069b7027af2 | 139 | case LCD20x4: |
okini3939 | 0:b069b7027af2 | 140 | return 4; |
okini3939 | 0:b069b7027af2 | 141 | case LCD8x2: |
okini3939 | 0:b069b7027af2 | 142 | case LCD16x2: |
okini3939 | 0:b069b7027af2 | 143 | case LCD16x2B: |
okini3939 | 0:b069b7027af2 | 144 | case LCD20x2: |
okini3939 | 0:b069b7027af2 | 145 | default: |
okini3939 | 0:b069b7027af2 | 146 | return 2; |
okini3939 | 0:b069b7027af2 | 147 | } |
okini3939 | 0:b069b7027af2 | 148 | } |
okini3939 | 0:b069b7027af2 | 149 | |
okini3939 | 0:b069b7027af2 | 150 | void I2CLCD::lcd_cfg (I2CLCDConfig cfg) { |
okini3939 | 0:b069b7027af2 | 151 | i2c.start(); |
okini3939 | 0:b069b7027af2 | 152 | i2c.write(I2CLCD_ADDR); |
okini3939 | 0:b069b7027af2 | 153 | i2c.write(LCDCFG_ENABLE | (cfg & 0x1f)); |
okini3939 | 0:b069b7027af2 | 154 | i2c.stop(); |
okini3939 | 0:b069b7027af2 | 155 | } |
okini3939 | 0:b069b7027af2 | 156 | |
okini3939 | 0:b069b7027af2 | 157 | void I2CLCD::lcd_out (int dat, int rs) { |
okini3939 | 0:b069b7027af2 | 158 | i2c.start(); |
okini3939 | 0:b069b7027af2 | 159 | i2c.write(I2CLCD_ADDR); |
okini3939 | 0:b069b7027af2 | 160 | i2c.write(rs ? 0x40 : 0); |
okini3939 | 0:b069b7027af2 | 161 | i2c.write(dat); |
okini3939 | 0:b069b7027af2 | 162 | i2c.stop(); |
okini3939 | 0:b069b7027af2 | 163 | } |
okini3939 | 0:b069b7027af2 | 164 | |
okini3939 | 0:b069b7027af2 | 165 | int I2CLCD::lcd_in (int rs) { |
okini3939 | 0:b069b7027af2 | 166 | int i; |
okini3939 | 0:b069b7027af2 | 167 | |
okini3939 | 0:b069b7027af2 | 168 | i2c.start(); |
okini3939 | 0:b069b7027af2 | 169 | i2c.write(I2CLCD_ADDR); |
okini3939 | 0:b069b7027af2 | 170 | i2c.write(rs ? 0x40 : 0); |
okini3939 | 0:b069b7027af2 | 171 | |
okini3939 | 0:b069b7027af2 | 172 | i2c.start(); |
okini3939 | 0:b069b7027af2 | 173 | i2c.write(I2CLCD_ADDR | 0x01); |
okini3939 | 0:b069b7027af2 | 174 | i = i2c.read(0); |
okini3939 | 0:b069b7027af2 | 175 | i2c.stop(); |
okini3939 | 0:b069b7027af2 | 176 | |
okini3939 | 0:b069b7027af2 | 177 | return i; |
okini3939 | 0:b069b7027af2 | 178 | } |