就要去北京学习了,在学习之前我们讨论下8963开发板上如何操作OLED显示器,希望对大家有所帮助。
1。显示原理
8963开发板上显示器的连接可以用下图来表示
MCU 8962 <------->显示驱动芯片SSD1329 <------->OLED屏幕
从上图我们可以看出MCU并不是与OLED屏幕直接连接的,它们之间还存在一个芯片SSD1329。那么这块芯片有什么作用呢?从这块芯片的DS(见附件)中我们可以得到对这块芯片作用的解释:128 x 128 OLED Segment/Common Driver with Controller Equips with 16 Gray Scale Levels and 64 Hard Icon Lines。简单说来,它就是一块能够驱动128*128段的 OLED显示器的芯片,MCU只有通过它才能让OLED屏幕工作。一般说来,该驱动IC 和OLED屏幕都是同时出售的,所以用户无需考虑它们之间的连接。在后面的工作中我们要让屏幕显示,实际上主要利用MCU对驱动IC发送命令。
2。深入了解SSD1329
在上面说过,要让屏幕显示,实际上主要利用MCU对驱动IC发送命令。下面我们来看看到底如何对SSD1329这块IC进行操作。首先参看SSD1329 DS的第6页,该页中主要说明该IC的基本特性,我们关心的主要有下面几个参数:
1。Power supply:VDD = 2.4 ~ 3.5V
VCI = 3.2 ~ 4.2V
VDDIO = 1.7V ~ 3.5V (must be smaller than or equal to VDD)
VCC = 9.0V ~ 18.0V
2。8-bit 6800-series Parallel Interface, 8080-series Parallel Interface and Serial Peripheral Interface
3。Embedded 128 x 128 x 4 bit SRAM display buffer
这两个参数主要是硬件上的对该IC的进行说明:接口电压和数据传输接口。电压很好理解,指的就是如何为SSD1329供电。那么,数据传输接口又是什么呢?简言之就是CPU如何与SSD1329连接。根据上面所述,SSD1329包含了对三种数据传输接口的支持: 8-bit 6800并行接口、8-bit 8080并行接口 和 串行接口。对这三种接口操作的方式我们可以从SSD1329 DS的第16、17、18页得到。那么有人会问了,如何确定当前到底是使用哪种方式与MCU连接呢?这个问题的答案同样可以从DS的15页得到。参看Table 7-2。第三,在DS中还提到SSD1329中内置了128*128*4 bit的显示缓冲区,对于这个缓冲区我们可以理解为显存,当我们需要在屏幕上显示的时候,只需要往该显存中相应的位置写入数据即可。那么到底如何向显存中写入数据呢?其实非常简单。对SSD1329的操作总的来说分为“写命令”和“写数据”两类。在执行操作的时候首先执行“写命令”操作用来指明当前要对SSD1329执行什么操作,然后再执行“写数据”操作用来为刚才写入的命令传入参数。
关于具体如何操作SSD1329,我们会在后面结合程序说明。
3。8962MCU与SSD1329的连接
在了解了显示的基本原理以后,我们来看看在这块8962的开发板上是如何操作的。首先让我们看看8962与SSD1329的连接,参考LM3S8962的原理图,从图中我们可以知道它们之间采用的是串行接口连接,除了D0、D1两根数据线外,与8962连接的还有CS片选线,RES复位线和D/C选择线。
4.8962MCU对SSD1329的操作
硬件方面上面已经介绍过了,下面来看看如何编程控制。这部分主要参考8962开发板所带的例子来讲述:
按照上一讲,拿到一个程序以后我们首先找到main函数,在本代码中,main函数被定义在hello.c文件中。
void main(void)
{
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_8MHZ);
RIT128x96x4Init(1000000);
RIT128x96x4StringDraw("Hello World!", 30, 24, 15);
while(1)
{
}
}
这个main函数首先调用函数SysCtlClockSet,该函数的作用在库说明文档中有详细介绍,主要是用来设置8962 MCU所使用的时钟源与采用的时钟频率。
第二条语句为RIT128x96x4Init(1000000);该函数为一个自定义函数,从字面可以理解为初始化OLED。
第三条语句为RIT128x96x4StringDraw("Hello World!", 30, 24, 15);该函数也是一个自己定义的函数,从字面可以看出该函数是用来在指定的位置上写一个字符串的。
最后,整个main函数以一个空循环结束。通过上面分析看出,整个程序的关键在于两个自定义的函数,下面我们来仔细分析这两个函数:
1。RIT128x96x4Init(1000000);
该函数被定义在rit128x96x4.c文件中,该函数带有一个参数ulFrequency,用来表示串行接口传输数据的速率。整个函数的执行遵守以下流程:
打开外围接口 ---》初始化接口 ----》调用RIT128x96x4Enable函数使能8962的SSI接口 ---》调用RIT128x96x4Clear函数清除屏幕 ---》调用RITWriteCommand函数写入初始化命令字。
下面我们一步一步分析该函数:
首先,打开和初始化外围GPIO接口。在这部分中,主要是调用库函数对GPIO引脚进行定义,需要注意的是在本例子中我们使用了SSI串行接口,所以要把GPIOA 2,3,5 作为SSI方式来使用,故而调用GPIOPinTypeSSI函数进行初始化。
其次,调用RIT128x96x4Enable函数使能8962的SSI接口,RIT128x96x4Enable函数同样定义在rit128x96x4.c中。在该函数中,首先调用SSIDisable函数禁止SSI接口,随后配置SSI接口(包括时钟、模式、主从等等)。最后再调用SSIEnable函数打开SSI接口,此时我们刚才的配置就可以生效了。在端口打开后有可能SSI缓冲区内还有上次残留的数据,所以需要调用SSIDataGetNonBlocking读取缓冲区中残留的无效的数据,最后函数设置好标记为g_bSSIEnabled = true表示目前SSI接口已经可以使用了。
在上面我们使用到了SSI(SPI)接口,该接口使用SPI协议进行数据传输。关于该接口与该协议的具体内容可以在百度上查询,在此不再详述。
第三,调用RIT128x96x4Clear,该函数用来清空屏幕的显示缓冲区(即前面说的显存)中的内容,这是为了避免上一次残留的数据对本次显示造成影响。下面来看看
RIT128x96x4Clear函数中都做了些什么。
void RIT128x96x4Clear(void)
{
static const unsigned char pucCommand1[] = { 0x15, 0, 63 };
static const unsigned char pucCommand2[] = { 0x75, 0, 127 }; //定义两个字符数组
unsigned long ulRow, ulColumn;
*(unsigned long *)&g_pucBuffer[0] = 0;
*(unsigned long *)&g_pucBuffer[4] = 0; //把g_pucBuffer数组中的元素清0
RITWriteCommand(pucCommand1, sizeof(pucCommand1));
RITWriteCommand(pucCommand2, sizeof(pucCommand2));
RITWriteCommand(g_pucRIT128x96x4HorizontalInc,
sizeof(g_pucRIT128x96x4HorizontalInc)); //调用写命令函数向SSD1329中写入命令
for(ulRow = 0; ulRow < 96; ulRow++)
{
for(ulColumn = 0; ulColumn < 128; ulColumn += 8 * 2)
{
RITWriteData(g_pucBuffer, sizeof(g_pucBuffer));
}
} //调用写数据函数向SSD1329中写入数据
}
通过程序后面的注释可以看到RIT128x96x4Clear函数主要是调用写命令和写数据函数对SSD1329进行操作。写命令写入了pucCommand1,pucCommand2两个数据,其中的数据分别为{ 0x15, 0, 63 } 和{ 0x75, 0, 127 }。那么为什么是这两组数据呢?它们有什么含义?要解决这两个问题我们需要参考SSD1329的DS 27页,0x15表示写入命令,通过DS 27可以看到该命令的作用是设置列地址(Set Column Address),紧接着该命令的两个数据表示列的起始地址和结束地址,0表示起始地址,63表示结束地址,共64个。 0x75的意义同理可得,请大家自己分析。g_pucRIT128x96x4HorizontalInc也是一个字符数组的定义,具体值可以在rit128x96x4.c中找到。同样,程序中也是用了写命令操作向SSD1329写入命令,同样,对该命令的意义也可以在DS 28页中找到。最后,循环96*8次,往SSD1392中写入数据(实际上就是往SSD1392的显存中写入数据)。
在RIT128x96x4Clear函数调用结束后,RIT128x96x4Init函数将会循环写入g_pucRIT128x96x4Init数组所定义的各个数据,这些数据将会对SSD1392进行初始化(一般来说该初始
化的命令以及执行流程屏幕的生产厂商会给出,用户无需担心),至于g_pucRIT128x96x4Init数组中为什么定义那些数据,和上面一样,大家可以参考SSD1329 DS,原理基本和上面所说的是一致的!
初始化完成后,main函数将调用RIT128x96x4StringDraw函数显示一串字符串,RIT128x96x4StringDraw函数的执行流程如下所示:
定为字符串显示的位置(通过写入0x15,0X75命令) ----》 根据待显示的字符查询字体数组,获取字体的字模 ----》调用写数据命令写入字模
到此,往OLED屏幕上将显示一串字符串Hello World!
hello显示实例.rar
(152.98 KB, 下载次数: 346)
SSD1329.pdf
(1.2 MB, 下载次数: 443)
[
本帖最后由 youki12345 于 2010-8-15 09:39 编辑 ]