<ssd1306.h>:
/*--------------------------------------------------------
name: mega8驱动ssd1306 OLed
date: 2015.01.02
coder:J
续: 2015.01.06 没法亮屏
--------------------------------------------------------*/
#include<iom8v.h>
#include<macros.h>
#include "asiic.h"
#define uchar unsigned char
#define uint unsigned int
const xtal = 8;
//延时函数
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 -> PB4 串行数据线SDIN
RES -> PB3 硬复位OLED
D/C -> PB2 命令/数据标志(0,读写命令;1,读写数据)
CS -> OLED片选信号(低电平有效)
-------------------------------------------------------*/
//---------------宏定义---------------------------------
//SCLK
#define SCLK_high (PORTB |= (1<<PB5))
#define SCLK_low (PORTB &=~(1<<PB5))
// SDIN
#define DSDIN_high (PORTB |= (1<<PB4))
#define DSDIN_low (PORTB &=~(1<<PB4))
#define RES_high (PORTB |= (1<<PB3))
#define RES_low (PORTB &=~(1<<PB3))
//写数据
#define DC_high (PORTB |= (1<<PB2))
//写命令
#define DC_low (PORTB &=~(1<<PB2))
//------------------------------------------------------
//端口初始化
void port_init(void)
{
DDRC = 0xff;
PORTC = 0x00;
PORTC |= 0x01;
DDRB = 0xfe;
PORTB = 0x00;
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);//初始位置
}
//==============================================================
//函数名:Oled_6x8_Str(uchar x,uchar y,uchar *p)
//功能描述:写入一组标准ASCII字符串
//参数:显示的位置(x,y),y为页范围0~7,要显示的字符串
//返回:无
//==============================================================
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 ++;
}
}
main:
#include <iom8v.h>
#include <macros.h>
#include "ssd1306.h"
uchar count = 0;
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);
}
}
4 个解决方案
#1
先将硬件的驱动要求搞清楚
#2
应经解决了。感谢你的答复。
#3
问题在哪里?
#4
port ini配置有问题
#1
先将硬件的驱动要求搞清楚
#2
应经解决了。感谢你的答复。
#3
问题在哪里?
#4
port ini配置有问题