[原创] MicroPython 普通IO口模拟SPI通信,移植到某些板子上可能会用到

如意如意   2020-7-9 11:41 楼主

将MicroPython移植到一个STM32F407板子上,由于硬件设计原因,只能用普通IO口模拟SPI通信,因此对照C语言写了MicroPython的驱动,希望对大家有帮助。

本人水平有限,如有错误之处,欢迎指正。

 

使用时将custom_spi.py复制到PYFLASH磁盘中,在main.py导入模块。

# -*- coding: utf-8-*-
# main.py -- put your code here!
from pyb import udelay, LED # 导入相关模块
from custom_spi import SPI  # 从定制spi模块中导入SPI对象

# 定义SPI对象,定义cs:D8, clk:D9, mosi:D10, miso:D11 (根据硬件连接决定)
my_spi = SPI('D8','D9','D10','D11')

# 发送字符串
my_spi.write_str('hello\r\n')

# 接收数据
my_spi.read(4)      

custom_spi.py文件如下:

# -*- coding: utf-8-*-
# custom_spi.py -- put your code here!
from pyb import Pin, udelay  # 导入相关模块

# 普通IO模拟SPI驱动
class SPI(object):
    """创建SPI对象时传入四个参数
        cs:   片选信号
        clk:  主机时钟信号
        mosi: 主机输出(从机输入)信号
        miso: 主机输入(从机输出)信号
    """
    # 对象创建时,自动初始化
    def __init__(self, cs, clk, mosi, miso):
        super(SPI, self).__init__()
        self.SPI_CS = Pin(cs, Pin.OUT_PP)              #片选信号输出
        self.SPI_CLK = Pin(clk, Pin.OUT_PP)            #时钟输出
        self.SPI_MOSI = Pin(mosi, Pin.OUT_PP)          #SPI输出
        self.SPI_MISO = Pin(miso, Pin.IN, Pin.PULL_UP) #SPI输入
        self.SPI_CS.high()                             #片选信号拉高
        self.SPI_CS.low()                              #片选信号拉低
        self.SPI_CLK.high()                            #时钟拉高
        self.SPI_CLK.low()                             #时钟拉低
        self.SPI_MOSI.high()                           #输入拉高
        self.SPI_MOSI.low()                            #输入拉低
        self.SPI_MISO.value()                          #输出
    
    # SPI发送一字节函数,传入一字节
    def _write_byte(self, data):
        temp = 0                     # 定义接收变量接收返回字节
        for i in range(7):           # 循环七次,发送七字节
            if data & 0x80:          # 发送最高位的一比特
                self.SPI_MOSI.high() # 输出信号线拉高
            else:
                self.SPI_MOSI.low()  # 输出信号线拉低
            
            self.SPI_CLK.low()       # 时钟信号线拉低
            udelay(5)                # 等输出信号线稳定

            if self.SPI_MISO.value():# 读取输入信号线
                temp |= 1            # 接收变量按位赋值
            else:
                temp |= 0

            self.SPI_CLK.high()      # 时钟信号线拉高,从机接收数据
            udelay(5) 
            data <<= 1               # 数据左移一位
            temp <<= 1               # 接收变量左移一位

        if data & 0x80:              # 发送最后一比特,不左移
            self.SPI_MOSI.high()
        else:
            self.SPI_MOSI.low()

        self.SPI_CLK.low()
        udelay(5) 

        if self.SPI_MISO.value():
            temp |= 1
        else:
            temp |= 0

        self.SPI_CLK.high()
        udelay(5) 

        return(chr(temp))             # 将ascii转换为字符并返回

    # 发送字符串,传入要发送的字符串
    def write_str(self, str):
        res = ''
        self.SPI_CS.high()                   # 片选信号拉高
        for i in str:                        # 逐个发送字符
            res += self._write_byte(ord(i))  # 将字符转换为ascii码值,传给写字节函数
        self.SPI_CS.low()                    # 片选信号拉低

        return(res)
        
    # 读字节函数,传入读取字节数
    def read(self, l):
        res = ''
        self.SPI_CS.low()
        for i in range(l):
            res += self._write_byte(0x00)     # 主机发送0x00,获取从机数据
        self.SPI_CS.high()

        return(res)

 

回复评论 (9)

 micropython已经支持软件I2C和软件SPI了。

 

from machine import SPI, Pin
spi = SPI(-1, sck = Pin('C0'), mosi = Pin('C1'), miso = Pin('C2'))

 

 

 

点赞 (1) 2020-7-9 12:04

哦哦,谢谢

点赞  2020-7-9 14:11
引用: dcexpert 发表于 2020-7-9 12:04  micropython已经支持软件I2C和软件SPI了。   from machine import SPI, Pin spi = SPI ...

请问版主,FSMC通信用micropython怎么实现?现在支持么?

点赞  2020-7-9 14:23
引用: 如意如意 发表于 2020-7-9 14:23 请问版主,FSMC通信用micropython怎么实现?现在支持么?

目前是不支持的,需要自己移植到固件中。只有少数F4、F7带有FSMC

点赞 (1) 2020-7-9 16:18
引用: dcexpert 发表于 2020-7-9 16:18 目前是不支持的,需要自己移植到固件中。只有少数F4、F7带有FSMC

嗯嗯,谢谢版主

点赞  2020-7-9 16:50

https://github.com/formica-multiuso/micropython-fsmc-sram  有人用python写了FSMC的驱动

点赞  2020-7-9 18:41
引用: 如意如意 发表于 2020-7-9 16:50 嗯嗯,谢谢版主

刚查了一下,前面说错了,现在STM32中已经支持FMC内存,具体可以参考STM32F769DISC板的定义

点赞  2020-7-9 21:05
引用: dcexpert 发表于 2020-7-9 21:05 刚查了一下,前面说错了,现在STM32中已经支持FMC内存,具体可以参考STM32F769DISC板的定义

请问下版主,我在是正点原子的stm32f428igt开发板上移植micropython,当前已能够repl控制led,但一直出现不了虚拟磁盘,我该从哪里查该问题,谢谢

点赞  2021-3-29 17:22
引用: qiuguo 发表于 2021-3-29 17:22 请问下版主,我在是正点原子的stm32f428igt开发板上移植micropython,当前已能够repl控制led,但一直出现 ...

不清楚正点原子的板子,虚拟磁盘需要连接STM32自己的USB口,并在配置文件中使能USB功能才行。可以参考源码中STM32F429Disco开发板的配置。

点赞  2021-3-29 20:57
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复