oled stm32的spi
其实各种协议是很重要的,这篇文章就当做我对spi协议的一个整理吧。
必要的spi简介:
https://www.cnblogs.com/zengsf/p/7221207.html?utm_source=itdadao&utm_medium=referral

前几天在网上看到一段关于oled的程序
不过那段程序是用的io口模拟spi来控制oled模块的
我在想stm32本身就有spi为何要用io口来模拟spi协议呢
所以就想自己试着写一写。
首先第一部分是关于stm32的spi引脚:
http://www.eeworld.com.cn/mcu/2015/0615/article_20333.html
SPI1->CS ------ PA4
SPI1->MISO ------ PA6
SPI2->CS ------ PB12
SPI2->CLK ------ PB13
SPI2->MISO ------ PB14
SPI2->MOSI ------ PB15
SPI3->CS ------ PA15
SPI3->CLK ------ PB3
SPI3->MISO ------ PB4
SPI3->MOSI ------ PB5
对于SPI ,需要打开相关RCC时钟
主模式下
CLK 配置成复用推挽输出
MOSI 配置成复用推挽输出
MISO 配置成富哦那个或带上拉输入
CS若采用硬件则配置成推挽输出,若采用软件模式,则采用普通IO推挽输出即可。
引脚配置好了,我们下面进行spi模式的配置。下面的图片仅供参考,具体问题还需具体分析。spi的极性和相位为4中,我们还需要根据实际情况去查看。

配置好了之后,我们就开始写应用了,也就是收发函数,收发函数把数据通过配置好的底层发出去。
对于应用函数,我们应该设置好形参,形参主要是用来保存协议来往的数据的。
这个协议的收发函数有两种(因为这个协议是双工的):读写分开的函数,读写一起的。
读写分开的函数:
void SPI_Ecah_Buffer_Send(u8* pBuffer, u16 NumByteToRead) //发送
{
for(int i = 0; i < NumByteToRead; i++)
{
SPI_Conmunication_SendByte(*pBuffer);
pBuffer++;
}
}
void SPI_Buffer_Receive(u8* pBuffer, u16 NumByteToRead) //接收
{
while (NumByteToRead--)
{
*pBuffer = SPI_Conmunication_SendByte (Dummy_Byte);
pBuffer++;
}
}
void SPI_Ecah_Buffer_Send(u8* str , u8* pBuffer, u16 NumByteToRead)
{
for(int i = 0; i < NumByteToRead; i++)
{
*str = SPI_Conmunication_SendByte(*pBuffer);
pBuffer++;
str++;
}
}
OLED引脚介绍: 这个是oled模块上的几个引脚。我们要把它和spi对应起来。
CS:OLED片选信号
RST:OLED复位端口
DC: 命令/数据选择端口(0:读写命令, 1: 读写数据)
SCLK(D0):串口时钟线
SDIN(D1): 串口数据线
CS————GPIOD3; spi的片选
RST————GPIOD4; 复位(spi里没有)
DC—————GPIOD5; 表示写数据还是命令。(spi里没有)
D0——————GPIOD6; spi时钟线
D1——————GPIOD7; spi MOSI,代表oled从这里接收数据,假设单片机是主机,oled屏是从机。
* Mode :O:写命令 1:写数据
* data :数据/命令
*
*/
void SPI_Write(char data, int Mode)
{
int i = 0;
if(Mode) //这个是用来区分命令,还是数据的。
{
OLED_DC(1); //DC引脚输入高,表示写数据
}
else
{
OLED_DC(0); //DC引脚输入低,表示写命令
}
OLED_CS(0); //CS引脚输入低,片选使能 这里符合spi协议,低电平是选中。
for(i = 0; i < 8; i++) //从这句话,我们能判断出,这个spi协议是,8位的, spi分为8帧和16帧
{
OLED_D0(0); //D0引脚输入低
if(data & 0x80) //判断传输的数据最高位为1还是0 从这里判断是先传输高位, spi协议有先传高位或先传低位。
{
OLED_D1(1); //D1引脚输入高
}
else
{
OLED_D1(0); //D1引脚输入低
}
OLED_D0(1); //D1引脚输入高 //先准备好数据,然后在让时钟有一个上升沿,也就是上升沿的时候读取数据。
data <<= 1; //将数据左移一位
}
OLED_DC(0); //DC引脚输入低
OLED_CS(1); //CS引脚输入高,片选失能, //这个可能是为了防止干扰,
}
CS————GPIOD3; spi的片选
RST————GPIOD4; 复位(spi里没有)
DC—————GPIOD5; 表示写数据还是命令。(spi里没有)
D0——————GPIOD6; spi时钟线
D1——————GPIOD7; spi MOSI,代表oled从这里接收数据,假设单片机是主机,oled屏是从机。
SPI1->CS ------ PA4----CS
SPI1->MISO ------ PA6-----D1
SPI1->MOSI ------ PA7
第一个是全双工,其实没有必要,因为oled屏好像不会返回数据给stm32
第二行是从机,我感觉单片机应该还是主机的好
第三个8帧,这个应该不用改
第四个,这个应该也是低电平,空闲时刻D0 ,,,,,,候选项:SPI_CPOL_High(=1)和SPI_CPOL_Low ( =0)
第五个,感觉应该是第一个跳变沿被采集,,,,,,, 候选项:SPI_CPHA_1Edge (=0) 和SPI_CPHA_2Edge(=1)
第六个,cs片选引脚为软件模式
第七个, 这个是波特率,分频为8,可以但是这个时钟默认应该是36M的。
第八个,这个的确是先传高字节
第九个,这个是CRC校验,实际上是这个赋值是7是没有意义的,至于为什么?
https://blog.csdn.net/kobesdu/article/details/50972273
SPI_CRCPolynomial :这是 SPI 的 CRC 校验中的多项式,若我们使用 CRC 校验
时,就使用这个成员的参数(多项式)来计算 CRC 的值。由于本实验的 Flash 不支持 CRC
校验,所以我们向这个结构体成员赋值为7 实际上是没有意义的。
配置完这些结构体成员后,我们要调用SPI_Init() 函数把这些参数写入寄存器中,实现
SPI 的初始化,然后调用
* Mode :O:写命令 1:写数据
* data :数据/命令
*
*/
void SPI_Write(char data, int Mode)
{
int i = 0;
if(Mode) //这个是用来区分命令,还是数据的。
{
OLED_DC(1); //DC引脚输入高,表示写数据
}
else
{
OLED_DC(0); //DC引脚输入低,表示写命令
}
OLED_CS(0); //CS引脚输入低,片选使能 这里符合spi协议,低电平是选中。
OLED_DC(0); //DC引脚输入低
OLED_CS(1); //CS引脚输入高,片选失能, //这个可能是为了防止干扰,
}
oled stm32的spi的更多相关文章
- STM32 F4 SPI Accelerometer
STM32 F4 SPI Accelerometer
- STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]
SPI是我最常用的接口之一,连接管脚仅为4根:在常见的芯片间通信方式中,速度远优于UART.I2C等其他接口.STM32的SPI口的同步时钟最快可到PCLK的二分之一,单个字节或字的通信时间都在us以 ...
- FPGA作为从机与STM32进行SPI协议通信---Verilog实现 [转]
一.SPI协议简要介绍 SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用 ...
- STM32的SPI问题。
问题描述: 之前一直使用的单片机是LPC2109,对其SPI很熟悉.基本就是原本拿来稍作修改就用.由于某种原因需要使用STM32,然后设备的驱动是之前写好的,只修改了一些硬件控制端口,由于硬件驱动使用 ...
- stm32之SPI通信协议
SPI (Serial Peripheral interface),顾名思义就是串行外围设备接口.SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为P ...
- FPGA作为从机与STM32进行SPI协议通信---Verilog实现
一.SPI协议简要介绍 SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用 ...
- STM32之spi管理模式
1)sip管理模式分为:硬件管理和软件管理:主要由NSS .SSI.SSM决定: NSS是芯片上一个实实在在的引脚,SSI和SSM是SPI_CR1控制器里的的位. 值得注意的是:NSS分外部引脚和内部 ...
- STM32 HAL SPI读取MPU6500的设备ID异常
1.问题背景 近前,使用STM32F4 HAL库的SPI读取MPU6500出现异常. 现象:读取ID失败,返回0,以为硬件焊接问题,各种排查,最后为了示波器测试方便,把读取ID的函数放到While(1 ...
- STM32之SPI时钟相位选择
SPI的时钟模式分为四种,由SPI_CR1寄存器的两位CPOL,CPHA组合选择. CPOL 如果为1,则时钟的空闲电平为高电平:CPOL 如果为0,则时钟的空闲电平为低电平.空闲电平影响不大. CP ...
随机推荐
- 通过rng-tools自动补充熵池
通过rng-tools自动补充熵池原文 https://blog.csdn.net/tiantao2012/article/details/78792046首先查看系统当前熵池的大小# cat /pr ...
- 设计模式之Build(生成者模式)
一.生成器模式的定义: 生成器模式也称为建造者模式.生成器模式的意图在于将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示(GoF).在软件设计中,有时候面临着一个非常复杂的对象的创 ...
- 44.Node.js Express 框架--web框架
转自:http://www.runoob.com/nodejs/nodejs-express-framework.html Express 简介 Express 是一个简洁而灵活的 node.js W ...
- Android Retrofit+RxJava 优雅的处理服务器返回异常、错误
标签: 开始本博客之前,请先阅读: Retrofit请求数据对错误以及网络异常的处理 异常&错误 实际开发经常有这种情况,比如登录请求,接口返回的 信息包括请求返回的状态:失败还是成功,错误码 ...
- [log4j]Slf4j的包冲突
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFa ...
- Linux硬件信息查看
more /proc/cpuinfo more /proc/meminfo more /proc/*info lspci 查看主板信息等cat /proc/cpuinfo CPU信息cat /proc ...
- GetInvocationList 委托链表
最近发现C#程序初始化时在构造函数中,偶尔出现事件注册不成功.后查资料发现有GetInvocationList 这么一个获取类中的委托链表的函数, 使用方法如下: 1.在需委托的类(Class1)中增 ...
- Spring AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)(转)
1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下让你不知所措,心想着:管不得很多人都和我说AOP多难多难.当我看进去以后, ...
- [Redux-Observable && Unit Testing] Use tests to verify updates to the Redux store (rxjs scheduler)
In certain situations, you care more about the final state of the redux store than you do about the ...
- JXL.jar简单封装Excel读写操作
1.分析 一个excel文件能够有多页,每页excel中能够有多行,每行中能够有多列.用面向对象的思想能够把一行中的某列看作是一个String对象,一行看作是一个包括多个列的对象.一页是包括多行的对面 ...