407 wiersze
11 KiB
C
407 wiersze
11 KiB
C
|
|
#include "oled_control.h"
|
|
#include "font5x8.h"
|
|
//
|
|
|
|
void led_send (char nible) {
|
|
char sdata;
|
|
sdata = 0;
|
|
RW = 0; E = 1;
|
|
sdata = sdata + nible;
|
|
sdata = sdata << 4;
|
|
if(LED) sdata = sdata + 8;
|
|
if(E) sdata = sdata + 4;
|
|
if(RW) sdata = sdata + 2;
|
|
if(RS) sdata = sdata + 1;
|
|
//
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(sdata); //
|
|
Soft_I2C_Stop();
|
|
delay_ms(1);
|
|
sdata = sdata - 4; // E = 0
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(sdata); //
|
|
Soft_I2C_Stop();
|
|
delay_ms(1);
|
|
}
|
|
//
|
|
void led_init (void) {
|
|
shift_line = EEPROM_read(7);
|
|
oled_shift = EEPROM_read(8);
|
|
if(led_type>1) oled_init(); // OLED
|
|
else if(led_type==1) { // 1602 LCD display init
|
|
LED = 1;
|
|
RS = 0; // Command
|
|
//
|
|
led_send(3);
|
|
delay_ms(5);
|
|
led_send(3);
|
|
delay_ms(1);
|
|
led_send(3);
|
|
led_send(2);
|
|
//
|
|
led_send(2);
|
|
led_send(8); //
|
|
//
|
|
led_send(0);
|
|
led_send(8); // LCD OFF
|
|
//
|
|
led_send(0);
|
|
led_send(1); // LCD clear
|
|
delay_ms(5);
|
|
//
|
|
led_send(0);
|
|
led_send(4 + 2); // I/D, S
|
|
//
|
|
led_send(0);
|
|
led_send(8 + 4 + 0 + 0); // LCD ON, Cursor, Blink Cursor
|
|
}
|
|
}
|
|
|
|
void dysp_on() {
|
|
if(led_type > 1) send_command(0xAF); // display ON
|
|
else if(led_type==1) {
|
|
LED = 1;
|
|
RS = 0;
|
|
led_send(0);
|
|
led_send(0);
|
|
}
|
|
}
|
|
|
|
void dysp_off() {
|
|
if(led_type > 1) send_command(0xAE); // display OFF
|
|
else if(led_type==1) {
|
|
LED = 0;
|
|
RS = 0;
|
|
led_send(0);
|
|
led_send(0);
|
|
}
|
|
}
|
|
|
|
|
|
void oled_init (void) { // OLED init
|
|
char i, r;
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(0); // 0 - continious mode, command; 64 - Co, data
|
|
Soft_I2C_Write (0xAE); // display OFF
|
|
//
|
|
if(led_type==2 | led_type==3) { // 128*32 OLED
|
|
Soft_I2C_Write (0xD5); // clock division
|
|
Soft_I2C_Write (0x80); // ratio
|
|
//
|
|
Soft_I2C_Write (0xA8); // multiplexer
|
|
Soft_I2C_Write (0x3f); //
|
|
//
|
|
Soft_I2C_Write (0xD3); // offset
|
|
if(led_type==2) Soft_I2C_Write (0 + shift_line); // column shift
|
|
else Soft_I2C_Write (31 + shift_line); // column shift
|
|
//
|
|
Soft_I2C_Write (0x40); // set line, line = 0
|
|
//
|
|
Soft_I2C_Write (0x8D); // charge pump
|
|
Soft_I2C_Write (0x14); // 0x10 - external, 0x14 - internal
|
|
//
|
|
Soft_I2C_Write (0x81); // contrast
|
|
Soft_I2C_Write (180); // 0-255
|
|
//
|
|
Soft_I2C_Write (0xD9); // pre-charge
|
|
Soft_I2C_Write (0x22); // 0x22 - external, 0xF1 - internal
|
|
//
|
|
Soft_I2C_Write (0x20); // memory addressing mode
|
|
Soft_I2C_Write (0x02); // page addressing mode
|
|
//
|
|
Soft_I2C_Write (0x21); // set column range
|
|
Soft_I2C_Write (0); // column start
|
|
Soft_I2C_Write (127); // column stop
|
|
//
|
|
Soft_I2C_Write (0x2E); // stop scrolling
|
|
//
|
|
if(led_type==2) {
|
|
Soft_I2C_Write (0xA0); // segment re-map, A0 - normal, A1 - remapped
|
|
//
|
|
Soft_I2C_Write (0xC0); // scan direction, C0 - normal, C8 - remapped
|
|
}
|
|
else {
|
|
Soft_I2C_Write (0xA1); // segment re-map, A0 - normal, A1 - remapped
|
|
//
|
|
Soft_I2C_Write (0xC8); // scan direction, C0 - normal, C8 - remapped
|
|
}
|
|
//
|
|
Soft_I2C_Write (0xDA); // COM pins configure
|
|
Soft_I2C_Write (0x02); // 12 for x64
|
|
//
|
|
Soft_I2C_Write (0xDB); // V-COM detect
|
|
Soft_I2C_Write (0x40); //
|
|
//
|
|
}
|
|
else { // 128*64 OLED
|
|
Soft_I2C_Write (0xD5); // clock division
|
|
Soft_I2C_Write (0x80); // ratio
|
|
//
|
|
Soft_I2C_Write (0xA8); // multiplexer
|
|
Soft_I2C_Write (63); //
|
|
//
|
|
Soft_I2C_Write (0xD3); // offset
|
|
Soft_I2C_Write (shift_line); // no offset for x64 !
|
|
//
|
|
Soft_I2C_Write (0x40); // set line, line = 0
|
|
//
|
|
Soft_I2C_Write (0x8D); // charge pump
|
|
Soft_I2C_Write (0x14); // 0x10 - external, 0x14 - internal
|
|
//
|
|
Soft_I2C_Write (0x81); // contrast
|
|
Soft_I2C_Write (255); // 0-255
|
|
//
|
|
Soft_I2C_Write (0xD9); // pre-charge
|
|
Soft_I2C_Write (0xf1); // 0x22 - external, 0xF1 - internal
|
|
//
|
|
Soft_I2C_Write (0x20); // memory addressing mode
|
|
Soft_I2C_Write (0x02); // page addressing mode 02
|
|
//
|
|
Soft_I2C_Write (0x21); // set column range
|
|
Soft_I2C_Write (0); // column start
|
|
Soft_I2C_Write (127); // column stop
|
|
//
|
|
Soft_I2C_Write (0x2E); // stop scrolling
|
|
//
|
|
if(led_type==4) {
|
|
Soft_I2C_Write (0xA0); // segment re-map, A0 - normal, A1 - remapped
|
|
//
|
|
Soft_I2C_Write (0xC0); // scan direction, C0 - normal, C8 - remapped
|
|
}
|
|
else {
|
|
Soft_I2C_Write (0xA1); // segment re-map, A0 - normal, A1 - remapped
|
|
//
|
|
Soft_I2C_Write (0xC8); // scan direction, C0 - normal, C8 - remapped
|
|
}
|
|
//
|
|
Soft_I2C_Write (0xDA); // COM pins configure
|
|
Soft_I2C_Write (0x12); // 12 for x64
|
|
//
|
|
Soft_I2C_Write (0xDB); // V-COM detect
|
|
Soft_I2C_Write (0x40); //
|
|
}
|
|
Soft_I2C_Write (0xA4); // display entire ON
|
|
//
|
|
Soft_I2C_Write (0xA6); // 0xA6 - normal, 0xA7 - inverse
|
|
//
|
|
Soft_I2C_Stop ();
|
|
//
|
|
// ********clear OLED***********
|
|
//
|
|
Delay_ms(100);
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(64); // 0 - continious mode, command; 64 - Co, data
|
|
//
|
|
if(led_type==2 | led_type==3) { // 128*32 OLED
|
|
for (r = 0; r <=3; r++) {
|
|
set_addressing (r, 0); // clear all 4 pages
|
|
for (i = 0; i < 128; i++, Soft_I2C_Write(0)); // clear one page pixels
|
|
}
|
|
}
|
|
else { // 128*64 OLED
|
|
for (r = 0; r <=7; r++) {
|
|
set_addressing (r, 0); // clear all 8 pages
|
|
for (i = 0; i < 128; i++, Soft_I2C_Write(0x00)); // clear one page pixels
|
|
}
|
|
|
|
}
|
|
//
|
|
Soft_I2C_Stop ();
|
|
send_command (0xAF); // display ON
|
|
//
|
|
|
|
}
|
|
|
|
|
|
|
|
void send_command (char oled_command) {
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(128); // 128 - command, 192 - data
|
|
Soft_I2C_Write(oled_command);
|
|
Soft_I2C_Stop();
|
|
}
|
|
|
|
void set_addressing (char pagenum, char c_start) {
|
|
char a, b, c;
|
|
c = c_start + oled_shift;
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(0); // 0 - continious mode, command; 64 - Co, data
|
|
Soft_I2C_Write(0xB0 + pagenum); // set page number
|
|
//
|
|
if (c <= 15) { a = c; b = 0; }
|
|
else { b = c / 16; a = c - b * 16; }
|
|
Soft_I2C_Write (a); // set lower nibble of start address
|
|
Soft_I2C_Write (0x10 + b); // set higher nibble of start address
|
|
//
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(64); // 0 - continious mode, command; 64 - Co, data
|
|
}
|
|
//
|
|
|
|
|
|
void led_wr_str (char col, char pos, char str[], char leng ) { //
|
|
char i;
|
|
if(led_type==4 | led_type==5) oled_wr_str(pos, col, str, leng); // 128*64 OLED display
|
|
else if(led_type==2 | led_type==3) oled_wr_str(7*pos+4, col*2, str, leng); // 128*32 OLED display
|
|
else { // 1602 LCD
|
|
// Set address
|
|
RS = 0;
|
|
led_send(8 + col*4);
|
|
led_send(pos);
|
|
//
|
|
RS = 1;
|
|
for (i = 0; i < leng; i++) { // write string
|
|
// write letter
|
|
led_send(str[i] >> 4);
|
|
led_send(str[i]);
|
|
}
|
|
|
|
}
|
|
}
|
|
//
|
|
|
|
void oled_wr_str (char col, char page, char str[], char leng ) { // 128*32 or 128*64 OLED
|
|
char i, h, g, w1, w2;
|
|
Soft_I2C_Start();
|
|
Soft_I2C_Write(led_addr); // device addres
|
|
Soft_I2C_Write(64); // 0 - continious mode, command; 64 - Co, data
|
|
//
|
|
set_addressing (page, col);
|
|
//
|
|
for (i = 0; i < leng; i++) { // write string
|
|
if (str[i] == 0) g = 0; else g = str[i] - 32; // NULL detection
|
|
for (h = 0; h <= 4; h++) { // write letter
|
|
w1 = font5x8[g*5+h];
|
|
if(page!=2 & page!=4 & page!=6) {
|
|
w2.B7 = w1.B3;
|
|
w2.B6 = w1.B3;
|
|
w2.B5 = w1.B2;
|
|
w2.B4 = w1.B2;
|
|
w2.B3 = w1.B1;
|
|
w2.B2 = w1.B1;
|
|
w2.B1 = w1.B0;
|
|
w2.B0 = w1.B0;
|
|
}
|
|
else {
|
|
w2.B7 = w1.B2;
|
|
w2.B6 = w1.B2;
|
|
w2.B5 = w1.B1;
|
|
w2.B4 = w1.B1;
|
|
w2.B3 = w1.B0;
|
|
w2.B2 = w1.B0;
|
|
w2.B1 = 0;
|
|
w2.B0 = 0;
|
|
}
|
|
Soft_I2C_Write(w2);
|
|
if(led_type==4 | led_type==5) Soft_I2C_Write(w2); // 128*64
|
|
}
|
|
Soft_I2C_Write (0);
|
|
Soft_I2C_Write (0);
|
|
}
|
|
set_addressing (page+1, col);
|
|
//
|
|
for (i = 0; i < leng; i++) { // write string
|
|
if (str[i] == 0) g = 0; else g = str[i] - 32; // NULL detection
|
|
for (h = 0; h <= 4; h++) { // write letter
|
|
w1 = font5x8[g*5+h];
|
|
if(page!=2 & page!=4 & page!=6) {
|
|
w2.B7 = w1.B7;
|
|
w2.B6 = w1.B7;
|
|
w2.B5 = w1.B6;
|
|
w2.B4 = w1.B6;
|
|
w2.B3 = w1.B5;
|
|
w2.B2 = w1.B5;
|
|
w2.B1 = w1.B4;
|
|
w2.B0 = w1.B4; }
|
|
else {
|
|
w2.B7 = w1.B6;
|
|
w2.B6 = w1.B6;
|
|
w2.B5 = w1.B5;
|
|
w2.B4 = w1.B5;
|
|
w2.B3 = w1.B4;
|
|
w2.B2 = w1.B4;
|
|
w2.B1 = w1.B3;
|
|
w2.B0 = w1.B3;
|
|
}
|
|
Soft_I2C_Write(w2);
|
|
if(led_type==4 | led_type==5) Soft_I2C_Write(w2); // 128*64
|
|
}
|
|
Soft_I2C_Write (0);
|
|
Soft_I2C_Write (0);
|
|
//if(led_type==2 | led_type==3) Soft_I2C_Write (0); // 128*32
|
|
}
|
|
Soft_I2C_Stop ();
|
|
}
|
|
|
|
|
|
|
|
void Soft_I2C_Init () {
|
|
led_addr = EEPROM_read(0); // 4E,7E for 1602 or 78, 7A for OLED
|
|
led_type = EEPROM_read(1);
|
|
if(led_type==0) {
|
|
Soft_I2C_Scl_Direction = 0;
|
|
Soft_I2C_Sda_Direction = 0;
|
|
LATB.B6 = 1;
|
|
LATB.B7 = 1;
|
|
}
|
|
else {
|
|
Soft_I2C_Scl_Direction = 1;
|
|
Soft_I2C_Sda_Direction = 1;
|
|
Soft_I2C_Scl = 0;
|
|
Soft_I2C_Sda = 0;
|
|
}
|
|
}
|
|
|
|
void Soft_I2C_Start () {
|
|
if(led_type!=0) {
|
|
Soft_I2C_Scl_Direction = 1;
|
|
Delay_us(5);
|
|
Soft_I2C_Sda_Direction = 1;
|
|
Delay_us(5);
|
|
Soft_I2C_Sda_Direction = 0;
|
|
Delay_us(5);
|
|
Soft_I2C_Scl_Direction = 0;
|
|
Delay_us(5);
|
|
}
|
|
}
|
|
|
|
void Soft_I2C_Write (char d) {
|
|
char i;
|
|
if(led_type!=0) {
|
|
for(i=0; i<=7; i++) {
|
|
if(d.B7==0) Soft_I2C_Sda_Direction = 0; else Soft_I2C_Sda_Direction = 1;
|
|
Delay_us(5);
|
|
Soft_I2C_Scl_Direction = 1;
|
|
Delay_us(5);
|
|
Soft_I2C_Scl_Direction = 0;
|
|
Delay_us(5);
|
|
d = d << 1;
|
|
}
|
|
//
|
|
Soft_I2C_Sda_Direction = 1; //ACK
|
|
Delay_us(5);
|
|
Soft_I2C_Scl_Direction = 1;
|
|
Delay_us(5);
|
|
Soft_I2C_Scl_Direction = 0;
|
|
Delay_us(5);
|
|
}
|
|
}
|
|
|
|
void Soft_I2C_Stop () {
|
|
if(led_type!=0) {
|
|
Soft_I2C_Sda_Direction = 0;
|
|
Delay_us(5);
|
|
Soft_I2C_Scl_Direction = 1;
|
|
Delay_us(5);
|
|
Soft_I2C_Sda_Direction = 1;
|
|
Delay_us(5);
|
|
}
|
|
} |