/* * si5351a signal generator * * File: oled.c * Author: www.hetenko.org * * Created on 2017/04/08, 10:32 * * Original Author Nicolas Pannwitz (http://pic-projekte.de) */ #include #include "pic16f_i2c.h" #include "oled.h" #include "font5x8.h" #include "font7x16.h" #include "font12x24.h" void oled_command(unsigned char command) { StartI2C(); WriteI2C(SSD1306_DEFAULT_ADDRESS); WriteI2C(0x00); WriteI2C(command); StopI2C(); } void oled_init(void) { // Turn display off oled_command(SSD1306_DISPLAYOFF); oled_command(SSD1306_SETDISPLAYCLOCKDIV); oled_command(0x80); oled_command(SSD1306_SETMULTIPLEX); oled_command(0x3F); oled_command(SSD1306_SETDISPLAYOFFSET); oled_command(0x00); oled_command(SSD1306_SETSTARTLINE | 0x00); // We use internal charge pump oled_command(SSD1306_CHARGEPUMP); oled_command(0x14); // Horizontal memory mode oled_command(SSD1306_MEMORYMODE); oled_command(0x00); oled_command(SSD1306_SEGREMAP | 0x01); oled_command(SSD1306_COMSCANDEC); oled_command(SSD1306_SETCOMPINS); oled_command(0x12); // Max contrast oled_command(SSD1306_SETCONTRAST); oled_command(0x4f); oled_command(SSD1306_SETPRECHARGE); oled_command(0xF1); oled_command(SSD1306_SETVCOMDETECT); oled_command(0x40); oled_command(SSD1306_DISPLAYALLON_RESUME); // Non-inverted display oled_command(SSD1306_NORMALDISPLAY); // oled_command(SSD1306_INVERTDISPLAY); // Turn display back on oled_command(SSD1306_DISPLAYON); } void oled_clear(void) { unsigned int i; StartI2C(); WriteI2C(SSD1306_DEFAULT_ADDRESS); WriteI2C(0x00); WriteI2C(SSD1306_SETPAGEADDRESS); WriteI2C(SSD1306_COLUMNADDR); WriteI2C(SSD1306_SETLOWCOLUMN); WriteI2C(0x7F); StopI2C(); StartI2C(); WriteI2C(SSD1306_DEFAULT_ADDRESS); WriteI2C(0x40); for(i = 0; i < (SSD1306_WIDTH * SSD1306_HEIGHT / 8); i++) WriteI2C(0x00); StopI2C(); } /** * oled_pattern * @param culumn 0-7 * @param x 0-127 * @param pattern BCD code */ void oled_pattern(unsigned int x, unsigned char culumn, unsigned char pattern) { StartI2C(); WriteI2C(SSD1306_DEFAULT_ADDRESS); WriteI2C(0x00); WriteI2C(SSD1306_MEMORYMODE); WriteI2C(0x02); WriteI2C(SSD1306_SETPAGEADDRESS | culumn); WriteI2C(SSD1306_SETLOWCOLUMN | (x & 0xF)); WriteI2C(SSD1306_SETHIGHCOLUMN | ((x >> 4) & 0xF)); StopI2C(); StartI2C(); WriteI2C(SSD1306_DEFAULT_ADDRESS); WriteI2C(0x40); WriteI2C(pattern); StopI2C(); } void oled_char(unsigned char size, unsigned int x, unsigned char culumn, unsigned int fIndex) { unsigned char width; unsigned char height; unsigned char loop; unsigned char i, j; if(size == 0) { width = FONT_SMALL_WIDTH; height = FONT_SMALL_HEIGHT; loop = 1; } else if(size == 1) { width = FONT_MIDIUM_WIDTH; height = FONT_MIDIUM_HEIGHT; loop = 2; } else { width = FONT_LARGE_WIDTH; height = FONT_LARGE_HEIGHT; loop = 3; } for(i = 0; i < loop; i++) { StartI2C(); WriteI2C(SSD1306_DEFAULT_ADDRESS); WriteI2C(0x00); WriteI2C(SSD1306_MEMORYMODE); WriteI2C(0x02); WriteI2C(SSD1306_SETPAGEADDRESS | culumn + i); WriteI2C(SSD1306_SETLOWCOLUMN | (x & 0xF)); WriteI2C(SSD1306_SETHIGHCOLUMN | ((x >> 4) & 0xF)); StopI2C(); StartI2C(); WriteI2C(SSD1306_DEFAULT_ADDRESS); WriteI2C(0x40); for(j = 0; j < width; j++) { if(size == 0) WriteI2C(font_small[fIndex + j * loop + i + 1]); else if(size == 1) WriteI2C(font_midium[fIndex + j * loop + i + 1]); else WriteI2C(font_large[fIndex + j * loop + i + 1]); } StopI2C(); } } void oled_string(unsigned char font, unsigned int x, unsigned char culumn, const char *pS) { unsigned int lIndex, k; unsigned char width; unsigned char height; if(font == 0) { width = FONT_SMALL_WIDTH; height = FONT_SMALL_HEIGHT; } else if(font == 1) { width = FONT_MIDIUM_WIDTH; height = FONT_MIDIUM_HEIGHT; } else { width = FONT_LARGE_WIDTH; height = FONT_LARGE_HEIGHT; } while(*pS) { lIndex = 0; for(k = 0; k < (*pS - ' '); k++) { if(font == 0) lIndex += width + 1; else lIndex += (height / 8) * width + 1; } oled_char(font, x, culumn, lIndex); x += width; pS++; } }