用ATmega8驱动OLED代码如下,用ICCAVR编程,显示屏不亮,不知道代码是否有问题,还是需要检查平台的配置?
#include<iom8v.h>
#include<macros.h>
//#include "asiic.h"
#define uchar unsigned char
#define uint unsigned int
const xtal = 8;
const unsigned char f6x8[][6] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
//延时函数
void delay_ms(uchar n)
{
uint i;
for(i=n;i<(uint)(xtal*143-2);i++);//xtal为晶振大小,单位为MHz
}
void delay_us(uint a)
{
uint i;
for(i = 0;i < a;i++)
{
asm("nop");
}
}
/*-------------------------------------------------------
注意: 该模块不和5.0V接口兼容,所以请大家在使用的时候一定
要小心,别直接接到5V的系统上去,接5V 系统时,应串接
3.3K电阻,电源依然是3.3V。
所用模块为4线SPI:每个数据长度均为8位,在SCLK的上升沿,数
据从SDIN移入到SSD1306,并且是高位在前的
D0 -> PB5 串行时钟线SCLK
D1 -> PB3 串行数据线SDIN
RES -> PC6 硬复位OLED
D/C -> PB1 命令/数据标志(0,读写命令;1,读写数据)
CS -> PB2 OLED片选信号(高电平有效)
-------------------------------------------------------*/
//---------------宏定义---------------------------------
//SCLK
#define SCLK_high (PORTB |= (1<<PB5))
#define SCLK_low (PORTB &=~(1<<PB5))
// SDIN
#define DSDIN_high (PORTB |= (1<<PB3))
#define DSDIN_low (PORTB &=~(1<<PB3))
#define RES_high (PORTC |= (1<<PC6))
#define RES_low (PORTC &=~(1<<PC6))
//写数据
#define DC_high (PORTB |= (1<<PB1))
//写命令
#define DC_low (PORTB &=~(1<<PB1))
//------------------------------------------------------
//端口初始化
void port_init(void)
{
DDRC = 0xff;
PORTC = 0x00;
PORTC |= 0x40;
DDRB = 0xff;
PORTB = 0x2f;
//PORTB |=(1<<PB1);
/*
SCLK_high;
DSDIN_high;
DC_low;
RES_high;
*/
}
//向Oled写入数据
void Oled_WR_Data(uchar data)
{
uchar i;
uchar temp = 0;
DC_high; //写数据
SCLK_low;
for(i=0;i<8;i++)
{
temp =data & 0x80;
// SCLK_high;//高位在前
if(temp==0)
{ DSDIN_low; }
else
{ DSDIN_high; }
SCLK_high;
delay_us(10);
SCLK_low;
data <<= 1;
}
// DSDIN_high;
}
//向Oled写入命令
void Oled_WR_Cmd(uchar cmd)
{
uchar i;
uchar temp = cmd & 0x80;
DC_low; //写命令
SCLK_low;
for(i=0;i<8;i++)
{
// SCLK_high; //高位在前
if(temp==0)
{ DSDIN_low; }
else
{ DSDIN_high; }
SCLK_high;
delay_us(10);
SCLK_low;
cmd <<= 1;
}
// DSDIN_high;
}
//满屏
void Oled_Fill(uchar dat)
{
uchar x,y;
for(y=0;y<8;y++)
{
Oled_WR_Cmd(0xb0 + y);
Oled_WR_Cmd(0x01);
Oled_WR_Cmd(0x10);
for(x=0;x<128;x++)
Oled_WR_Data(dat);
}
}
//清屏
void Oled_Cls(void)
{
uchar x,y;
for(y=0;y<8;y++)
{
Oled_WR_Cmd(0xb0 + y);
Oled_WR_Cmd(0x01);
Oled_WR_Cmd(0x10);
for(x=0;x<128;x++)
Oled_WR_Data(0);
}
}
//初始光标位置
void Oled_Set_Pos(uchar x,uchar y)
{
Oled_WR_Cmd(0xb0 + y);
Oled_WR_Cmd(((x & 0xf0)>>4)|0x10);
Oled_WR_Cmd((x & 0x0f)|0x01);
}
// OLED的初始化
void Oled_init(void)
{
SCLK_high;
RES_low;
delay_ms(100);
RES_high;
//从上电到下面开始初始化要有足够的时间,即等待RC复位完毕
Oled_WR_Cmd(0xae);//关闭显示
Oled_WR_Cmd(0x00);//---set low column address
Oled_WR_Cmd(0x10);//---set high column address
Oled_WR_Cmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
Oled_WR_Cmd(0x81);//--对比度设置
Oled_WR_Cmd(0xcf); // Set SEG Output Current Brightness
Oled_WR_Cmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
Oled_WR_Cmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
Oled_WR_Cmd(0xa6);//--set normal display
Oled_WR_Cmd(0xa8);//设置驱动路数(1 to 64)
Oled_WR_Cmd(0x3f);//--1/64 默认0X3F
Oled_WR_Cmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
Oled_WR_Cmd(0x00);//-not offset
Oled_WR_Cmd(0xd5);//--set display clock divide ratio/oscillator frequency
Oled_WR_Cmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
Oled_WR_Cmd(0xd9);//设置预充电周期
Oled_WR_Cmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
Oled_WR_Cmd(0xda);//--set com pins hardware configuration
Oled_WR_Cmd(0x12);
Oled_WR_Cmd(0xdb);//--set vcomh
Oled_WR_Cmd(0x40);//Set VCOM Deselect Level
Oled_WR_Cmd(0x20);//设置内存地址模式 (0x00/0x01/0x02)
Oled_WR_Cmd(0x02);//
Oled_WR_Cmd(0x8d);//电荷泵设置
Oled_WR_Cmd(0x14);//--set(0x10) disable
Oled_WR_Cmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
Oled_WR_Cmd(0xa6);// Disable Inverse Display On (0xa6/a7)
Oled_WR_Cmd(0xaf);//--开启显示
Oled_Fill(0xff);
//Oled_Cls(); //初始清屏
Oled_Set_Pos(0,0);//初始位置
}
void Oled_6x8_Str(uchar x,uchar y,uchar ch)
{
uchar c=0,i=0,j=0;
while (ch)
{
ch -= 32;
if(x > 126)
{
x = 0; y++;
}
Oled_Set_Pos(x,y);
for(i=0;i<6;i++)
Oled_WR_Data(f6x8[ch][i]);
x += 6;
j ++;
}
}
void main(void)
{
port_init();
Oled_init();
Oled_Fill(0xff);
// while(1)
// {
// if((PINB&(1<<PB0))==0)
// {
// while(!(PINB&(1<<PB0)));
// if(count>=10)
// count = 0;
// else
// count += 1;
// }
// delay_ms(5000);
// Oled_Cls();
// Oled_6x8_Str(2,2,count);
// delay_ms(5000);
// Oled_Fill(0x00);
// }
}