1. 课程导论与硬件准备

各位同学好,我是你们的嵌入式讲师。今天咱们正式开始这门课——STM32F103 OLED显示驱动与DMA传输驱动开发实战。

第一节课,我不打算直接扔代码。咱们先把手头的家伙事儿认清楚。你想想看,做嵌入式开发,硬件都认不全,后面出了问题你都不知道该怀疑谁。

1.1 STM32F103开发板——我们的主心骨

STM32F103,Cortex-M3内核,72MHz主频。说实话,这颗芯片在2025年的今天已经不算新了。但为什么我还要用它来讲课?

原因很简单:它太经典了。市面上绝大多数工业产品、物联网终端、甚至一些医疗设备,里面跑的还是F103。你学会了它,再去看F4、H7系列,上手会非常快。

我个人习惯用最小系统板,就是那种蓝色或黑色的板子,带一个USB口、一个复位键、引出所有GPIO。为什么?因为便宜、灵活,坏了不心疼。我在项目中遇到过好几次,客户要求改方案,最小系统板拔下来换一块就行,成本才十几块钱。

参数 值 备注
内核 ARM Cortex-M3 32位RISC
主频 72 MHz 实际可超频到96MHz(不推荐)
Flash 64KB ~ 512KB 根据具体型号
SRAM 20KB ~ 64KB 做DMA传输时要注意别溢出
GPIO 最多80个 大部分可复用为其他功能
DMA 7通道 这是我们课程的重点之一
我的建议:如果你手头还没有开发板,买一块STM32F103C8T6最小系统板就行。淘宝上20块钱左右,性价比极高。别买那种带一堆外设的“大板子”,咱们做驱动开发,引脚引出来自己接,反而学得更扎实。

1.2 0.96寸OLED模块(SSD1306)——显示的主角

这块小屏幕,尺寸只有0.96英寸,分辨率128×64。说白了,就是128列、64行像素点。每个点可以独立控制亮灭。

它用的驱动芯片是SSD1306。这颗芯片很有意思——它内部自带GRAM(显存),大小是128×64位,也就是1KB。你往GRAM里写数据,它就自动刷新显示。这意味着什么?意味着MCU只需要告诉它“哪个点亮、哪个灭”,剩下的刷新工作它自己搞定。

我曾经在一个手持设备项目里用过这块屏。当时客户要求低功耗,我算了一下,SSD1306在正常显示时功耗只有20mA左右,休眠模式更是低到微安级。嗯,这个数据在电池供电产品里非常吃香。

参数 值 说明
分辨率 128 × 64 横向128点,纵向64点
驱动芯片 SSD1306 支持I²C和SPI两种接口
显存 1KB(128×64位) MCU只需写GRAM,自动刷新
工作电压 3.3V ~ 5V 模块自带稳压,3.3V供电即可
接口 I²C / SPI 本课程使用SPI接口(速度更快)
功耗 正常20mA,休眠<10μA 适合电池供电
注意:市面上很多0.96寸OLED模块,背面有跳线电阻或焊盘,用来选择I²C还是SPI模式。买回来先检查一下,别焊错了。我曾经有个学生,焊了半天不亮,结果发现是I²C/SPI选择焊盘没接对。

1.3 杜邦线连接与原理图解读

好,硬件都认识了,接下来咱们把它们连起来。

我用的接口方式是SPI。为什么不用I²C?因为SPI速度更快。SSD1306的SPI最高可以跑到10MHz,而I²C通常只有400kHz。你想想看,如果我们要做动画或者快速刷新,SPI的优势就出来了。

连接方式如下:

  • VCC → 3.3V(开发板供电)
  • GND → GND
  • SCL → PA5(SPI1_SCK)
  • SDA → PA7(SPI1_MOSI)
  • RES → PB0(复位引脚,软件控制)
  • DC → PB1(数据/命令选择)
  • CS → PA4(SPI1_NSS,片选)

这里我要特别说一下DC引脚。它决定了你发给SSD1306的是命令还是数据。DC=0,发的是命令;DC=1,发的是数据。这个区分非常重要,后面写驱动的时候你会反复用到。

核心逻辑:SPI负责高速传输数据,DC引脚负责告诉屏幕“你收到的是命令还是像素数据”。两者配合,才能正确驱动OLED。

下面这张图,是我画的本次课程的整体硬件架构。你可以看到数据是怎么从STM32流向OLED的。

STM32F103 + SSD1306 硬件连接与数据流架构图 STM32F103 + SSD1306 硬件连接与数据流架构 STM32F103 Cortex-M3 @72MHz SPI1: PA5(SCK) PA7(MOSI) GPIO: PA4(CS) PB0(RES) PB1(DC) DMA 控制器 7通道,内存→外设 DMA请求 SPI 总线 (10MHz) SCK + MOSI 0.96" OLED SSD1306 驱动 128×64 像素 1KB GRAM CS (PA4) DC (PB1) RES (PB0) 电源: VCC(3.3V) + GND 数据流向 ① CPU配置DMA ② DMA搬运数据→SPI ③ SPI发送→OLED GRAM 控制信号 CS/DC/RES 由GPIO控制

这张图里,你可以看到两条路径:

  • 数据路径:STM32的DMA把显存数据搬到SPI发送寄存器,SPI自动把数据串行发送给OLED的GRAM。
  • 控制路径:CS、DC、RES三个引脚由GPIO控制,告诉OLED“现在发的是命令还是数据”。

为什么要用DMA?说白了,就是解放CPU。如果没有DMA,你要刷新一屏128×64的数据,CPU得一条一条地搬,搬完这一屏,其他事就别干了。有了DMA,你只需要告诉它“从内存地址A搬1024字节到SPI数据寄存器”,然后CPU就可以去干别的事,比如处理按键、跑算法。DMA搬完了,会给你发个中断通知一声。

一个小技巧:连接杜邦线的时候,我建议你把线整理好,用扎带或者胶带固定一下。别小看这个细节——我在调试一个项目时,就是因为杜邦线松动,SPI时钟线接触不良,导致屏幕时不时花屏。查了整整两天才找到原因。从那以后,我所有实验板的线都扎得整整齐齐。

1.4 原理图快速解读

咱们来看一下SSD1306模块的原理图(我这里用文字描述,你可以在网上搜到标准原理图)。

核心芯片是SSD1306,它周围有:

  • VCC和GND:供电引脚,模块上通常有一个3.3V稳压芯片(比如XC6206),所以你可以直接用5V供电,但建议用3.3V。
  • SCL和SDA:SPI模式下的时钟和数据线。
  • RES:复位引脚,低电平有效。上电后需要拉低再拉高,完成复位。
  • DC:数据/命令选择。这个前面说过了。
  • CS:片选,低电平选中。
  • BS0、BS1、BS2:接口模式选择引脚。模块上通常用电阻上拉或下拉,固定为SPI 4线模式。你不需要动它。

嗯,这里要注意:有些模块的RES引脚是直接接在VCC上的,也就是说上电自动复位。但我不建议你依赖这个——最好还是用MCU的GPIO来控制复位,这样你可以随时软件复位屏幕。

避坑指南:我曾经遇到过一块OLED模块,它的CS引脚内部已经拉低了,结果我外部又接了一个GPIO控制CS,导致电平冲突,屏幕死活不亮。后来用万用表一量,才发现CS引脚一直是低电平,根本不受我控制。所以,买模块的时候问清楚,或者自己用万用表测一下默认电平。

1.5 本章小结

好,第一节课的内容就到这里。咱们认识了STM32F103开发板、0.96寸OLED模块(SSD1306),也搞清楚了它们之间怎么连线、数据怎么流动。