|
|
Microcontroller example with an Atmel AVR
The µOLED-96-G1 module is very easy to interface with a microcontroller because you only need one resistor when the circuit is working on 5V (with 3.3V system you don't even need the resistor). I'm using an Atmel ATmega8 for this example, but it is possible to use any microcontroller where you can get serial data out. If the user wants to interface the display with a microcontroller, the serial platform firmware has to be loaded onto the module with a computer first.

Display and microcontroller schematic

Display and microcontroller on prototyping board
The code is very easy to do as you just send simple commands over the serial line to the display. The user manual for the display module tells you everything you need to know and lists all the possible commands that you can use for controlling the display. The example code shows some functions made according to the manual, eg. clear screen, set background color, draw a circle...

Microcontroller controlling the display
The example code initialized the display and starts drawing a simple bouncing ball, but without clearing the screen between the steps so it leaves a trail behind. The color is changed on every step and it is set to smoothly fade the color from one to another so in the end the screen is filled with a colorful pattern.
!!NOTE!! Don't worry about the refresh lines of the display on the video, they are just because of the camera, you can't see them with your bare eye.
The code:
/**
* MetkuMods - /
* OLED displays from 4D Systems
* AVR + µOLED-96-G1 example
*
* Author: Aki Korhonen
* Date: 2009-06-08
*/
// If clock speed isn't set in the project settings then it is set here
#ifndef F_CPU
#define F_CPU 4000000UL // 4 MHz
#endif
#define BAUD 9600
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <util/delay.h>
#include <util/setbaud.h>
#include <math.h>
// ------------------------------------- //
// General stuff
#define OLED_RES 4
uint16_t counter = 0;
// ------------------------------------- //
// Screen stuff
#define DISP_HEIGHT 64
#define DISP_WIDTH 96
uint16_t color_16b = 0x0000;
// Bouncing Ball
uint8_t bb_x_step = 1;
uint8_t bb_y_step = 1;
uint8_t bb_size = 4;
uint8_t bb_x = 5;
uint8_t bb_y = 10;
uint8_t bb_color_r = 16;
uint8_t bb_color_g = 0;
uint8_t bb_color_b = 16;
int8_t bb_color_r_step = 1;
int8_t bb_color_g_step = 1;
int8_t bb_color_b_step = 2;
// ------------------------------------- //
// Function Prototypes
void BouncingBall();
// ------------------------------------- //
// Serial functions
// UART initialization
void Init_USART(void)
{
UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE;
UCSRA = 0x00;
UCSRB |= (1 << RXEN); // RXEN, Enable RX
UCSRB |= (1 << RXCIE); // RXCIE, Enable RX interrupt
UCSRB |= (1 << TXEN); // TXEN, Enable TX
UCSRC = 0x86; // 8 Data, 1 Stop, No Parity
}
// SendByte sends the wanted byte to the TX line
void USART_SendByte(uint8_t data)
{
// Wait if a byte is being transmitted
loop_until_bit_is_set(UCSRA, UDRE);
// Send the given data
UDR = data;
}
// ReceiveByte reads a byte from RX line
uint8_t USART_ReceiveByte(void)
{
// Wait until a byte has been received
loop_until_bit_is_set(UCSRA, RXC);
// Return received data
return UDR;
}
// ------------------------------------- //
// OLED functions
uint16_t OLED_makeColor(uint8_t red, uint8_t green, uint8_t blue)
{
uint8_t msb, lsb;
uint16_t color;
if(0x1F < red) red = 0x1F;
if(0x3F < green) green = 0x3F;
if(0x1F < blue) blue = 0x1F;
msb = ((red << 3) & ~0b00000111) | ((green >> 3) & ~0b11111000);
lsb = ((green << 5) & ~0b00011111) | (blue & ~0b11100000);
color = (((uint16_t)msb) << 8) | lsb;
return color;
}
void OLED_setBackgroundColor(uint16_t color)
{
USART_SendByte(0x42);
USART_SendByte((color >> 8));
USART_SendByte((uint8_t)color);
}
void OLED_drawCircle(uint8_t x, uint8_t y, uint8_t rad, uint16_t color)
{
USART_SendByte(0x43);
if(0x5F < x) x = 0x5F;
if(0x3F < y) y = 0x3F;
if(0x3F < rad) rad = 0x3F;
USART_SendByte(x);
USART_SendByte(y);
USART_SendByte(rad);
USART_SendByte((color >> 8));
USART_SendByte((uint8_t)color);
}
void OLED_eraseScreen()
{
USART_SendByte(0x45);
}
void OLED_putPixel(uint8_t x, uint8_t y, uint16_t color)
{
USART_SendByte(0x50);
USART_SendByte(x);
USART_SendByte(y);
USART_SendByte((color >> 8));
USART_SendByte((uint8_t)color);
}
void OLED_putChar(char c, uint8_t col, uint8_t row, uint16_t color)
{
USART_SendByte(0x54);
USART_SendByte(c);
USART_SendByte(col);
USART_SendByte(row);
USART_SendByte((color >> 8));
USART_SendByte((uint8_t)color);
}
void OLED_Init(void)
{
USART_SendByte(0x55);
}
// ------------------------------------- //
// Interrupts
// Timer0 interrupt
ISR(TIMER0_OVF_vect)
{
// Speed of the ball, smaller value makes faster
if(counter == 20)
{
BouncingBall();
counter = 0;
}
else
{
counter++;
}
}
// RX interrupt, this gets executed when data is coming from the RX line
ISR(USART_RXC_vect)
{
uint8_t c;
// Get the byte that is coming
c = USART_ReceiveByte();
}
// ------------------------------------- //
// Main program
int main(void)
{
DDRD = _BV(OLED_RES);
PORTD = 0xFF;
// Flip the reset line of the display
PORTD &= ~(_BV(OLED_RES));
_delay_ms(2);
PORTD |= _BV(OLED_RES);
// Disable global interrupts
cli();
// Delays, wait for the display to be ready
_delay_ms(700);
_delay_ms(700);
_delay_ms(700);
_delay_ms(700);
// Initialize UART
Init_USART();
// Initialize OLED
OLED_Init();
// Initialize timers
TCCR0 = 0x00;
TCNT0 = 0x00;
TCCR0 = 0b00000010;
TIMSK |= _BV(TOIE0);
// OLED tests
OLED_eraseScreen();
// Enable global interrupts
sei();
while(1)
{
// Nothing is done here
}
return 0;
}
// ------------------------------------------------ //
void BouncingBall()
{
bb_x += bb_x_step;
bb_y += bb_y_step;
if(bb_x <= bb_size/2) // Left
{
bb_y_step *= -1;
bb_x_step += 1;
}
else if(DISP_WIDTH-1-bb_size/2 <= bb_x && bb_x_step > 0) // Right
{
bb_x_step *= -1;
}
if(bb_y <= bb_size/2) // Up
{
bb_y_step *= -1;
}
else if(bb_y > DISP_HEIGHT-1-bb_size/2 && bb_y_step > 0) // Down
{
bb_y_step *= -1;
}
color_16b = OLED_makeColor(bb_color_r, bb_color_g, bb_color_b);
OLED_drawCircle(bb_x, bb_y, bb_size/2, color_16b);
bb_color_r += bb_color_r_step;
bb_color_g += bb_color_g_step;
bb_color_b += bb_color_b_step;
if(bb_color_r >= 0x1F || bb_color_r <= 0)
bb_color_r_step *= -1;
if(bb_color_g >= 0x3F || bb_color_g <= 0)
bb_color_g_step *= -1;
if(bb_color_b >= 0x1F || bb_color_b <= 0)
bb_color_b_step *= -1;
}
// ------------------------------------------------ //
| | Pages: 1 2 3 4 5 6 7 8 9 10 11 12 | |


Content in english!
Sisältö suomeksi!
