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

Posted 卓晴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MicroPython内核开发笔记书内软件用例 :SPI部分的实验相关的知识,希望对你有一定的参考价值。

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

关键词 MicroPythonMM32F3277SPI

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

 

 

§01 稿内容


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

SPI管脚SCKMOSIMISO
SPI0PA5PA7PA6
SPI1PB10PB15PB14
SPI2PC9PA8PB9

一、基础实验

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时钟极性与相位

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信号波形

(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信号波形

二、读写FLASH

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

▲ 图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 信号波形

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

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


■ 相关文献链接:

● 相关图表链接:

以上是关于MicroPython内核开发笔记书内软件用例 :SPI部分的实验的主要内容,如果未能解决你的问题,请参考以下文章

MicroPython内核开发笔记书内软件用例 :MEM相关实验用例

MicroPython内核开发笔记书内软件用例 :浮点数相关实验

MicroPython内核开发笔记书内软件用例 :DAC相关实验

MicroPython内核开发笔记书内软件用例 :Timer相关实验

MicroPython内核开发笔记书内软件用例 :UART相关实验

MicroPython内核开发笔记书内软件用例 :ADC 相关实验