目录
第13章 Cortex-M4-SPI总线
13.1 SPI总线概述
13.1.1 SPI总线介绍
SPI(Serial Peripheral interface):是由Motorola公司开发的串行外围设备接口,是一种高速的,全双工,同步的通信总线。主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器等器件。
UART:异步串行全双工
SPI:同步串行全双工
13.1.2 SPI总线接口与物理拓扑结构
(1)五线制接口(4线SPI)—4-wire-spi
MOSI(单向数据线)、MISO(单向数据线)、CLK(时钟线)、NSS/CS(片选)
(2)四线制接口(3线SPI)
SDA(双向数据线)、CLK(时钟线)、NSS/CS(片选)
(3) 拓扑图
在SPI总线上,有主机(MCU)和从机(外围器件)之分,主机只有一个,从机可以有多个。
主机通过从机的片选信号线来选中从机与其进行通信。同一时间只能选择其中一个从机。随着SPI总线上挂接的从机增多,主机的片选IO也响应会增多。
M:master O:output S:slaver I:Input
MOSI(单向数据线):主出从入,主机通过这跟数据线发送数据给从机。
MISO(单向数据线):主入从出,从机通过这跟数据线发送数据给主机。
SCK(单向):时钟线,控制数据线什么时候才能传输数据。只有主机才能控制时钟线。
只有主机才能主动寻求从机与其通信,从机永远不可能主动跟主机通信。
CS:片选信号线,主机通过片选信号线来选中从机与其通信。
13.1.3 SPI总线通信原理
主机片选从机
主机通过时钟线决定什么时候发送数据给从机
主机通过时钟线决定什么时候接受从机的数据
主机取消片选
补充:
平行线:数据不允许发生改变,必须稳定发送
交叉线:数据允许发生改变,但不一定要变
13.1.4 SPI总线数据格式
SPI数据格式有4种:MODE0~3
决定数据格式的因素:时钟线哪一种跳边沿发送数据,前沿还是后沿接受数据,总线的空闲电平状态
CPHA:时钟相位。当CPHA=0,在第一个跳变沿(前沿)采集数据;当CPHA=1,在第二个跳边沿(后沿)采集数据。CPHA决定是前沿还是后沿采集数据和输出数据。
CPOL:时钟极性。当CPOL=0,总线空闲电平为低电平;当CPOL=1,总线的空闲电平为高电平。间接决定了哪一种跳边沿采集数据和发送数据。
如果一个设备支持MODE0,同时也会支持MODE3 (CPHA为0)
如果一个设备支持MODE1,同时也会支持MODE2
MODE0:
下降沿发送数据,上升沿采集数据
当SCK产生下降沿时,主机在MOSI上发送数据,同时从机在MISO上发送数据
等数据稳定在数据线上
当SCK产生上升沿时,主机在MISO上采集数据,同时从机在MOSI上采集数据
主机发送一位数据给从机:
SCK=0;//主机准备数据
MOSI=0/1;
SCK=1;//从机采集数据
主机接收一位数据给从机:
SCK=0;//从机准备数据
SCK=1;//主机采集数据.
读取MISO
主机和从机通信起始就是数据交换:
主机发送一个字节数据给从机//void SPI_Send_Byte(uint8_t data) //data = 1100 0000//{// uint8_t i;// for(i=0;i<8;i++)// {// SPI_SCK_L;//主机准备数据// if(data&0x80) // 1100 0000 & 1000 0000 // ((A=0)&&(B=1))// SPI_MOSI_H;// else// SPI_MOSI_L; // // data<<=1;//让次高位变成最高位 // data=data<<1;// // SPI_SCK_H;//从机采集数据// }//} 主机读取一个字节数据//uint8_t SPI_Revice_Byte(void)//{// uint8_t i;// uint8_t data=0; // for(i=0;i<8;i++)// {// SPI_SCK_L;//从机准备数据 // SPI_SCK_H;//主机采集数据// data <<=1;//空出最低位保存读取的数据// if(SPI_MISO)// data |=1;// }// // return data;//} //函数功能:SPI主机从机传输数据//参数说明:主机待发送的数据//返回值:主机接到到的数据uint8_t SPI_Exchange_Byte(uint8_t data){ uint8_t i; for(i=0;i<8;i++) { SPI_SCK_L;//主机准备数据/从机准备数据 if(data&0x80)SPI_MOSI_H; else SPI_MOSI_L; data<<=1;//让次高位变成最高位/空出最低位保存读取的数据 SPI_SCK_H;//从机采集数据/主机采集数据 if(SPI_MISO) data |=1; } return data;}只写:SPI_Exchange_Byte(data);只读:data=SPI_Exchange_Byte(0xFF);//发什么不重要
13.2 IO口模拟SPI操作OLED
OLED_CS(CS)—PB7----MCU发出----普通功能推挽输出
OLED_SCLK(SCK)—PB13–MCU发出----普通功能推挽输出
OLED_DIN(MOSI)—PB15—MCU发出----普通功能推挽输出
MISO–这里不需要
13.2.1 常见的显示设备
LED、数码管、点阵、LCD屏、OLED屏(消费电子)
13.2.2 OLED显示屏概述
OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。因为具备轻薄、省电等特性,因此从2003 年开始,这种显示设备在 MP3 播放器上得到了广泛应用,而对于同属数码类产品的 DC与手机,此前只是在一些展会上展示过采用 OLED 屏幕的工程样品。自 2007 年后,寿命得到很大提高,具备了许多 LCD 不可比拟的优势。
补充:
像素点:构成是一幅完整画面的最小单元
分辨率:一幅完整画面横向像素点的个数乘以纵向像素点的个数
帧:一幅完整画面就为一帧。
色深:表示一个像素点颜色数据的位数。16bpp,24bpp,32bpp
13.2.3 OLED特征
分辨率:128*64
尺寸:1.3寸
13.2.4 显示原理
主要目的:让OLED显示东西
显示内容从哪里来?MCU
MCU如何发显示数据给OLED?
\1. 相关管脚接线
\2. 遵循一定的通信协议—SPI
一般要让显示设备显示出内容,都需要显示屏的驱动芯片。
在STM32上,一般都是没有集成显示屏驱动芯片,那么显示模块本身就要具备自己的驱动芯片
13.2.5 管脚介绍
通信模式选择
OLED_CS:片选管脚,低电平有效
OLED_RES:复位管脚,低电平有效
OLED_D/C:数据命令选择管脚。当OLED_D/C=0,输入的数据是作为命令;当OLED_D/C=1,输入的数 据是作为显示数据
OLED_SDIN:串行数据输入管脚
OLED_SCLK:串行时钟线
OLED_CS、OLED_RES、OLED_D/C是控制管脚
OLED_SDIN、OLED_SCLK是数据管脚
13.2.6 OLED驱动
13.2.6.1 驱动时序
跟SPI的MODE0/3一样
13.2.7 操作指令
13.2.7.1 设置列地址(Y坐标)
设定列地址为column(A7~A0)
高4位列地址命令:0001A7A6A5A4—00010000| A7A6A5A4—0x10 | (column&0xf0)>>4
低4位列地址命令:0000A3A2A1A0—00000000|A3A2A1A0—0x00 | (column&0x0f)
OLED_DC=0;//发送命令
SPI_Exchange_Byte(0x10 | (column&0xf0)>>4);//发送高4位列地址(A7~A4)
SPI_Exchange_Byte(0x00 | (column&0x0f) );//发送低4位列地址(A3~A0)
13.2.7.2 页地址
OLED屏一共有64行,将这64行平均分成8份,每一份有8行,每一份就为一页
设定页地址是设定在本页的首行开始显示,而不能设定在本页的任意行开始显示
设定页地址为page(A3~A0)
页地址命令:1011A3A2A1A0—10110000 | A3A2A1A0—0xB0|page
OLED_DC=0;//发送命令
SPI_Exchange_Byte(0xB0|page);//设定页地址
13.2.8 OLED初始化
在前面知道OLED的管脚功能,也知道了MCU跟OLED是采用SPI通信。就算对OLED所有的管脚进行了初始化,并且完成SPI协议,但是仍然不能让OLED正常工作起来。我们还需要对OLED进行真正的初始化,就是对显示控制器(驱动芯片)进行初始化工作。
这个初始化官方已经提供了初始化序列给我们,直接调用就行 。
OELD_RES=1; delay_ms(100); OELD_RES=0; delay_ms(100); OELD_RES=1; delay_ms(100); Oled_Write_Cmd(0xAE); //关闭显示 Oled_Write_Cmd(0xD5); //设置时钟分频因子,震荡频率 Oled_Write_Cmd(80); //[3:0],分频因子;[7:4],震荡频率 Oled_Write_Cmd(0xA8); //设置驱动路数 Oled_Write_Cmd(0X3F); //默认0X3F(1/64) Oled_Write_Cmd(0xD3); //设置显示偏移 Oled_Write_Cmd(0X00); //默认为0 Oled_Write_Cmd(0x40); //设置显示开始行 [5:0],行数. Oled_Write_Cmd(0x8D); //电荷泵设置 Oled_Write_Cmd(0x14); //bit2,开启/关闭 Oled_Write_Cmd(0x20); //设置内存地址模式 Oled_Write_Cmd(0x02); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; Oled_Write_Cmd(0xA1); //段重定义设置,bit0:0,0->0;1,0->127; Oled_Write_Cmd(0xC8); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 Oled_Write_Cmd(0xDA); //设置COM硬件引脚配置 Oled_Write_Cmd(0x12); //[5:4]配置 Oled_Write_Cmd(0x81); //对比度设置 Oled_Write_Cmd(0xEF); //1~255;默认0X7F (亮度设置,越大越亮) Oled_Write_Cmd(0xD9); //设置预充电周期 Oled_Write_Cmd(0xf1); //[3:0],PHASE 1;[7:4],PHASE 2; Oled_Write_Cmd(0xDB); //设置VCOMH 电压倍率 Oled_Write_Cmd(0x30); //[6:4] 000,0.65vcc;001,0.77vcc;011,0.83*vcc; Oled_Write_Cmd(0xA4); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) Oled_Write_Cmd(0xA6); //设置显示方式;bit0:1,反相显示;0,正常显示 Oled_Write_Cmd(0xAF); //开启显示
当我调用OLED初始化函数后,OLED屏就有东西显示出来。但是我在本代码里并没有发送任何显示数据。这是因为我OLED显示控制器的显存里面已经存在着显示数据,我初始化成功了就能从显存把显示数据显示在OLED屏上。
但是正常情况并不希望在初始化OLED完成有任何东西显示出来。所以在OLED初始化完成后要有一个清屏动作。
如何清屏?–其实就是发送显示数据。
13.3 OLED显示方式说明
每发送完一个显示数据,列地址会自动加1.
13.4 显示代码的编程流程
得到显示数据
设定页地址
设定列地址
发送显示数据
13.5 显示文字
13.5.1 程序设计流程
得到带显示文字的点阵编码
设定页地址
设定列地址
发送显示数据
13.5.2 取模方法
13.6 显示图片
13.6.1 程序设计流程
13.6.2 取模方法
13.7 STM32的SPI控制器操作OLED
13.7.1 STM32的SPI总线介绍
串行外设接口(SPI)允许芯片与外部设备以半/全双工、同步、串行方式通信。此接口可以被配置成主模式,并为外部从设备提供通信时钟(SCK)。接口还能以多主配置方式工作。
它可用于多种用途,包括使用一条双向数据线的双线单工同步传输,还可使用CRC校验的可靠通信。
13.7.1.1 SPI控制器特征
● 3线全双工同步传输
● 带或不带第三根双向数据线的双线单工同步传输
● 8或16位传输帧格式选择
● 主或从操作(做为主设备还是从设备)
● 支持多主模式
● 8个主模式波特率预分频系数(最大为fPCLK/2)–设定SPI数据传输速度
● 从模式频率 (最大为fPCLK/2)
● 主模式和从模式的快速通信
● 主模式和从模式下均可以由软件或硬件进行NSS管理:主/从操作模式的动态改变
● 可编程的时钟极性和相位(决定MODE0~3)
● 可编程的数据顺序, MSB在前或LSB在前
● 可触发中断的专用发送和接收标志
● SPI总线忙状态标志
● 支持可靠通信的硬件CRC
─ 在发送模式下, CRC值可以被作为最后一个字节发送
─ 在全双工模式中对接收到的最后一个字节自动进行CRC校验
● 可触发中断的主模式故障、过载以及CRC错误标志
● 支持DMA功能的1字节发送和接收缓冲器:产生发送和接受请求
13.7.2 STM32的SPI控制器框架(重点)
要通过SPI控制器发送数据,就是要把数据写入到数据寄存器(DR)里,然后数据寄存器(DR)里的数据就会被送到移位寄存器里,然后再移位寄存器中的数据就会按照设定的帧格式(高位先出/低位先出)一位一位地通过MOSI发送出去,同时也会通过MISO一位一位地接收到新的数据。当移位寄存器把待发送的数据全部发送出去后,也就会接受一个完整的新数据,移位寄存器就会把这个新数据送到接收缓冲区里。然后通过读取数据寄存器(DR)就能得到该数据。
上述数据传输过程受到主控制电路的控制。
13.7.3 STM32的SPI相关寄存器
13.7.4 SPI控制器使用
速度限制:
[外链图片转存中…(img-bwDJFQxy-1700124605457)]
要通过SPI控制器发送数据,就是要把数据写入到数据寄存器(DR)里,然后数据寄存器(DR)里的数据就会被送到移位寄存器里,然后再移位寄存器中的数据就会按照设定的帧格式(高位先出/低位先出)一位一位地通过MOSI发送出去,同时也会通过MISO一位一位地接收到新的数据。当移位寄存器把待发送的数据全部发送出去后,也就会接受一个完整的新数据,移位寄存器就会把这个新数据送到接收缓冲区里。然后通过读取数据寄存器(DR)就能得到该数据。
上述数据传输过程受到主控制电路的控制。
13.7.3 STM32的SPI相关寄存器
[外链图片转存中…(img-dJL9Kwwf-1700124605457)]
13.7.4 SPI控制器使用
[外链图片转存中…(img-jod05jCk-1700124605463)]
速度限制:
[外链图片转存中…(img-IzVxDiRY-1700124605463)]文章来源:https://www.toymoban.com/news/detail-808554.html
文章来源地址https://www.toymoban.com/news/detail-808554.html
到了这里,关于STM32_SPI总线驱动OLED详细原理讲解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!