if(dat&0x80)OLED_SDIN=1; else OLED_SDIN=0;
OLED_SCLK=1; dat<<=1; }
OLED_CS=1; OLED_RS=1; } #endif
这里有2个一样的函数,通过宏定义OLED_MODE来决定使用哪一个。如果OLED_MODE=1,就定义为并口模式,选择第一个函数,而如果为0,则为4线串口模式,选择第二个函数。这两个函数输入参数均为2个:dat和cmd,dat为要写入的数据,cmd则表明该数据是命令还是数据。这两个函数的时序操作就是根据上面我们对8080接口以及4线SPI接口的时序来编写的。
OLED_GRAM[128][8]中的128代表列数,也就是x坐标,而8代表的是页,每个代表8个列,从高到底对应列数从小到大。比如,我们要在x=100,y=29这个点写入1,则可以用这个句子实现:
OLED_GRAM[100][4]|=1<<2;
一个通用的在点(x,y)置1表达式为: OLED_GRAM[x][y/8]|=1<<(7-y%8); 因此,我们可以得出下一个画点函数,void OLED_DrawPoint(u8 x,u8 y,u8 t);代码如下:
void OLED_DrawPoint(u8 x,u8 y,u8 t) {
u8 pos,bx,temp=0;
if(x>127||y>63)return;//超出范围了.
pos=7-y/8; bx=y%8;
temp=1<<(7-bx);
if(t)OLED_GRAM[x][pos]|=temp;
else OLED_GRAM[x][pos]&=~temp; }
该函数有3个参数,前两个是坐标,第三个t为要写入1还是0。该函数实现了我们在OLED模块上任意位置画点的功能。
在介绍完画点函数之后,我们介绍一下显示字符函数,OLED_ShowChar,在介绍之前,我们来介绍一下字符(ASCII字符集)是怎么显示在OLED模块上去的。要显示字符,我们先要有字符的点阵数据,ASCII常用的字符集总共有95个,从空格符开始,分别为:!\,-0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.
我们先要得到这个字符集的点阵数据,这里我们介绍一个款很好的字符提取软件:PCtoLCD2002完美版。该软件可以提供各种字符,包括汉字(字体和大小都可以自己设置)阵提取,且取模方式可以设置好几种,常用的取模方式,该软件都支持。该软件还支持图形模式, 也就是用户可以自己定义图片的大小,然后画图,根据所画的图形再生成点阵数据,这功能在制作图标或图片的时候很有用。
该软件的界面如下:
图3.9.3.1 PCtoLCD2002软件界面
然后我们选择设置,在设置里面设置取模方式入下图所示:
图3.9.3.2 设置取模方式
上图设置的取模方式,在右上角的取模说明里面有,即:从第一列开始向下每取8个点作为一个字节,如果最后不足8个点就补满8位。取模顺序是从高到低,即第一个点作为最高位。如*-------取为10000000。其实就是按如下这种方式:
图3.9.3.3 取模方式图解
从上到下,从左到右,高位在前。我们按这样的取模方式,然后把ASCII字符集按12*6大小和16*0大小取模出来(对应汉字大小为12*12和16*16,字符的只有汉字的一半大!),保存在font.h里面,每个12*6的字符占用12个字节,每个16*8的字符占用16个字节。具体见font.h部分代码(该部分我们不再这里列出来了,请大家参考光盘里面的代码)。
在知道了取模方式之后,我们就可以根据取模的方式来编写显示字符的代码了,这里我们针对以上取模方式的显示字符代码如下:
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode) {
u8 temp,t,t1; u8 y0=y;
chr=chr-' ';//得到偏移后的值
for(t=0;t if(size==12)temp=asc2_1206[chr][t]; //调用1206字体 else temp=asc2_1608[chr][t]; //调用1608字体 for(t1=0;t1<8;t1++) { if(temp&0x80)OLED_DrawPoint(x,y,mode); else OLED_DrawPoint(x,y,!mode); temp<<=1; y++; if((y-y0)==size) { y=y0; x++; break; } } } } 该函数为字符以及字符串显示的核心部分,函数中chr=chr-' ';这句是要得到在字符点阵数据里面的实际地址,因为我们的取模是从空格键开始的,例如asc2_1206[0][12],代表的是空格键的点阵码。在接下来的代码,我们也是按照从上到小,从左到右的取模方式来编写的,先得到最高位,然后判断是写1还是0,画点;接着读第二位,如此循环,直到一个字符的点阵全部取完为止。这其中涉及到列地址和行地址的自增,根据取模方式来理解,就不难了。 最后,我们介绍一下初始化函数,void OLED_Init(void),该函数代码比较长,我们就不列出来了,见上面oled.c代码部分。 该函数的结构比较简单,开始是对IO口的初始化,这里我们也是用了宏定义OLED_MODE来决定要设置的IO口,其他就是一些初始化序列了,我们按照厂家提供的资料来做就可以。最后要说明一点的是,因为OLED是无背光的,在初始化之后,我们把显存都清空了,所以我们在屏幕上是看不到任何内容的,跟完全通电一个样,不要以为这就是初始化失败,要写入数据模块才会显示的。 oled.c的内容就为大家介绍到这里,将oled.c保存,然后加入到HARDWARE组下。接下来我们在oled.h中输入如下代码: #ifndef __OLED_H #define __OLED_H #include \ #include \//OLED模式设置 //0:4线串行模式 //1:并行8080模式 #define OLED_MODE 1 //-----------------OLED端口定义---------------- #define OLED_CS PCout(9) //#define OLED_RST PBout(14)//在MINISTM32上直接接到了STM32的复位脚! #define OLED_RS PCout(8) #define OLED_WR PCout(7) #define OLED_RD PCout(6) //PB0~7,作为数据线 #define DATAOUT(x) GPIOB->ODR=(GPIOB->ODR&0xff00)|(x&0x00FF); //输出 //使用4线串行接口时使用 #define OLED_SCLK PBout(0) #define OLED_SDIN PBout(1) #define OLED_CMD 0 //写命令 #define OLED_DATA 1 //写数据 //OLED控制用函数 void OLED_WR_Byte(u8 dat,u8 cmd); void OLED_Display_On(void); void OLED_Display_Off(void); void OLED_Refresh_Gram(void); void OLED_Init(void); void OLED_Clear(void); void OLED_DrawPoint(u8 x,u8 y,u8 t); void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot); void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size); void OLED_ShowString(u8 x,u8 y,const u8 *p); #endif 该部分比较简单,OLED_MODE的定义也在这个文件里面,我们必须根据自己OLED模块BS0~2的设置(仅支持8080和4线SPI)来确定OLED_MODE的值。 保存好oled.h之后,我们就可以在主程序里面编写我们的应用层代码了,该部分代码如下: int main(void) { u8 t=0; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口初始化 LED_Init(); //初始化与LED连接的硬件接口 OLED_Init(); //初始化液晶 OLED_ShowString(0,0, \OLED_ShowString(0,16,\OLED_ShowString(0,32,\ OLED_ShowString(0,48,\ OLED_ShowString(63,48,\OLED_Refresh_Gram(); t=' '; while(1) { OLED_ShowChar(48,48,t,16,1);//显示ASCII字符 OLED_Refresh_Gram(); t++; (t>'~')t=' '; ED_ShowNum(103,48,t,3,16);//显示ASCII字符的码值 delay_ms(300); LED0=!LED0; } } 该部分代码用于在OLED上显示一些字符,然后从空格键开始不停的循环显示ASCII字符集,并显示该字符的ASCII值。注意在test.c文件里面包含oled.h头文件,同时把oled.c文件加入到HARDWARE组下,然后我们编译此工程,直到编译成功为止。 3.9.4 下载与测试 将代码下载到MiniSTM32后,可以看到DS0不停的闪烁,提示程序已经在运行了。同时可以看到OLED模块显示如下内容: