在裸板下使用 SPI 的话,有两种方法可选:

  1. 使用 IO 口模拟 SPI 进行操作
  2. 使用 SPI 控制器进行操作

这里我们选用控制器的方式,简单方便。

初始化 SPI

static void SPIControllerInit(void)
{
/* 设置频率 */
SPPRE0 = 2;
SPPRE1 = 2; /* 配置 SPI */
SPCON0 = (1<<4) | (1<<3);
SPCON1 = (1<<4) | (1<<3);
}



如手册所示,频率配置公式如下:

Baud rate = PCLK / 2 / (Prescaler value + 1)

PCLK = 50MHZ

设置 SPPREn = 2,符合 OLED 的频率要求。



配置 SPCONn 寄存器如下:

   /* [6:5] : 00, polling mode
* [4] : 1 = enable
* [3] : 1 = master
* [2] : 0 = active high
* [1] : 0 = format A
* [0] : 0 = normal mode
*/

SPI 的发送与接收

/* 发送一字节 */
void SPISendByte(unsigned char val)
{
/* 等待发送或接收 ready */
while (!(SPSTA1 & 1));
SPTDAT1 = val;
} /* 接收一字节 */
unsigned char SPIRecvByte(void)
{
SPTDAT1 = 0xff; /* 等待发送或接收 ready */
while (!(SPSTA1 & 1));
return SPRDAT1;
}

OLED 初始化

我们选用的是 SSD1306 这款 OLED,根据手册说明,它有 4 种操作接口可以选择,如图所示:

Different MCU mode can be set by hardware selection on BS[2:0] pins.

可以通过 BS[2:0] 来选择模式,如下图所示:

参照如下流程图写出 OLED 的初始化程序:

void OLEDInit(void)
{
/* 向 OLED 发命令以初始化 */
OLEDWriteCmd(0xAE); /*display off*/
OLEDWriteCmd(0x00); /*set lower column address*/
OLEDWriteCmd(0x10); /*set higher column address*/
OLEDWriteCmd(0x40); /*set display start line*/
OLEDWriteCmd(0xB0); /*set page address*/
OLEDWriteCmd(0x81); /*contract control*/
OLEDWriteCmd(0x66); /*128*/
OLEDWriteCmd(0xA1); /*set segment remap*/
OLEDWriteCmd(0xA6); /*normal / reverse*/
OLEDWriteCmd(0xA8); /*multiplex ratio*/
OLEDWriteCmd(0x3F); /*duty = 1/64*/
OLEDWriteCmd(0xC8); /*Com scan direction*/
OLEDWriteCmd(0xD3); /*set display offset*/
OLEDWriteCmd(0x00);
OLEDWriteCmd(0xD5); /*set osc division*/
OLEDWriteCmd(0x80);
OLEDWriteCmd(0xD9); /*set pre-charge period*/
OLEDWriteCmd(0x1f);
OLEDWriteCmd(0xDA); /*set COM pins*/
OLEDWriteCmd(0x12);
OLEDWriteCmd(0xdb); /*set vcomh*/
OLEDWriteCmd(0x30);
OLEDWriteCmd(0x8d); /*set charge pump enable*/
OLEDWriteCmd(0x14); OLEDSetPageAddrMode(); OLEDClear(); OLEDWriteCmd(0xAF); /*display ON*/
}

设置为页显示模式:

static void OLEDSetPageAddrMode(void)
{
OLEDWriteCmd(0x20);
OLEDWriteCmd(0x02);
}

OLED 的分辨率为 128 x 64,每 8 行为一页,我们选用 8 x 16 的字模进行显示。

显示一个字符

void OLEDPutChar(int page, int col, char c)
{
int i = 0; /* 得到字模 */
const unsigned char *dots = oled_asc2_8x16[c - ' ']; /* 发给 OLED */
OLEDSetPos(page, col); /* 发出 8 字节数据 */
for (i = 0; i < 8; i++)
OLEDWriteDat(dots[i]); OLEDSetPos(page+1, col); /* 发出 8 字节数据 */
for (i = 0; i < 8; i++)
OLEDWriteDat(dots[i+8]); }

页模式下定位方法:



即:

static void OLEDSetPos(int page, int col)
{
OLEDWriteCmd(0xB0 + page); /* page address */
OLEDWriteCmd(col & 0xf); /* Lower Column Start Address */
OLEDWriteCmd(0x10 + (col >> 4)); /* Lower Higher Start Address */
}

下篇将写出在 Linux 下操作 OLED 的驱动及应用程序。

Mini2440 通过 SPI 操作 OLED (裸板下使用 SPI 控制器)的更多相关文章

  1. 今天学习的裸板驱动之存储控制器心得(初始化SDRAM)

    CPU只管操作地址,而有些地址代表的是某些存储设备. 但是操作这些存储设备需要很多东西,比如需要制定bank,行/列地址等.所以就有了存储管理器,用来处理这种CPU操作的地址和存储设备间的转换. (1 ...

  2. uboot-tiny4412启动流程(下)----如何将自己的裸板测试程序加入uboot中启动测试

    今天在工作上搞了一天高通的芯片uboot程序,目的是希望将一个裸板的程序移植到uboot中,并且开机让它运行.这个芯片是NXP4330,目前是高通的一个芯片,基于ARM-contexA9架构,那么就跟 ...

  3. 嵌入式 hi3518c裸板uboot烧写、kernel烧写、fs烧写小结

    1.在uboot中我可以添加自己的命令,添加的方法是找到一个uboot的命令,然后模仿着去增加属于自己的命令代码以及实现函数就可以 2.记住在使用printf进行调试的时候,在遇到指针或者字符串的时候 ...

  4. S5PV210裸板驱动:启动

    以往2440和6410的启动方式,只要我们把裸板代码烧写到NAND FLASH的开始位置,当开发板上点启动时,处理器会自动从NAND FLASH上拷贝前面一段的代码到内部的RAM中执行.按照以前的方法 ...

  5. 裸板驱动总结(makefile+lds链接脚本+裸板调试)

    在裸板2440中,当我们使用nand启动时,2440会自动将前4k字节复制到内部sram中,如下图所示: 然而此时的SDRAM.nandflash的控制时序等都还没初始化,所以我们就只能使用前0~40 ...

  6. 【嵌入式开发】 嵌入式开发工具简介 (裸板调试示例 | 交叉工具链 | Makefile | 链接器脚本 | eclipse JLink 调试环境)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42239705  参考博客 : [嵌入式开发]嵌入式 开发环境 (远 ...

  7. arm裸板驱动总结(makefile+lds链接脚本+裸板调试)

    在裸板2440中,当我们使用nand启动时,2440会自动将前4k字节复制到内部sram中,如下图所示: 然而此时的SDRAM.nandflash的控制时序等都还没初始化,所以我们就只能使用前0~40 ...

  8. 裸板中中断异常处理,linux中断异常处理 ,linux系统中断处理的API,中断处理函数的要求,内核中登记底半部的方式

    1.linux系统中的中断处理  1.0裸板中中断异常是如何处理的?     以s5p6818+按键为例          1)按键中断的触发        中断源级配置            管脚功 ...

  9. NUC980 运行 RT-Thread 驱动 SPI 接口 OLED 播放 badapple

    badapple 是什么,上网随便查了下,没看出个究竟,不过有个关于这个挺火的标签或者主题 < 有屏幕的地方就有 badapple >,网上有很多人用很多方式播放 badapple 动画, ...

随机推荐

  1. PDF 转 PNG JPG 操作

    # gs   gs -dSAFER -dBATCH -dNOPAUSE -r300 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pnggray - ...

  2. Android 软件退出系统方法重写

    Android 软件退出系统按键方法重写 //针对Andriod软件退出系统按键方法重写 ;//key down time @Override public boolean onKeyDown(int ...

  3. P3379 【模板】最近公共祖先(LCA)(树链剖分)版

    #include <bits/stdc++.h> #define read read() #define up(i,l,r) for(register int i = (l);i < ...

  4. sock5协议转换http协议工具polipo使用笔记(Centos7)

    一.安装 Shadowsocks使用socks5协议,而终端很多工具目前只支持http和https等协议,所以我们为终端设置Shadowsocks的思路就是将socks5协议转换成http协议,然后为 ...

  5. 不修改模板的前提下修改VisualState中的某些值

    原文链接:不修改模板的前提下修改VisualState中的某些值 - 超威蓝火 UWP里有一件非常令人不爽的事,大部分控件只提供了Normal状态下的Background,Foreground,Bor ...

  6. SpringBean作用域

    1.Bean作用域 spring中为bean定义了5种作用域,分别为singleton(单例).prototype(原型).request.session和global session.默认情况下为s ...

  7. GC垃圾回收机制,iOS内存管理。

    问题: MRC中通过调用静态方法创建的新对象,不再使用时需要对其发送release消息吗? 不需要,因为约定静态方法创建的对象会自动将其放入自动释放池,即已对其发送autorelease消息,因此不可 ...

  8. Javascript高级编程学习笔记(10)—— 作用域、作用域链

    昨天介绍了,JS中函数的作用域 什么词法环境之类的,可能很多小伙伴不太明白. 在今天的内容开始之前,先做个简短的声明: 词法环境这一概念是在ES5中提出的,因为词法环境主要用于保存let.const声 ...

  9. jQuery的JS库在本地运行项目时提示无法加载

    最近公司有个项目在我本地运行时引用本地的jquery.js,浏览器提示无法加载 <script src="/js/newperson/jquery-1.11.3.min.js" ...

  10. Java 实现网络图片的读取与下载

    //网络图片的下载,读取与删除 public static void fileDowAndDel(String httpurl){ try { URL url = new URL(httpurl); ...