/******************************** * XS128OLED12864 * by Quex * 2014/7/10 ********************************/ #include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ #define LED_SCL PTT_PTT0 // 时钟定义 #define LED_SDA PTT_PTT1 //数据口D1 #define LED_RST PTT_PTT2 //复位低能电平 #define LED_DC PTT_PTT3 //偏置常低 #define WIDTH 128 #define HEIGHT 64 //写指令: void Write_Cmd(byte cmd){ uchar cycle; //循环量 LED_DC=0; //写命令 LED_SCL=0; //拉低时钟 for(cycle=0;cycle<8;cycle++){ if(cmd&0x80) LED_SDA=1; else LED_SDA=0; // asm("nop"); LED_SCL=1; asm("nop"); asm("nop"); LED_SCL=0; cmd<<=1; } } //写数据 void Write_Data(byte data){ uchar cycle; //循环量 LED_DC=1; //写命令 LED_SCL=0; //拉低时钟 for(cycle=0;cycle<8;cycle++){ if(data&0x80) LED_SDA=1; else LED_SDA=0; // asm("nop"); LED_SCL=1; asm("nop"); asm("nop"); LED_SCL=0; data<<=1; } } //初始化 void OLED_Init(){ DDRT=0xff; //T口作为输出 LED_SCL=1; LED_RST=0; asm("nop"); asm("nop"); LED_RST=1; Write_Cmd(0xa0); //写命令 Write_Cmd(0xc0);//写命令 Write_Cmd(0x8d); //写命令 Write_Cmd(0x14); Write_Cmd(0xaf); //开显示 } //填充数据 void OLED_Fill(byte data) { byte y,x; for(y=0;y<8;y++) { Write_Cmd(0xb0+y);//设置页地址 Write_Cmd(0x01); //设置列低四位 Write_Cmd(0x10); //设置列高四位 for(x=0;x<WIDTH;x++) Write_Data(data); } } //毫秒级延时 void Delay_ms(int ms) { int i,j; if (ms<1) ms=1; for(i=0;i<ms;i++) for(j=0;j<1335;j++); //16MHz--1ms } void main(void) { OLED_Init(); // EnableInterrupts; for(;;) { OLED_Fill(0xf0); Delay_ms(1000); OLED_Fill(0x01); Delay_ms(1000); _FEED_COP(); } }
1,与其他显示屏差不多,如1602(并行数据口),拥有自己的RAM区,需要写指令和写数据;
2,时序图很重要,写指令和写数据的函数都需要看时序图,注意延时;
3,写指令 :选择写指令 DC=02,时钟拉低 SCLK=0,循环右移写入各个位(&0x80从最高位取,然后左移),每写一个位之后,将时钟拉高 SCLK=1,延时两次asm("nop"),再拉低
4,写数据:选择写数据 DC=1 ,时钟拉低 SCLK=0,循环右移写入各个位(&0x80从最高位取,然后左移),每写一个位之后,将时钟拉高 SCLK=1,延时两次asm("nop"),再拉低
5,写字节后拉高时钟,稍微延时后拉低,因为数据在时钟信号 SCLK 的每个上升沿移位到内部寄存器,这一点在时序图也能看出
6,初始化:LED_SCL=1; LED_RST=0; asm("nop"); asm("nop"); LED_RST=1;然后写一系列命令
原文:http://www.cnblogs.com/renlongpingxuexi/p/5246298.html