7、OLED实验、8080、SPI

来源:互联网 发布:网络神话txt下载 编辑:程序博客网 时间:2024/06/06 17:23

1、学习 SSD1306 型OLED的使用,区别8088与080 接口以及 4 线 SPI接口的写数据与命令的区别。

2、8080 并行接口的发明者是 INTEL,该总线也被广泛应用于各类液晶显示器,ALIENTEK OLED 模块也提供了这种接口,使得 MCU 可以快速的访问 OLED。ALIENTEK

 OLED 模块的 8080 接口方式需要如下一些信号线:

CS:OLED 片选信号。

WR:向 OLED 写入数据。

RD:从 OLED 读取数据。

D[7:0]:8 位双向数据线。

RST(RES):硬复位 OLED。

DC:命令/数据标志(0,读写命令;1,读写数据)。

模块的 8080 并口读/写的过程为:先根据要写入/读取的数据的类型,设置 DC 为高(数据)/低(命令),然后拉低片选,选中 SSD1306,接着我们根据是读数据,还是要写

数据置 RD/WR

为低,然后:

在 RD 的上升沿,  使数据锁存到数据线(D[7:0])上; 

在 WR 的上升沿,使数据写入到 SSD1306 里面;

SSD1306 的 8080 并口写时序图如图:


实现代码为:

//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
DATAOUT(dat);    
  OLED_RS=cmd;
OLED_CS=0;   
OLED_WR=0;  
OLED_WR=1;
OLED_CS=1;  
OLED_RS=1;  
}      

SPI 模式:

SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入)、SDO(数据输出)、SCLK(时钟)、CS(片选)。

(1)SDO – 主设备数据输出,从设备数据输入;

(2)SDI – 主设备数据输入,从设备数据输出;

(3)SCLK – 时钟信号,由主设备产生;

(4)CS – 从设备使能信号,由主设备控制。

其中,CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许在同一总线上连接多个SPI设备成为可能。

其数据写入方式:


实现代码:基本思路是在8个时钟周期内,将数据的最高位与0x80进行比较,如果为真,寄存器将记录下数值。

//向SSD1306写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
u8 i;  
OLED_RS=cmd; //写命令 
OLED_CS=0;  
for(i=0;i<8;i++)
{  
OLED_SCLK=0;
if(dat&0x80)OLED_SDIN=1;
else OLED_SDIN=0;
OLED_SCLK=1;
dat<<=1;   //将数据进行左移动,方便之后的数值采集(移动到最高位)
}  
OLED_CS=1;  
OLED_RS=1;    

3、字符集点阵的制作,可以参考以下链接:

http://blog.csdn.net/exbob/article/details/6532772

http://wenku.baidu.com/link?url=F6tJTZcH6AYxGOaX_-YqFx0-OsPmUd7zxPTZRGiVK0AwHxrtAvX0I11dDP6zMKOqDlAjC2GxnmdKx6i7v-lBf94kvA0H2mXrsQQCidYT-JS

同时我们可以用以下的代码实现字符点阵的显示,思路就是首先判断字体一个字符对应点阵集所需要占的字节数,然后在确定所要显示的字符与空格符的相差数值,因为我们所

编写的字符点阵是从空格符开始,两者相减得到的数值就是该字符在字符点阵中的行数。一个字节又有8个位,我们在每一个字节数中都对每一位进行一次判断,(通过数据

的左移,最高位与0x80进行与运算)。

//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示  
//size:选择字体 16/12 
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
{          
u8 temp,t,t1;
u8 y0=y;
u8 csize=(size/8+((size%8)?1:0))*(size/2);//得到字体一个字符对应点阵集所占的字节数
chr=chr-' ';//得到偏移后的值 
    for(t=0;t<csize;t++)
    {   
if(size==12)temp=asc2_1206[chr][t]; //调用1206字体
else if(size==16)temp=asc2_1608[chr][t];//调用1608字体
else if(size==24)temp=asc2_2412[chr][t];//调用2412字体
else return; //没有的字库
        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;
}
}    
    }          
}


0 0
原创粉丝点击