最近刚接触的一个案子,调一个0.49寸屏的驱动,做一款苹果线材,现在把IIC驱动和显示代码发布下,仅供参考:
IIC写这个函数,有些8051 IC是需要加delay();的,不加可能不能正常驱动屏,开始时我也没加,后来加上了IIC就写OK了。
点阵字模提取方法:我用的是zimo221.exe这个字模提取工具,开始不太会用,总是显示不出你想要的。后面弄了几次就找到门路了,
先新建一个图像,比如16*16或64*32的,然后在底图上画出你要的字或ASCII等,因为是个镜像,所以得上下调换一下
然后在取字模。取了字模后,16*16的字模16进制的,将后面16个16进制数放到数组的前面。如果是64*32的图片,就一次将
后4个16个16进制数放到数组前面,然后一次放后面。
#include "hal_types.h"
#include "hal_mcu.h"
#include "OLED-04901.h"
//======================================================
#define IIC_init() P1SEL = 0;P1DIR = 0x0C;P1 = 0x0C
#define SCL P1_2 //接口定义:lcd_sclk就是LCD的SCLK //SCLK接到“D0”脚
#define SDA P1_3 //接口定义:lcd_sda就是LCD的SDA //SDIN接到“D1”脚
#define key P2_0 //定义一个按键:P2.0口与GND之间接一个按键
void delay(int i)
{
int j,k;
for(j=0;j
for(k=0;k<3;k++);
}
void write_w(unsigned char dat)
{
unsigned char m,da;
unsigned char j;
da=dat;
for(j=0;j<8;j++)
{
m=da;
delay(1);
SCL=0;
m=m&0x80;
if(m==0x80)
{
SDA=1;
}
else
{
SDA=0;
}
da=da<<1;
//delay(20);
SCL=1;
}
SCL=0;
delay(1);
SCL=1;
}
void transfer_command(unsigned char ins)
{
start();
write_w(0x78);
write_w(0x00);
write_w(ins);
stop();
}
void transfer_data(unsigned char dat)
{
start();
write_w(0x78);
write_w(0x40);
write_w(dat);
stop();
}
void start()
{
SCL=1;
SDA=1;
SDA=0;
SCL=0;
}
void stop()
{
SCL=0;
SDA=0;
SDA=1;
SCL=1;
}
//OLED显示模块初始化
void initial_lcd(void)
{
IIC_init();
delay(30);
#if 1
transfer_command(0xae); //关显示
transfer_command(0xd5); //晶振频率
transfer_command(0x80);
transfer_command(0xa8); //duty设置
transfer_command(0x1f); //duty=1/64
transfer_command(0xd3); //显示偏移
transfer_command(0x00);
transfer_command(0x40); //起始行
transfer_command(0x8d); //升压允许
transfer_command(0x14);
transfer_command(0x20); //page address mode
transfer_command(0x02);
transfer_command(0xc8); //行扫描顺序:从上到下
transfer_command(0xa1); //列扫描顺序:从左到右
transfer_command(0xda); //sequential configuration
transfer_command(0x12);
transfer_command(0x81); //微调对比度,本指令的0x81不要改动,改下面的值
transfer_command(0xcf); //微调对比度的值,可设置范围0x00~0xff
transfer_command(0xd9); //Set Pre-Charge Period
transfer_command(0xf1);
transfer_command(0xdb); //Set VCOMH Deselect Level
transfer_command(0x40);
transfer_command(0xaf); //开显示
#else
transfer_command(0xAE); /*display off*/
transfer_command(0x00); /*set lower column address*/
transfer_command(0x12); /*set higher column address*/
transfer_command(0x00); /*set display start line*/
transfer_command(0xB0); /*set page address*/
transfer_command(0x81); /*contract control*/
transfer_command(0x4f); /*128*/
transfer_command(0xA1); /*set segment remap*/
transfer_command(0xA6); /*normal / reverse*/
transfer_command(0xA8); /*multiplex ratio*/
transfer_command(0x1F); /*duty = 1/32*/
transfer_command(0xC8); /*Com scan direction*/
transfer_command(0xD3); /*set display offset*/
transfer_command(0x00);
transfer_command(0xD5); /*set osc division*/
transfer_command(0x80);
transfer_command(0xD9); /*set pre-charge period*/
transfer_command(0x1f);
transfer_command(0xDA); /*set COM pins*/
transfer_command(0x12);
transfer_command(0xdb); /*set vcomh*/
transfer_command(0x40);
transfer_command(0x8d); /*set charge pump enable*/
transfer_command(0x14);
transfer_command(0xAF); /*display ON*/
#endif
}
void lcd_address(uint8 page,uint8 column)
{
column=column-1; //我们平常所说的第1列,在LCD驱动IC里是第0列。所以在这里减去1.
page=page-1;
transfer_command(0xb0+page); //设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页,在LCD驱动IC里是第0页,所以在这里减去1
transfer_command(((column>>4)&0x0f)+0x12); //设置列地址的高4位
transfer_command(column&0x0f); //设置列地址的低4位
//transfer_command(column+0x12);
}
//全屏清屏
void clear_screen(void)
{
unsigned char i,j;
for(j=0;j<8;j++)
{
lcd_address(1+j,1);
for(i=0;i<128;i++)
{
transfer_data(0x00);
}
}
}
//full display test
void full_display(uint8 data1,uint8 data2)
{
int i,j;
for(i=0;i<8;i++)
{
lcd_address(i+1,1);
for(j=0;j<32;j++)
{
transfer_data(data1);
transfer_data(data2);
}
}
}
阅读(2578) | 评论(0) | 转发(0) |