MicroPython内核开发笔记书内软件用例 :SPI部分的实验

简 介: 本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的 SPI 软件用例部分内容。

关键词 MicroPythonMM32F3277SPI

书稿内容
目 录
Contents
基础实验
读写FLASH
总 结
存在问题

§01 稿内容


在MM32F3277 MicroPython 所支持的 SPI 包括三个通道: SPI0、SPI1、SPI2,下面表格给出了它们占用的端口资源。

SPI管脚 SCK MOSI MISO
SPI0 PA5 PA7 PA6
SPI1 PB10 PB15 PB14
SPI2 PC9 PA8 PB9

一、基础实验

1、显示SPI信息

通过下面小程序,也可以直接通过 REPL 交互输入下面程序,显示 SPI 相关信息。

from machine                import Pin,SPI
import time

print(SPI(0))
print(SPI(1))
print(SPI(2))

执行结果显示如下,给出了三个通道所占用的单片机管脚资源。

SPI(id=0, baudrate=80000000, polarity=0, phase=0), on MOSI(PA7), MISO(PA6), SCK(PA5)
SPI(id=1, baudrate=80000000, polarity=0, phase=0), on MOSI(PB15), MISO(PB14), SCK(PB10)
SPI(id=2, baudrate=80000000, polarity=0, phase=0), on MOSI(PA8), MISO(PB9), SCK(PC9)

可以看到,缺省情况下,SPI 的时钟频率为 8MHz,极性和相位模式为 00。四种不同的时钟极性相位模式对应的 SPI 信号如下图所示。

▲ 图1.1.1 SPI时钟极性与相位

▲ 图1.1.1 SPI时钟极性与相位

2、SPI相关函数

通过下面代码,可以查看 spi 对象提供的相关函数。

from machine                import SPI
spi = SPI(0, baudrate=100000, polarity=1, phase=0)
dir(SPI)

代码输出信息为:

['read', 'readinto', 'write', 'LSB', 'MSB', 'deinit', 'init', 'write_readinto']
  • init:初始化 SPI 总线;
  • deinit:关闭 SPI 总线;
  • read,readinto:从 SPI 读入若干字节,同时写出固定字节;
  • write,write_readinto:从 SPI 输出若干字节,同时将读入数据存入内部缓存;
  • LSB,MSB:分别设置字节的低位先发送和高位先发送;缺省情况下,是字节高位先发送;

3、测试SPI输出信号

(1)SPI输出字节

下面代码将 SPI0 设置成波特率 100kHz, 时钟 polarity=1,phase=0。 每隔 10ms 发送字节 0x55,0xaa。spi 通过函数 write 输出数据。

在PA5(SCK)、PA7(MOSI)测量 SPI0 输出信号。

from machine                import Pin,SPI
import time

spi = SPI(0, baudrate=100000, polarity=1, phase=0)

print("Begin to send 0x55aa from SPI0.")

buf = bytes((0x55,0xaa))
while True:
    spi.write(buf)
    time.sleep_ms(10)

▲ 图1.1.2 MOSI,SCK信号波形

▲ 图1.1.2 MOSI,SCK信号波形

(2)SPI读入字节

由于 SPI 总结是全双工总线,也就是发送与接收可以同时进行。下面代码从 SPI 总线读入两个字节,在读入字节的同时,输出 0x55。

from machine                import Pin,SPI
import time

spi = SPI(0, baudrate=100000, polarity=1, phase=0)
print("Begin to read 2 bytes from SPI0.")

buf = bytes((0x55,0xaa))
while True:
    data = spi.read(2,0x55)
    time.sleep_ms(10)

测量 PA5(SCK)、PA7(MOSI)两个管脚的信号。从信号波形上可以看到,SPI 读入函数 read 在执行的时候,读入两个字节的同时发送了两个字节的 0x55。
▲ 图1.1.3 MOSI,SCK信号波形

▲ 图1.1.3 MOSI,SCK信号波形

二、读写FLASH

在 PLUS-F3270 实验板上配置有一颗 SPI接口的FLASH芯片 W25Q64 ,连接在 SPI1接口上。 使用 PE3 作为芯片的片选信号。

▲ 图1.2.1 实验板上的FLASH

▲ 图1.2.1 实验板上的FLASH

1、读W25Q64 ID数据

根据 W25Q64 数据手册可知,通过指令 0x90,0xab,0x4b 可以分别读出厂商ID、器件ID、64位唯一序列号。下面代码演示了读取这些 ID 数据方法。使用了 SPI 的 write_readinto 函数,完成了命令的发送与数据的接受。

from machine                import Pin,SPI
import time

W25Q_CE = Pin("PE3", Pin.OUT_PUSHPULL, value=1)
W25Q_SPI = SPI(1, baudrate=8000000, polarity=0, phase=1)

def w25qIO6Bytes(outb,inbs):
    outbuf = bytes([outb] + [0]*(inbs-1))
    inbuf = bytearray(inbs)

    W25Q_CE(0)
    W25Q_SPI.write_readinto(outbuf, inbuf)
    W25Q_CE(1)

    return inbuf

inb = w25qIO6Bytes(0x90,6)
print(list(inb))
inb = w25qIO6Bytes(0xab,5)
print(list(inb))
inb = w25qIO6Bytes(0x4b,13)
print(list(inb))

下面是代码运行结果。对比 W25Q64 数据手册,可以知道读出的数据是正确的。

[255, 255, 255, 255, 239, 23]
[255, 255, 255, 255, 23]
[255, 255, 255, 255, 255, 210, 100, 108, 51, 91, 20, 19, 45]

2、W25Q64数据读写

下面给出了利用 SPI 对 W25Q64 进行读、写、擦除等函数。

def w25qReadData(address, readlen):
    inbuf = bytearray(readlen)

    W25Q_CE(0)
    W25Q_SPI.write(b'\x03' + address.to_bytes(3, 1))
    W25Q_SPI.readinto(inbuf, 0x0)
    W25Q_CE(1)

    return inbuf

def w25qWritePage(address, data):
    W25Q_CE(0)
    W25Q_SPI.write(b'\x02' + address.to_bytes(3, 1) + data)
    W25Q_CE(1)

def w25qWriteEnable():
    W25Q_CE(0)
    W25Q_SPI.write(b'\x06')
    W25Q_CE(1)

def w25qSectorErase(address):
    W25Q_CE(0)
    W25Q_SPI.write(b'\x20' + address.to_bytes(3, 1))
    W25Q_CE(1)

利用上述函数可以完成对 W25Q64 的编程。

下面是在对 W25Q64 编程之前读取 W25Q64前 16 字节数据,都是0xff,这说明这些地址可以允许后期写入新的数据。

bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')

下面代码是将 0x0 ~ 0xf 写入 W25Q64。

w25qWriteEnable()
w25qWritePage(0x0, bytes(list(range(0x10))))
time.sleep_ms(10)
inb = w25qReadData(0, 0x10)
print(inb)

然后在读取前 0x10 个数据,显示的结果如下:

bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f')

  结 ※


本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的 SPI 软件用例部分内容。

一、存在问题

1、SPI输出管脚

当 SPI 的 CLK 的极性设置为 0, polarity=0 时,CLK信号在静态时似乎是高阻状态。下面是抓取到的信号波形。可以看到在CLK波形基线存在50Hz干扰信号。

▲ MOSI,CLK 信号波形

▲ MOSI,CLK 信号波形

但是,当 polarity=1时, CLK信号处在高电平时,电压是稳定的。

猜测:具体原因不详。 似乎需要将 CLK 信号线通过下拉电阻接地。


■ 相关文献链接:

● 相关图表链接:

猜你喜欢

转载自blog.csdn.net/zhuoqingjoking97298/article/details/125548560