首先,我使用的是SPI协议的0.96寸oled屏幕,如图 相信大家在淘宝下单的时候,能以各种渠道获得“中景园科技”的关于驱动该屏幕的源码,但令人遗憾的是,源码中仅仅包含了写数字,写指数,写符号,写汉字,写图片的各种函数,唯独缺少了画图需要的最基本函数——画点函数。只有了画点函数,我们才可以画线,画方形画圆形等图形。 先贴源码
void OLED_DrawPoint(u8 x,u8 y){
double abs_y=y/8;
double tem_y;
u8 dat;
tem_y=y%8;
abs_y=ceil(abs_y);
switch(tem_y){
case 0:dat=0x01;break;
case 1:dat=0x02;break;
case 2:dat=0x04;break;
case 3:dat=0x08;break;
case 4:dat=0x10;break;
case 5:dat=0x20;break;
case 6:dat=0x40;break;
case 7:dat=0x80;break;
}
oled_RAM[x][(u8)abs_y]+=dat;
OLED_Renew(x);
}
由于仅仅实现画点功能,程序就不写注释了,能用就行。 说明一下各子函数与重要变量,频繁使用double是因为我的这个程序运行在DSP28335中,其double类型与float类型皆占16位,其余环境下需要节省内存可换为float。该函数输入两个变量x与y,分别为屏幕x与y的绝对坐标,x范围0-127,y范围0-63,共128*64分辨率。
abs_y=ceil(abs_y);
为C语言中math.h中自带的向上取整函数,调用时包含math.h即可。
void OLED_Renew(u8 x){
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD);
OLED_WR_Byte (0x00,OLED_CMD);
OLED_WR_Byte (0x10,OLED_CMD);
for(n=0;n<x;n++){
OLED_WR_Byte(oled_RAM[n][i],OLED_DATA);
}
}
}
该函数为刷新屏幕函数,已进行些许优化,根据画点的绝对x坐标来刷新,其余部分不刷新。
typedef unsigned char u8;
至于u8类型就是无符号的char。
unsigned char oled_RAM[128][8];
二维数组oled_RAM即为oled屏幕点阵在单片机内存中的映射。
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD);
OLED_WR_Byte (0x00,OLED_CMD);
OLED_WR_Byte (0x10,OLED_CMD);
for(n=0;n<128;n++){
OLED_WR_Byte(0,OLED_DATA);
oled_RAM[n][i]=0;
}
}
}
然后记得在中景园科技自带的清屏函数中把该数组归零。
void OLED_WR_Byte(u8 dat,u8 cmd)
{
volatile u8 dummy;
if(cmd)
OLED_DC_Set();
else
OLED_DC_Clr();
SpiaRegs.SPITXBUF=(dat<<8);
while(SpiaRegs.SPISTS.bit.INT_FLAG !=1);
dummy=SpiaRegs.SPIRXBUF;
OLED_DC_Set();
}
这是中景园科技自带的oled写字节函数,例程里应该都有,未作修改。
接下来说一下0.96寸oled的画点原理,只需要使用而不需要原理的可以不用看了。 该oled屏幕分为128*64个点阵,左上角坐标为(0,0)右下角坐标为(127,63),如图 屏幕在y轴64格中分为8页,每页有8个格子,代表2个16进制数,即8位,1字节。操作点阵时,可以向屏幕写入1字节来控制这8个格子的亮灭,1为亮0为灭。拿出一页分析 注意,该字节数从下到上为从高到低,最下面为高位。如图所示的一页,只有最上面为1的点是亮的,其他都是灭的,要达成此效果,需要向屏幕写入二进制0000 0001的指令,即是0x01。 由此,若要令某一页最上面与最下面的两个点亮,则应写入二进制1000 0001,即0x81。
|