This is a sample program to drive a 128x128 LCD with t6963 controller through SPI by means of an MCP23S17 16-Bit I/O Expander with Serial Interface
main.cpp@2:9071445a6895, 2010-12-06 (annotated)
- Committer:
- gertk
- Date:
- Mon Dec 06 20:45:00 2010 +0000
- Revision:
- 2:9071445a6895
- Parent:
- 1:e98e29ea2d03
- Child:
- 3:fc101c00b5be
0.0003
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gertk | 0:bf72877f77ab | 1 | #include "mbed.h" |
gertk | 1:e98e29ea2d03 | 2 | #include "mcp_lcd.h" |
gertk | 0:bf72877f77ab | 3 | |
gertk | 2:9071445a6895 | 4 | // for 21 characters on a row (6x8 font) |
gertk | 2:9071445a6895 | 5 | // #define LCDFONTSEL 0xFF |
gertk | 2:9071445a6895 | 6 | // for 16 characters on a row (8x8 font) |
gertk | 2:9071445a6895 | 7 | #define LCDFONTSEL 0xDF |
gertk | 2:9071445a6895 | 8 | |
gertk | 2:9071445a6895 | 9 | // lcd dimensions in pixels |
gertk | 2:9071445a6895 | 10 | #define LCD_XWIDTH 128 |
gertk | 2:9071445a6895 | 11 | #define LCD_YHEIGHT 128 |
gertk | 2:9071445a6895 | 12 | |
gertk | 2:9071445a6895 | 13 | #if LCDFONTSEL == 0xFF |
gertk | 2:9071445a6895 | 14 | // lcd dimensions in characters |
gertk | 2:9071445a6895 | 15 | #define LCD_WIDTH 22 |
gertk | 2:9071445a6895 | 16 | #define LCD_HEIGHT 16 |
gertk | 2:9071445a6895 | 17 | #else |
gertk | 2:9071445a6895 | 18 | #define LCD_WIDTH 16 |
gertk | 2:9071445a6895 | 19 | #define LCD_HEIGHT 16 |
gertk | 2:9071445a6895 | 20 | #endif |
gertk | 2:9071445a6895 | 21 | |
gertk | 2:9071445a6895 | 22 | #define TEXT_STARTADDRESS 0x0000 |
gertk | 2:9071445a6895 | 23 | #define GRAPHIC_STARTADDRESS 0x1000 |
gertk | 2:9071445a6895 | 24 | |
gertk | 0:bf72877f77ab | 25 | DigitalOut myled(LED1); |
gertk | 0:bf72877f77ab | 26 | SPI spi(p5, p6, p7); // mosi, miso, sclk |
gertk | 0:bf72877f77ab | 27 | DigitalOut cs(p20); |
gertk | 0:bf72877f77ab | 28 | |
gertk | 0:bf72877f77ab | 29 | Serial pc(USBTX, USBRX); // tx, rx |
gertk | 0:bf72877f77ab | 30 | |
gertk | 0:bf72877f77ab | 31 | |
gertk | 0:bf72877f77ab | 32 | // write 8 bits lcd data |
gertk | 0:bf72877f77ab | 33 | void lcd_data(unsigned char d) |
gertk | 0:bf72877f77ab | 34 | { |
gertk | 0:bf72877f77ab | 35 | cs=0; |
gertk | 0:bf72877f77ab | 36 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 37 | spi.write(GPIOB); // select GPIOB |
gertk | 0:bf72877f77ab | 38 | spi.write(d); // set data byte |
gertk | 0:bf72877f77ab | 39 | cs=1; |
gertk | 0:bf72877f77ab | 40 | |
gertk | 0:bf72877f77ab | 41 | cs=0; |
gertk | 0:bf72877f77ab | 42 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 43 | spi.write(GPIOA); // select GPIOA |
gertk | 0:bf72877f77ab | 44 | spi.write(LCDFONTSEL-LCD_CE-LCD_CD); |
gertk | 0:bf72877f77ab | 45 | cs=1; |
gertk | 0:bf72877f77ab | 46 | |
gertk | 0:bf72877f77ab | 47 | cs=0; |
gertk | 0:bf72877f77ab | 48 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 49 | spi.write(GPIOA); // select GPIOA |
gertk | 0:bf72877f77ab | 50 | spi.write(LCDFONTSEL - LCD_WR - LCD_CE - LCD_CD); |
gertk | 0:bf72877f77ab | 51 | cs=1; |
gertk | 0:bf72877f77ab | 52 | |
gertk | 0:bf72877f77ab | 53 | cs=0; |
gertk | 0:bf72877f77ab | 54 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 55 | spi.write(GPIOA); // select GPIOA |
gertk | 0:bf72877f77ab | 56 | spi.write(LCDFONTSEL - LCD_CD); |
gertk | 0:bf72877f77ab | 57 | cs=1; |
gertk | 0:bf72877f77ab | 58 | |
gertk | 0:bf72877f77ab | 59 | } |
gertk | 0:bf72877f77ab | 60 | |
gertk | 0:bf72877f77ab | 61 | // write 8 bits lcd command |
gertk | 0:bf72877f77ab | 62 | void lcd_command(unsigned char c) |
gertk | 0:bf72877f77ab | 63 | { |
gertk | 0:bf72877f77ab | 64 | cs=0; |
gertk | 0:bf72877f77ab | 65 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 66 | spi.write(GPIOB); // select GPIOB |
gertk | 0:bf72877f77ab | 67 | spi.write(c); // set data byte |
gertk | 0:bf72877f77ab | 68 | cs=1; |
gertk | 0:bf72877f77ab | 69 | |
gertk | 0:bf72877f77ab | 70 | cs=0; |
gertk | 0:bf72877f77ab | 71 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 72 | spi.write(GPIOA); // select GPIOA |
gertk | 0:bf72877f77ab | 73 | spi.write(LCDFONTSEL-LCD_CE); |
gertk | 0:bf72877f77ab | 74 | cs=1; |
gertk | 0:bf72877f77ab | 75 | |
gertk | 0:bf72877f77ab | 76 | cs=0; |
gertk | 0:bf72877f77ab | 77 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 78 | spi.write(GPIOA); // select GPIOA |
gertk | 0:bf72877f77ab | 79 | spi.write(LCDFONTSEL - LCD_WR - LCD_CE); |
gertk | 0:bf72877f77ab | 80 | cs=1; |
gertk | 0:bf72877f77ab | 81 | |
gertk | 0:bf72877f77ab | 82 | cs=0; |
gertk | 0:bf72877f77ab | 83 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 84 | spi.write(GPIOA); // select GPIOA |
gertk | 0:bf72877f77ab | 85 | spi.write(LCDFONTSEL); |
gertk | 0:bf72877f77ab | 86 | cs=1; |
gertk | 0:bf72877f77ab | 87 | } |
gertk | 0:bf72877f77ab | 88 | |
gertk | 0:bf72877f77ab | 89 | void lcd_init() |
gertk | 0:bf72877f77ab | 90 | { |
gertk | 0:bf72877f77ab | 91 | cs=0; |
gertk | 0:bf72877f77ab | 92 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 93 | spi.write(IODIRA); // select IODIRA at start |
gertk | 0:bf72877f77ab | 94 | spi.write(0x00); // IODIRA all outputs |
gertk | 0:bf72877f77ab | 95 | spi.write(0x00); // IODIRB all outputs |
gertk | 0:bf72877f77ab | 96 | cs=1; |
gertk | 0:bf72877f77ab | 97 | wait(0.1); |
gertk | 0:bf72877f77ab | 98 | |
gertk | 0:bf72877f77ab | 99 | cs=0; |
gertk | 0:bf72877f77ab | 100 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 101 | spi.write(GPIOA); // select GPIOA at start |
gertk | 0:bf72877f77ab | 102 | spi.write(LCDFONTSEL-LCD_RST); // activate reset |
gertk | 0:bf72877f77ab | 103 | spi.write(0x00); // all B outputs 0 |
gertk | 0:bf72877f77ab | 104 | cs=1; |
gertk | 0:bf72877f77ab | 105 | wait(0.1); |
gertk | 0:bf72877f77ab | 106 | |
gertk | 0:bf72877f77ab | 107 | cs=0; |
gertk | 0:bf72877f77ab | 108 | spi.write(0x40); |
gertk | 0:bf72877f77ab | 109 | spi.write(GPIOA); // select GPIOA at start |
gertk | 0:bf72877f77ab | 110 | spi.write(LCDFONTSEL); // deactivate reset |
gertk | 0:bf72877f77ab | 111 | cs=1; |
gertk | 0:bf72877f77ab | 112 | wait(0.1); |
gertk | 0:bf72877f77ab | 113 | |
gertk | 0:bf72877f77ab | 114 | // set text home address at 0x0000 |
gertk | 2:9071445a6895 | 115 | lcd_data(TEXT_STARTADDRESS%0x100); |
gertk | 2:9071445a6895 | 116 | lcd_data(TEXT_STARTADDRESS/0x100); |
gertk | 0:bf72877f77ab | 117 | lcd_command(TXHOME); |
gertk | 0:bf72877f77ab | 118 | |
gertk | 2:9071445a6895 | 119 | // set graphic home address at 0x1000 |
gertk | 2:9071445a6895 | 120 | lcd_data(GRAPHIC_STARTADDRESS%0x100); |
gertk | 2:9071445a6895 | 121 | lcd_data(GRAPHIC_STARTADDRESS/0x100); |
gertk | 0:bf72877f77ab | 122 | lcd_command(GRHOME); |
gertk | 0:bf72877f77ab | 123 | |
gertk | 2:9071445a6895 | 124 | // set text area |
gertk | 2:9071445a6895 | 125 | lcd_data(LCD_WIDTH); |
gertk | 0:bf72877f77ab | 126 | lcd_data(0x00); |
gertk | 0:bf72877f77ab | 127 | lcd_command(TXAREA); |
gertk | 0:bf72877f77ab | 128 | |
gertk | 2:9071445a6895 | 129 | // set graphic area |
gertk | 2:9071445a6895 | 130 | lcd_data(LCD_WIDTH); |
gertk | 0:bf72877f77ab | 131 | lcd_data(0x00); |
gertk | 0:bf72877f77ab | 132 | lcd_command(GRAREA); |
gertk | 0:bf72877f77ab | 133 | |
gertk | 0:bf72877f77ab | 134 | // mode set (internal character generation mode) |
gertk | 0:bf72877f77ab | 135 | lcd_command(0x80); |
gertk | 0:bf72877f77ab | 136 | |
gertk | 0:bf72877f77ab | 137 | // set offset register |
gertk | 0:bf72877f77ab | 138 | lcd_data(0x02); |
gertk | 0:bf72877f77ab | 139 | lcd_data(0x00); |
gertk | 0:bf72877f77ab | 140 | lcd_command(OFFSET); |
gertk | 0:bf72877f77ab | 141 | |
gertk | 0:bf72877f77ab | 142 | // display mode (text on graphics on cursor off) |
gertk | 2:9071445a6895 | 143 | lcd_command(0x90+0x08+0x04); |
gertk | 2:9071445a6895 | 144 | |
gertk | 2:9071445a6895 | 145 | } |
gertk | 2:9071445a6895 | 146 | |
gertk | 2:9071445a6895 | 147 | // put a text string at position x,y (character row,column) |
gertk | 2:9071445a6895 | 148 | void lcd_string(char x,char y,char *s) |
gertk | 2:9071445a6895 | 149 | { |
gertk | 2:9071445a6895 | 150 | int adr; |
gertk | 2:9071445a6895 | 151 | adr=TEXT_STARTADDRESS+x+y*LCD_WIDTH; |
gertk | 2:9071445a6895 | 152 | lcd_data(adr%0x100); |
gertk | 2:9071445a6895 | 153 | lcd_data(adr/0x100); |
gertk | 2:9071445a6895 | 154 | lcd_command(ADPSET); |
gertk | 2:9071445a6895 | 155 | lcd_command(AWRON); |
gertk | 0:bf72877f77ab | 156 | |
gertk | 2:9071445a6895 | 157 | while (s[0]) |
gertk | 2:9071445a6895 | 158 | { |
gertk | 2:9071445a6895 | 159 | // convert from ascii to t6963 |
gertk | 2:9071445a6895 | 160 | lcd_data(s[0]-32); |
gertk | 2:9071445a6895 | 161 | s++; |
gertk | 2:9071445a6895 | 162 | } |
gertk | 2:9071445a6895 | 163 | lcd_command(AWROFF); |
gertk | 2:9071445a6895 | 164 | } |
gertk | 2:9071445a6895 | 165 | |
gertk | 2:9071445a6895 | 166 | // clear lcd display memory (8k) |
gertk | 2:9071445a6895 | 167 | void lcd_cls() |
gertk | 2:9071445a6895 | 168 | { |
gertk | 2:9071445a6895 | 169 | int a; |
gertk | 0:bf72877f77ab | 170 | lcd_data(0x00); |
gertk | 0:bf72877f77ab | 171 | lcd_data(0x00); |
gertk | 0:bf72877f77ab | 172 | lcd_command(ADPSET); |
gertk | 0:bf72877f77ab | 173 | lcd_command(AWRON); |
gertk | 2:9071445a6895 | 174 | for (a=0; a<8192; a++) lcd_data(0); |
gertk | 0:bf72877f77ab | 175 | lcd_command(AWROFF); |
gertk | 2:9071445a6895 | 176 | } |
gertk | 2:9071445a6895 | 177 | |
gertk | 2:9071445a6895 | 178 | // set or reset a pixel on the display on position x,y with color 0 or 1 |
gertk | 2:9071445a6895 | 179 | void lcd_plot(char x,char y,char color) |
gertk | 2:9071445a6895 | 180 | { |
gertk | 2:9071445a6895 | 181 | int adr; |
gertk | 2:9071445a6895 | 182 | adr = GRAPHIC_STARTADDRESS + ((LCD_WIDTH) * y) + (x/8); // calculate offset |
gertk | 2:9071445a6895 | 183 | lcd_data(adr%0x100); // set low byte |
gertk | 2:9071445a6895 | 184 | lcd_data(adr/0x100); // set high byte |
gertk | 2:9071445a6895 | 185 | lcd_command(ADPSET); // set address pointer |
gertk | 2:9071445a6895 | 186 | if (color) lcd_command(BS + (7-(x%8))); // use bit set mode |
gertk | 2:9071445a6895 | 187 | else lcd_command(BR + (7-(x%8))); // use bit reset mode |
gertk | 2:9071445a6895 | 188 | } |
gertk | 2:9071445a6895 | 189 | |
gertk | 2:9071445a6895 | 190 | int main() { |
gertk | 2:9071445a6895 | 191 | |
gertk | 2:9071445a6895 | 192 | int a; |
gertk | 2:9071445a6895 | 193 | pc.printf("SPI test\n"); |
gertk | 2:9071445a6895 | 194 | |
gertk | 2:9071445a6895 | 195 | // set SPI to full speed (10 MHz mode) |
gertk | 2:9071445a6895 | 196 | spi.format(8,0); |
gertk | 2:9071445a6895 | 197 | spi.frequency(10000000); |
gertk | 2:9071445a6895 | 198 | // spi.frequency(10000); |
gertk | 2:9071445a6895 | 199 | wait(0.1); |
gertk | 2:9071445a6895 | 200 | |
gertk | 2:9071445a6895 | 201 | pc.printf("MCP init\n"); |
gertk | 2:9071445a6895 | 202 | lcd_init(); |
gertk | 2:9071445a6895 | 203 | lcd_cls(); |
gertk | 0:bf72877f77ab | 204 | |
gertk | 0:bf72877f77ab | 205 | // write some text |
gertk | 2:9071445a6895 | 206 | lcd_string(0,0,"Hello World!"); |
gertk | 2:9071445a6895 | 207 | lcd_string(0,2,"0123456789"); |
gertk | 2:9071445a6895 | 208 | lcd_string(0,15,"abcdefghijklmnopqrstuvwxyz"); |
gertk | 2:9071445a6895 | 209 | |
gertk | 2:9071445a6895 | 210 | for (a=0; a<128; a++) lcd_plot(a,a/2+48,1); |
gertk | 2:9071445a6895 | 211 | |
gertk | 0:bf72877f77ab | 212 | while(1) { |
gertk | 0:bf72877f77ab | 213 | myled = 1; |
gertk | 0:bf72877f77ab | 214 | wait(0.2); |
gertk | 0:bf72877f77ab | 215 | myled = 0; |
gertk | 0:bf72877f77ab | 216 | wait(0.2); |
gertk | 0:bf72877f77ab | 217 | } |
gertk | 0:bf72877f77ab | 218 | } |