OLED display + ATmega8

This is just the sparkfun example code that I modified for an ATmega8.

Parallel 8080 mode.

Since it may be useful, I’ve decided to post it :wink:

/*
 * Mcu type: ATmega8
 * Fuses: Default fuses (1MHz internal osc)
 * Hardware connection:
 * D0		-> PB0
 * D1		-> PB1
 * ...
 * D7		-> PB7
 *
 * RES		-> PC0
 * CS		-> PC1
 * DC		-> PC2
 * E(RD)	-> PC3
 * RW(WR)	-> PC4
 * EN		-> PC5
 *(Not strictly necessary) Connect a led to PD0
 *
 */

#define F_CPU 1000000
#include <inttypes.h>
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

// inialize OLED
void OLED_init(void);

// reset Controller
void Reset_SSD1339(void);

// write command or data
void write_c(unsigned char out_command);
void write_d(unsigned char out_data);

// these write data to the OLED on 8 bit data bus,  depends on MCU
void LCD_out(unsigned char cmd);
unsigned int get_LCD_port(unsigned char data);

// these functions set / clear pins for OLED control lines.  they accecpt a 0 or 1 
void RD(char stat);
void RW(char stat);
void DC(char stat);
void RES(char stat);
void CS(char stat);

#define X_OFFSET 0
#define Y_OFFSET 0

void line(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2)
{
 write_c(0x83);//Draw line
 write_d(X_OFFSET+x1);
 write_d(Y_OFFSET+y1);
 write_d(X_OFFSET+x2);
 write_d(Y_OFFSET+y2);
 write_d(7);//Color green
 write_d(224);
 _delay_ms(10);
}

void long_delay()
{
 uint8_t i;
 for(i=0;i<20;i++) _delay_ms(100);
}

void ioinit()
{
 PORTB=0;
 DDRB=0xFF;//PortB 0..7:Data bus (Out)
 PORTC=31;//'00011111' EN @ 0 (dc-dc off)
 DDRC=63;//'00111111' Pc0=RES Pc1=CS Pc2=D/C Pc3=RD Pc4=WR Pc5=EN
 PORTD=0xFF;
 DDRD=1;//Pd0=Led
}

int main()
{
 int i=0;
 ioinit();
 OLED_init();
 _delay_ms(120);
 write_c(0x8e);    // clear window command
 write_d(0);
 write_d(0);
 write_d(130);
 write_d(130);
 
 long_delay();

 write_c(0x92);    // fill enable command
 write_d(0x01); 
 _delay_ms(10);
 // draw 100 random circles
 for(i = 0;i < 100;i++){
  write_c(0x86);    // draw circle command
  write_d(rand() % 130);
  write_d(rand() % 130);
  write_d(rand() % 64);
  write_d(rand());
  write_d(rand());
  write_d(rand());
  write_d(rand());
  _delay_ms(10);
 }

 long_delay();

 write_c(0x8e);    // clear window command
 write_d(0);
 write_d(0);
 write_d(130);
 write_d(130);
 _delay_ms(100);


 // write directly to ram,  this fills up bottom 1/3 of display with color pattern
 write_c(0x5c);
 for (i = 0; i < 2000; i++){
  write_c(0x5c);  
  write_d(i);
  write_d(i);
  write_d(i);
  _delay_ms(1);
 }

 long_delay();

 write_c(0x8e);    // clear window command
 write_d(0);
 write_d(0);
 write_d(130);
 write_d(130);
 _delay_ms(100);

 line(0,0,127,127);//Draw lines
 line(0,0,10,0);
 line(0,0,0,10);
 line(127,127,117,127);
 line(127,117,127,127);

 for(;;)//Blink LED
 {
  PORTD|=_BV(0);
  _delay_ms(100);
  PORTD&=~_BV(0);
  _delay_ms(100);
 }
}


/**********************************************************
                      Initialize
***********************************************************/

void OLED_init(void)
{
 PORTC|=_BV(5);//EN High (DC-DC ON)
 //LCD_out(0);
 //RD(1);
 //DC(0);
 //RW(0);
 //CS(0);
 Reset_SSD1339();
 write_c(0xa0); // Set Re-map / Color Depth
 write_d(0x34);//0xb4); // 262K 8bit R->G->B (0x34=256color  0xb4=262Kcolor)
 write_c(0xa1); // Set display start line
 write_d(0x00); // 00h start
 write_c(0xa2); // Set display offset
 write_d(0x80); // 80h start
 write_c(0xA6); // Normal display
 write_c(0xad); // Set Master Configuration
 write_d(0x8e); // DC-DC off & external VcomH voltage & internal pre-charge voltage
 write_c(0xb0); // Power saving mode
 write_d(0x05);//
 write_c(0xb1); // Set pre & dis_charge
 write_d(0x11); // pre=1h dis=1h
 write_c(0xb3); // clock & frequency
 write_d(0xf0); // clock=Divser+1 frequency=fh
 write_c(0xbb); // Set pre-charge voltage of color A B C
 write_d(0x1c); // color A
 write_d(0x1c); // color B
 write_d(0x1c); // color C
 write_c(0xbe); // Set VcomH
 write_d(0x1f); //
 write_c(0xc1); // Set contrast current for A B C
 write_d(0xaa); // Color A
 write_d(0xb4); // Color B
 write_d(0xc8); // Color C
 write_c(0xc7); // Set master contrast
 write_d(0x0f); // no change
 write_c(0xca); // Duty
 write_d(0x7f); // 127+1
 write_c(0xaf); // Display on
}
void Reset_SSD1339(void)
{
 RES(0);
 _delay_ms(100);
 RES(1);
}
void write_c(unsigned char out_command)
{
 LCD_out(out_command);
 DC(0);CS(0);RW(0);
 _delay_us(50);
 RW(1);
 CS(1);
 DC(1);
}

void write_d(unsigned char out_data)
{
 LCD_out(out_data);
 DC(1);CS(0);RW(0);
 _delay_us(50);
 RW(1);
 CS(1);
 DC(1);
}

// these functions set / clear pins for LCD control lines.  they accecpt a 0 or 1 
void RD(char stat)
{
 if (stat==1) PORTC|=_BV(3);//Pc3= RD
 else PORTC&=~_BV(3);
}

void RW(char stat)
{
 if (stat==1) PORTC|=_BV(4);//Pc4= RW
 else PORTC&=~_BV(4);
}

void DC(char stat)
{
 if (stat==1) PORTC|=_BV(2);//Pc2= DC
 else PORTC&=~_BV(2);
}

void RES(char stat)
{
 if (stat==1) PORTC|=_BV(0);//Pc0= RES
 else PORTC&=~_BV(0);
}

void CS(char stat)
{
 if (stat==1) PORTC|=_BV(1);//Pc1= CS
 else PORTC&=~_BV(1);
}

// send to the LCD
void LCD_out(unsigned char cmd)
{
 PORTB=cmd;
}

Ah, last thing, is it normal that the brekout board DC-DC regulator outputs 13.6V instead of 12V

What voltage is the oled panel supposed to work?

I tried running your code on an ATMEAGA 8515… and got nothing! :frowning:

I also tried running it on a 90usb1287, the display never lit, but I did get the flashing LED at the end.

I have successfully run the OLED on the 90usb1287 via SPI, but I wanted to try my hand at parallel…

Any ideas?

MDJ

Did you change the jumper settings? parallel mode requires BS1 and BS2 to be @ logic high, while serial requires them to be @ logic low

thanks, that was exactly it… I’m now banging away in parallel mode… thanks so much for the help.