#include "avr/io.h"
#include "util/delay.h"
#include "LibOled.h"
#include "LibAscii.h"
#include <util/twi.h>
#define OLED_SEG_COUNT 128
#define OLED_ROW_COUNT 64
#define OLED_PAGE_COUNT 8
#define OLED_ROW_PER_PAGE 8
unsigned char OLED_GRAM[OLED_SEG_COUNT][OLED_PAGE_COUNT]={{0}};
unsigned char OLED_GRAM_FLG[OLED_SEG_COUNT]={0};
//unsigned char OLED_GRAM[1][1];
#if OLED_I2C
void I2CInit(void);
unsigned char I2CStart(void);
void I2CStop(void);
#elif OLED_4LINE
#endif
void OLEDInit(void);
unsigned char OLEDWriteBus(unsigned char data);
void OLEDWriteCmd(unsigned char cmd);
void OLEDWriteData(unsigned char dat);
void OLEDSetPos(unsigned char x, unsigned char y);
void OLEDSetPoint(unsigned char x,unsigned char y,unsigned char dot);
void OLEDSetPointBuffer(unsigned char x,unsigned char y,unsigned char dot);
void OLEDFillBuffer(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char dot);
void OLEDFill(unsigned char dat);
void OLEDUpdateBuffer();
void OLED6x8Str(unsigned char x, unsigned char y,char ch[]);
void OLEDWord(unsigned char x, unsigned char y, int uIntNum);
void OLEDRefreshLevel(unsigned int levelAD, unsigned char *levelPageLast, unsigned char x1, unsigned char x2);
#if OLED_I2C
void I2CInit(void)
{
// 16 M晶振,400K TWI 速率
TWBR=0x0a;
//TWBR=0x20;
TWAR=0x00;
//TWCR=0x94;
TWCR = (1 << TWEA) | (1 << TWEN); //允许ACK,使能I2C,PC0、PC1转换成SCL、SDA引脚
TWSR=0x00;
}
unsigned char I2CStart(void)
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))){};
return 1;
}
void I2CStop(void)
{
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
unsigned char OLEDWriteBus(unsigned char data)
{
unsigned char ack=1;
TWDR=data;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))){};
if((TWSR&0xF8)!=TW_MT_SLA_ACK)
ack=0;
return ack;
}
void OLEDWriteCmd(unsigned char cmd)
{
I2CStart();
OLEDWriteBus(0x78);//Slave Address b7 b6 b5 b4 b3 b2 b1 b0
// 0 1 1 1 1 0 0 0(R/W#)
OLEDWriteBus(0x00);//Control byte CO D/C# 00000000
OLEDWriteBus(cmd);
I2CStop();
}
void OLEDWriteData(unsigned char dat)
{
I2CStart();
OLEDWriteBus(0x78);//Slave Address b7 b6 b5 b4 b3 b2 b1 b0
// 0 1 1 1 1 0 0 0(R/W#)
OLEDWriteBus(0x40);//Control byte CO D/C# 01000000
OLEDWriteBus(dat);
I2CStop();
}
/*
unsigned char OLEDReadBus(unsigned char ack)
{
if (ack)
TWCR = (1<<TWINT) | (1<<TWEA) | (1 << TWEN);
else
TWCR = (1<<TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
return (TWDR);
}
*/
#elif OLED_4LINE
unsigned char OLEDWriteBus(unsigned char data)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((data << i) & 0x80)
OLED_SDA_1;
else
OLED_SDA_0;
OLED_SCL_0;
OLED_SCL_1;
}
return 1;
}
void OLEDWriteCmd(unsigned char cmd)
{
OLED_DC_0;
OLEDWriteBus(cmd);
}
void OLEDWriteData(unsigned char dat)
{
OLED_DC_1;
OLEDWriteBus(dat);
}
#endif
void OLEDSetPoint(unsigned char x,unsigned char y,unsigned char dot)
{
unsigned char page,row,data=0;
if(x>OLED_SEG_COUNT-1||y>OLED_PAGE_COUNT*OLED_ROW_PER_PAGE-1)return;
page=y/OLED_ROW_PER_PAGE;
row=y%OLED_ROW_PER_PAGE;
if(dot)
data|=(1<<row);
else
data&=~(1<<row);
OLEDSetPos(x,page);
OLEDWriteData(data);
}
void OLEDFill(unsigned char dat)
{
unsigned char y,x;
for(y=0;y<OLED_PAGE_COUNT;y++)
{
OLEDSetPos(0,y);
for(x=0;x<OLED_SEG_COUNT;x++)
OLEDWriteData(dat);
}
}
void OLEDSetPos(unsigned char x, unsigned char y)
{
OLEDWriteCmd(0xb0+y);
OLEDWriteCmd(((x&0xf0)>>4)+0x10);
//OLEDWriteCmd((x&0x0f)|0x01);
OLEDWriteCmd(x&0x0f);
}
void OLEDSetPointBuffer(unsigned char x,unsigned char y,unsigned char dot)
{
unsigned char page,row;
if(x>OLED_SEG_COUNT-1||y>OLED_PAGE_COUNT*OLED_ROW_PER_PAGE-1)return;
page=y/OLED_ROW_PER_PAGE;
row=y%OLED_ROW_PER_PAGE;
if(dot)OLED_GRAM[x][page]|=(1<<row);
else OLED_GRAM[x][page]&=~(1<<row);
OLED_GRAM_FLG[x] |= (1<<page);
}
void OLEDFillBuffer(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char dot)
{
unsigned char x,y;
for(x=x1;x<=x2;x++)
{
for(y=y1;y<=y2;y++)OLEDSetPointBuffer(x,y,dot);
}
}
void OLEDUpdateBuffer()
{
unsigned char i,j;
for(i=0;i<OLED_SEG_COUNT;i++)
{
for(j=0;j<OLED_PAGE_COUNT;j++)
{
if(OLED_GRAM_FLG[i] & (1<<j))
{
OLEDSetPos(i,j);
OLEDWriteData(OLED_GRAM[i][j]);
OLED_GRAM_FLG[i]&=~(1<<j);
}
}
}
}
void OLEDInit(void)
{
#if OLED_I2C
_delay_ms(100);
I2CInit();
_delay_ms(100);
#elif OLED_4LINE
OLED_CTRL_DDR |= (1 << OLED_RST) | (1 << OLED_DC) | (1 << OLED_SCL) | (1 << OLED_SDA);
_delay_ms(100);
OLED_SCL_1;
OLED_RST_0;
_delay_ms(100);
OLED_RST_1; //从上电到下面开始初始化要有足够的时间,即等待RC复位完毕
#endif
OLEDWriteCmd(0xae);//--turn off oled panel
OLEDWriteCmd(0xd5);//--set display clock divide ratio/oscillator frequency
OLEDWriteCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
OLEDWriteCmd(0xa8);//--set multiplex ratio(1 to 64)
OLEDWriteCmd(0x3f);//--1/64 duty 若是128*32 LCD_WrCmd(0x1F);
OLEDWriteCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLEDWriteCmd(0x00);//-not offset
OLEDWriteCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLEDWriteCmd(0x8d);//--set Charge Pump enable/disable
OLEDWriteCmd(0x14);//--set(0x10) disable
OLEDWriteCmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLEDWriteCmd(0xc8);//--Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLEDWriteCmd(0xda);//--set com pins hardware configuration
OLEDWriteCmd(0x12);
OLEDWriteCmd(0x81);//--set contrast control register
OLEDWriteCmd(0x10);//--Set SEG Output Current Brightness
OLEDWriteCmd(0xd9);//--set pre-charge period
OLEDWriteCmd(0xf1);//--Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLEDWriteCmd(0xdb);//--set vcomh
OLEDWriteCmd(0x30);//Set VCOM Deselect Level
OLEDWriteCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
OLEDWriteCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
_delay_ms(100);
OLEDFillBuffer(0,0,OLED_SEG_COUNT-1,OLED_ROW_COUNT-1,0);
OLEDUpdateBuffer();
OLEDWriteCmd(0xaf);//--turn on oled panel
_delay_ms(100);
/*
OLEDWriteCmd(0xae);//--turn off oled panel
OLEDWriteCmd(0x00);//---set low column address
OLEDWriteCmd(0x10);//---set high column address
OLEDWriteCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLEDWriteCmd(0x81);//--set contrast control register
OLEDWriteCmd(0xcf); // Set SEG Output Current Brightness
OLEDWriteCmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLEDWriteCmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLEDWriteCmd(0xa6);//--set normal display
OLEDWriteCmd(0xa8);//--set multiplex ratio(1 to 64)
OLEDWriteCmd(0x3f);//--1/64 duty 若是128*32 LCD_WrCmd(0x1F);
OLEDWriteCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLEDWriteCmd(0x00);//-not offset
OLEDWriteCmd(0xd5);//--set display clock divide ratio/oscillator frequency
OLEDWriteCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
OLEDWriteCmd(0xd9);//--set pre-charge period
OLEDWriteCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLEDWriteCmd(0xda);//--set com pins hardware configuration
OLEDWriteCmd(0x12);
OLEDWriteCmd(0xdb);//--set vcomh
OLEDWriteCmd(0x30);//Set VCOM Deselect Level
OLEDWriteCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02) 若是128*32 LCD_WrCmd(0x02);
OLEDWriteCmd(0x02);//
OLEDWriteCmd(0x8d);//--set Charge Pump