微雪树莓派PICO笔记——7. SPI(串行外设接口)
文章目录
- SPI简介
- 硬件连接
- 通讯协议详解
- RP2040 SPI 主要参数
- RP2040 SPI 逻辑框图
- machine.SPI类函数详解
- 例程地址
- 代码示例
- 代码实现
SPI简介
SPI全称为串行外设接口(Serial Peripherall Interface)
一种高速,全双工,同步通信总线
以主从方式工作,这种模式通常一个主设备对应一个或多个从设备
双向数据传输时需要4根线,单向数据传输时可以裁剪为3根线
硬件连接
MOSI(Master output slave input)-主设备输出/从设备输入引脚
该引脚对应主设备数据接收引脚,从设备数据发送引脚
SCLK-同步时钟,通常由主设备输出
CS - 从设备选择,用来选择从设备
功能是让主设备可以与特定从设备通信,避免数据线上的冲突
SPI没有规定最高速度,通讯速率完全有通信双方的能力决定
所以使用SPI需要查阅双方的数据手册,和根据实际情况调制通讯速率
通讯协议详解
SPI总线协议最早是摩托罗拉公司推出的一种同步串行接口
由于其简单实用,性能优异,因此许多产商的设备都支持该接口,广泛用于与·MCU和外设模块
如E2PROM,ADC,显示驱动器等
注意,SPI接口是一种事实标准,大部分产商都是参照摩托罗拉的SPI接口定义来设计的,并在此基础上衍生出很多变种
因此,不同厂家产品的SPI接口在使用上可能存在一定差别
有的甚至无法直接互连(需要软件进行必要的修改),在实际中需要仔细阅读厂家文档确认
最常见的为摩托罗拉SPI格式
主要特点:
其可以配置时钟极性和时钟相位来控制同步时钟在空闲时的状态和相位
-
时钟极性 Clock Polarity :空闲时时钟信号电平,如果时钟极性为低,则时钟信号脚空闲时输出低电平,反之则输出高电平
-
时钟相位 Clock Phase: 选择 捕获数据的时钟边缘,如果时钟相位为低,则数据在第一个时钟边缘上捕获。反之则数据在第二个时钟边缘上捕获
RP2040 SPI 主要参数
RP2040 有两个相同的SPI控制器,都是基于ARM Primecell 同步串口(ssp)(pl022)
RP2040 SPI 逻辑框图
machine.SPI类函数详解
-
machine.SPI(id,baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None)
- SPI对象构造函数,作用为初始化对应通道和引脚
- id:使用SPI通道,可为0或者1
- baudrate: SPI通讯速率,也就是SCK引脚上的频率
- polarity:时钟极性,若为0则总线空闲时SCK输出低电平,反之则输出高电平。
- phase:时钟相位,若为0则在第一个时钟边缘捕获数据,反之则在第二个时钟边缘捕获数据。
- bits:每次传输的数据位数
- firstbit:先传输高位还是低位
- sck:SCK引脚,应为Pin对象
- mosi:MOSI引脚,应为Pin对象
- miso:MISO引脚,应为Pin对象
- sck、mosi和miso均为SPI使用的引脚,应为Pin对象
-
SPI.init()
- init函数,用于重新开启SPI
-
SPI.deinit()
- deinit函数,用于关闭SPI
-
SPI.read(nbytes,write=0x00)
- read函数,用于读取从设备数据并返回
- nbytes:读取字节数
- write:读取数据时,MOSI输出数据。
-
SPI.readinto(buf,write=0x00)
- readinto函数,用于读取从设备数据并存入指定字符数组中。
- buf:字符数组,用于存放接收数据
- write:读取数据时,MOSI输出数据。
-
SPI.write(buf)
- write函数,将字符数组写入从设备。
- buf:字符数组,用于存放传输数据
-
SPI.write_readinto(write_buf, read_buf)
- write_readinto函数,用于同时发送和接收数据
- write_buf:字符数组,用于存放传输数据
- read_buf:字符数组,用于存放接收数据
- PS: 这里传输和接收数据的字符数组的长度要求一致。
例程地址
- Github仓库
MicroPython源码
代码示例
以Pico - Evel - Board 的原理图
- Pico 的CPIO10,GPIO11和GPIO12分别作为SCLK,MOSI和MISO连接到XPT2046触摸屏芯片和LCD驱动电路
XPT2046触摸芯片
一款电阻式触摸控制芯片,其通过ADC采集电压获取触摸面板坐标
一次完整的转换需要24个串行同步时钟来完成
前8个时钟用来通过SPI输入控制字节,后16个时钟读取对应ADC数值
XPT2046的控制字节各位描述表
代码实现
from machine import SPI,Pin
umport time
# 初始化SPI,使用通道1,频率为5Mhz,引脚
spi = SPI(1,baudrate=5_000_000,sck=Pin(10),mosi=Pin(11),miso=Pin(12))
# 初始化输入输出引脚将GPIO16设置为高电平
IRQ = Pin(17,Pin.IN)
TP_CS = Pin(16,Pin.OUT)
TP_CS(1)
while True:
# 当XPT2046检测到触摸,则会在IRQ引脚输出中断信号,用于表示检测到触摸
# 所以在循环中,程序会不断判断IRQ引脚是否被拉低,如果IQO引脚被拉低
# 则开始读取XPT2046的ADC读数并输出
if IRQ() == 0:
TP_CS(0)
spi.write(bytearray[0xD0])
Read_date = spi.read(2)
time.sleep_us(10)
X_Point=((Read_date[0]<<8)+Read_date[1])>>3
spi.write(bytearray[0x90])
Read_date = spi.read(2)
Y_Point=((Read_date[0]<<8)+Read_date[1])>>3
TP_CS(1)
print("*****************************")
print("*********TP_Read_ADC*********")
print("*****************************")
print("X_Point = {}".format(X_Point))
print("Y_Point = {}".format(Y_Point))
time.sleep(0.5)
微雪PICO教程