Richard Kuo
/
NTOUEE-mbed-I2C_LCD_movingcircle
mbed I2C to LCD for drawing a moving circle
Diff: ssd1306.cpp
- Revision:
- 0:5e40d147a8e1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ssd1306.cpp Thu Oct 20 13:05:10 2016 +0000 @@ -0,0 +1,411 @@ +// SSD1306Z LCD Driver: 0.96" lcd LY096BG30 +#include "mbed.h" +#include "ssd1306.h" +#include "Font8x16.h" +#include "Font5x7.h" + +I2C ssd1306_i2c(PD_12, PD_10); // I2C1_SDA, I2C1_SCL + +char DisplayBuffer[128*8]; + +void lcdWriteCommand(uint8_t lcd_Command) +{ + char data[2]; + data[0]=0x00; + data[1]=lcd_Command; + ssd1306_i2c.write(SSD1306_slave_addr, data, 2, 0); +} + +void lcdWriteData(uint8_t lcd_Data) +{ + char data[2]; + data[0]=0x40; + data[1]=lcd_Data; + ssd1306_i2c.write(SSD1306_slave_addr, data, 2, 0); +} + +void lcdSetAddr(uint8_t column, uint8_t page) +{ + lcdWriteCommand(0xb0+page); // set page address + lcdWriteCommand(0x10 | ((column & 0xf0) >> 4)); // set column address MSB + lcdWriteCommand(0x00 | (column & 0x0f) ); // set column address LSB +} + +void SSD1306::initialize(void) +{ + lcdWriteCommand(0xae); //display off + lcdWriteCommand(0x20); //Set Memory Addressing Mode + lcdWriteCommand(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid + lcdWriteCommand(0xb0); //Set Page Start Address for Page Addressing Mode,0-7 + lcdWriteCommand(0xc8); //Set COM Output Scan Direction + lcdWriteCommand(0x00);//---set low column address + lcdWriteCommand(0x10);//---set high column address + lcdWriteCommand(0x40);//--set start line address + lcdWriteCommand(0x81);//--set contrast control register + lcdWriteCommand(0x7f); + lcdWriteCommand(0xa1);//--set segment re-map 0 to 127 + lcdWriteCommand(0xa6);//--set normal display + lcdWriteCommand(0xa8);//--set multiplex ratio(1 to 64) + lcdWriteCommand(0x3F);// + lcdWriteCommand(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content + lcdWriteCommand(0xd3);//-set display offset + lcdWriteCommand(0x00);//-not offset + lcdWriteCommand(0xd5);//--set display clock divide ratio/oscillator frequency + lcdWriteCommand(0xf0);//--set divide ratio + lcdWriteCommand(0xd9);//--set pre-charge period + lcdWriteCommand(0x22); // + lcdWriteCommand(0xda);//--set com pins hardware configuration + lcdWriteCommand(0x12); + lcdWriteCommand(0xdb);//--set vcomh + lcdWriteCommand(0x20);//0x20,0.77xVcc + lcdWriteCommand(0x8d);//--set DC-DC enable + lcdWriteCommand(0x14);// + lcdWriteCommand(0xaf);//--turn on lcd panel +} + +void SSD1306::clearscreen(void) +{ + int16_t x, Y; + for (Y=0;Y<LCD_Ymax/8;Y++) + { + lcdSetAddr(0, Y); + for (x=0;x<LCD_Xmax;x++) + lcdWriteData(0x00); + } +} + +// print char function using Font5x7 +void SSD1306::printC_5x7 (int x, int y, unsigned char ascii_code) +{ + int8_t i; + if (x<(LCD_Xmax-5) && y<(LCD_Ymax-7)) { + if (ascii_code<0x20) ascii_code=0x20; + else if (ascii_code>0x7F) ascii_code=0x20; + for (i=0;i<5;i++) { + lcdSetAddr((x+i), (y/8)); + lcdWriteData(Font5x7[(ascii_code-0x20)*5+i]); + } + } +} + +void SSD1306::printC(int Line, int Col, unsigned char ascii_code) +{ + uint8_t j, i, tmp; + for (j=0;j<2;j++) { + lcdSetAddr(Col*8, Line*2+j); + for (i=0;i<8;i++) { + tmp=Font8x16[(ascii_code-0x20)*16+j*8+i]; + lcdWriteData(tmp); + } + } +} + +void SSD1306::printLine(int line, char text[]) +{ + uint8_t Col; + for (Col=0; Col<strlen(text); Col++) + printC(line, Col, text[Col]); +} + +void SSD1306::printS(int x, int y, char text[]) +{ + int8_t i; + for (i=0;i<strlen(text);i++) + printC(x+i*8, y,text[i]); +} + +void SSD1306::printS_5x7(int x, int y, char text[]) +{ + int8_t i; + for (i=0;i<strlen(text);i++) { + printC_5x7(x,y,text[i]); + x=x+5; + } +} + +void SSD1306::drawPixel(int x, int y, int fgColor, int bgColor) +{ + if (fgColor!=0) + DisplayBuffer[x+y/8*LCD_Xmax] |= (0x01<<(y%8)); + else + DisplayBuffer[x+y/8*LCD_Xmax] &= (0xFE<<(y%8)); + + lcdSetAddr(x, y/8); + lcdWriteData(DisplayBuffer[x+y/8*LCD_Xmax]); +} + +void SSD1306::drawBmp8x8(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,k, kx,ky; + if (x<(LCD_Xmax-7) && y<(LCD_Ymax-7)) // boundary check + for (i=0;i<8;i++){ + kx=x+i; + t=bitmap[i]; + for (k=0;k<8;k++) { + ky=y+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } +} + +void SSD1306::drawBmp32x8(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,k, kx,ky; + if (x<(LCD_Xmax-7) && y<(LCD_Ymax-7)) // boundary check + for (i=0;i<32;i++){ + kx=x+i; + t=bitmap[i]; + for (k=0;k<8;k++) { + ky=y+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } +} + +void SSD1306::drawBmp120x8(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,k, kx,ky; + if (x<(LCD_Xmax-7) && y<(LCD_Ymax-7)) // boundary check + for (i=0;i<120;i++){ + kx=x+i; + t=bitmap[i]; + for (k=0;k<8;k++) { + ky=y+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } +} + +void SSD1306::drawBmp8x16(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,k, kx,ky; + if (x<(LCD_Xmax-7) && y<(LCD_Ymax-7)) // boundary check + for (i=0;i<8;i++){ + kx=x+i; + t=bitmap[i]; + for (k=0;k<8;k++) { + ky=y+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + t=bitmap[i+8]; + for (k=0;k<8;k++) { + ky=y+k+8; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } +} + +void SSD1306::drawBmp16x8(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,k,kx,ky; + if (x<(LCD_Xmax-15) && y<(LCD_Ymax-7)) // boundary check + for (i=0;i<16;i++) + { + kx=x+i; + t=bitmap[i]; + for (k=0;k<8;k++) { + ky=y+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } +} + +void SSD1306::drawBmp16x16(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,j,k, kx,ky; + if (x<(LCD_Xmax-15) && y<(LCD_Ymax-15)) // boundary check + for (j=0;j<2; j++){ + for (i=0;i<16;i++) { + kx=x+i; + t=bitmap[i+j*16]; + for (k=0;k<8;k++) { + ky=y+j*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp16x24(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,j,k, kx,ky; + if (x<(LCD_Xmax-15) && y<(LCD_Ymax-15)) // boundary check + for (j=0;j<3; j++){ + for (i=0;i<16;i++) { + kx=x+i; + t=bitmap[i+j*16]; + for (k=0;k<8;k++) { + ky=y+j*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp16x32(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t, i,j,k, kx,ky; + if (x<(LCD_Xmax-15) && y<(LCD_Ymax-31)) // boundary check + for (j=0;j<4; j++) { + for (i=0;i<16;i++) { + kx=x+i; + t=bitmap[i+j*16]; + for (k=0;k<8;k++) { + ky=y+j*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp16x40(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t, i,j,k, kx,ky; + if (x<(LCD_Xmax-15) && y<(LCD_Ymax-31)) // boundary check + for (j=0;j<5; j++) { + for (i=0;i<16;i++) { + kx=x+i; + t=bitmap[i+j*16]; + for (k=0;k<8;k++) { + ky=y+j*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp16x48(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,j,k,kx,ky; + if (x<(LCD_Xmax-15) && y<(LCD_Ymax-47)) // boundary check + for (j=0;j<6; j++) { + k=x; + for (i=0;i<16;i++) { + kx=x+i; + t=bitmap[i+j*16]; + for (k=0;k<8;k++) { + ky=y+j*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp16x64(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,j,k,kx,ky; + if (x<(LCD_Xmax-15) && y==0) // boundary check + for (j=0;j<8; j++) { + k=x; + for (i=0;i<16;i++) { + kx=x+i; + t=bitmap[i+j*16]; + for (k=0;k<8;k++) { + ky=y+j*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp32x16(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,jx,jy,k,kx,ky; + if (x<(LCD_Xmax-31) && y<(LCD_Ymax-15)) // boundary check + for (jy=0;jy<2;jy++) + for (jx=0;jx<2;jx++) { + k=x; + for (i=0;i<16;i++) { + kx=x+jx*16+i; + t=bitmap[i+jx*16+jy*32]; + for (k=0;k<8;k++) { + ky=y+jy*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp32x32(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,jx,jy,k, kx,ky; + if (x<(LCD_Xmax-31) && y<(LCD_Ymax-31)) // boundary check + for (jy=0;jy<4;jy++) + for (jx=0;jx<2;jx++) { + k=x; + for (i=0;i<16;i++) { + kx=x+jx*16+i; + t=bitmap[i+jx*16+jy*32]; + for (k=0;k<8;k++) { + ky=y+jy*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp32x48(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,jx,jy,k, kx,ky; + if (x<(LCD_Xmax-31) && y<(LCD_Ymax-47)) // boundary check + for (jy=0;jy<6;jy++) + for (jx=0;jx<2;jx++) { + k=x; + for (i=0;i<16;i++) { + kx=x+jx*16+i; + t=bitmap[i+jx*16+jy*32]; + for (k=0;k<8;k++) { + ky=y+jy*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp32x64(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t,i,jx,jy,k, kx,ky; + if (x<(LCD_Xmax-31) && y==0) // boundary check + for (jy=0;jy<8;jy++) + for (jx=0;jx<2;jx++) { + k=x; + for (i=0;i<16;i++) { + kx=x+jx*16+i; + t=bitmap[i+jx*16+jy*32]; + for (k=0;k<8;k++) { + ky=y+jy*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBmp64x64(int x, int y, int fgColor, int bgColor, unsigned char bitmap[]) +{ + uint8_t t, i,jx,jy,k, kx,ky; + if (x<(LCD_Xmax-63) && y==0) // boundary check + for (jy=0;jy<8;jy++) + for (jx=0;jx<4;jx++) { + k=x; + for (i=0;i<16;i++) { + kx=x+jx*16+i; + t=bitmap[i+jx*16+jy*64]; + for (k=0;k<8;k++) { + ky=y+jy*8+k; + if (t&(0x01<<k)) drawPixel(kx,ky,fgColor,bgColor); + } + } + } +} + +void SSD1306::drawBMP(unsigned char *buffer) +{ + uint8_t x,y; + for (x=0; x<LCD_Xmax; x++) { + for (y=0; y<(LCD_Ymax/8); y++) { + lcdSetAddr(x ,y); + lcdWriteData(buffer[x+y*LCD_Xmax]); + } + } +} +