当前位置:网站首页>MindMotion MM32F3277 SoftI2C功能测试

MindMotion MM32F3277 SoftI2C功能测试

2021-11-25 17:22:12 卓晴

简 介: 对于从MindMotion SuYong发送过来的带有SoftI2C 的移植版本进行测试。初步证明了该SoftI2C移植功能。 利用OLED显示测试,可以看到该版本的SoftI2C的外部总线的命令非常慢。经过测试,可以看到该版本的SoftI2C对于输出时钟的控制没有准备好。

关键词 I2CMM32MicroPython

MM32F3277 MicroPython
文章目录
测试 MicroPython
将MicroPython下载到MCU
初步测试
编程测试
测试端口
测试I2C OLED
连接OLED
初步测试
初始化OLED
测试总结

 

§01 MM32F3277 MicroPython


  天(2021-11-25)收到MindMotion SuYong发送过来对于MM32F3277的MicroPython增加I2C总线功能的移植版本。

微蓝[SY]:
卓老师,这两天仅仅搞出来这么个鬼东西

微蓝[SY]:
硬件的i2c驱动,估计需要我亲自操刀了

微蓝[SY]:
如果soft i2c能用,我就着手先搞硬件spi的优化和pwm通道的扩展

微蓝[SY]:
这样还可以给我们做i2c硬件驱动的同事一点时间,让她调代码,或者请逐飞帮忙

  下面对于这个版本进行测试。

一、测试 MicroPython

1、将MicroPython下载到MCU

▲ 图1.1.1  下载MicroPython到MM32F3277

▲ 图1.1.1 下载MicroPython到MM32F3277

2、初步测试

(1)REPL 测试machine模块

>>> import machine
>>> dir(machine)
['__name__', 'ADC', 'DAC', 'PWM', 'Pin', 'SDCard', 'SPI', 'SoftI2C', 'SoftSPI', 'UART', 'freq', 'mem16', 'mem32', 'mem8']
>>> 

3、编程测试

  对于MicroPython关于I2C编程的文档参见: MicroPython class I2C

▲ 图1.1.2 I2C使用用例

▲ 图1.1.2 I2C使用用例

(1)初步测试

Ⅰ.测试程序
from machine                import I2C
import utime

i2c = I2C(freq400000)
i2c.scan()
i2c.writeto(42, b'123')
Ⅱ.输出结果
>> Download MicroPython : 22 lines/515 characters.
>> -------------------------------------------------------------------------

Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
ImportError: can't import name I2C
>>> 

(2)import SoftI2C

Ⅰ.测试代码
from machine                import Pin,SoftI2C
i2c = SoftI2C(freq400000)
i2c.scan()
i2c.writeto(42, b'123')
Ⅱ.输出结果
>> Download MicroPython : 22 lines/524 characters.
>> -------------------------------------------------------------------------

Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
ImportError: module not found
>>> 

4、测试端口

二、测试I2C OLED

  在 乐鑫esp8266模块MicroPython开发板MQTT物联网人工智能最小系统 测试了 I2C OLED模块,下面将其连接在MM32F3277上。

1、连接OLED

▲ 图1.2.1 在面包板上将OLED连接在测试板上

▲ 图1.2.1 在面包板上将OLED连接在测试板上

2、初步测试

(1)扫描总线

Ⅰ.测试代码
from machine                import Pin,SoftI2C
import utime

print("Test I2C")

scl = Pin('PA0')
sda = Pin('PA1')

i2c = SoftI2C(scl, sda, freq=100000)

ret = i2c.scan()
print(ret)
Ⅱ.输出结果
>> Download MicroPython : 26 lines/584 characters.
>> -------------------------------------------------------------------------

Test I2C
[60]
>>> 

从上面的scan得到的I2C的Slave的地址为60(0x3C),这与在 乐鑫esp8266模块MicroPython开发板MQTT物联网人工智能最小系统 给定的地址是一致的。

(2)测试写入

Ⅰ.测试代码
from machine                import Pin,SoftI2C
import utime
from micropython import const

scl = Pin('PA0')
sda = Pin('PA1')

i2c = SoftI2C(scl, sda, freq=100000)

ret = i2c.scan()
print(ret)

temp = bytearray(2)
i2c.start()
temp[0] = 120
temp[1] = 1
i2c.write(temp)
i2c.stop()

print('Test end.')
Ⅱ.输出结果
>> Download MicroPython : 34 lines/760 characters.
>> -------------------------------------------------------------------------

[60]
2
Test end.
>>> 

  可以看到写入两个字节。

3、初始化OLED

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTI2C.PY -- by Dr. ZhuoQing 2021-11-25
#
# Note:
#============================================================
from machine                import Pin,SoftI2C
import utime
from micropython import const
#------------------------------------------------------------
scl = Pin('PA0')
sda = Pin('PA1')
i2c = SoftI2C(scl, sda, freq=100000)
#------------------------------------------------------------
SET_CONTRAST        = const(0x81)
SET_ENTIRE_ON       = const(0xa4)
SET_NORM_INV        = const(0xa6)
SET_DISP            = const(0xae)
SET_MEM_ADDR        = const(0x20)
SET_COL_ADDR        = const(0x21)
SET_PAGE_ADDR       = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP       = const(0xa0)
SET_MUX_RATIO       = const(0xa8)
SET_COM_OUT_DIR     = const(0xc0)
SET_DISP_OFFSET     = const(0xd3)
SET_COM_PIN_CFG     = const(0xda)
SET_DISP_CLK_DIV    = const(0xd5)
SET_PRECHARGE       = const(0xd9)
SET_VCOM_DESEL      = const(0xdb)
SET_CHARGE_PUMP     = const(0x8d)
#------------------------------------------------------------
class SSD1306():
    def __init__(self, width, height, external_vcc):
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        self.init_display()
    def init_display(self):
        for cmd in (
            SET_DISP | 0x00,            # off
            SET_MEM_ADDR, 0x00,         # horizontal
            SET_DISP_START_LINE | 0x00,
            SET_SEG_REMAP | 0x01,       # column addr 127 mapped to SEG0
            SET_MUX_RATIO, self.height - 1,
            SET_COM_OUT_DIR | 0x08,     # scan from COM[N] to COM0
            SET_DISP_OFFSET, 0x00,
            SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
            SET_DISP_CLK_DIV, 0x80,
            SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
            SET_VCOM_DESEL, 0x30,       # 0.83*Vcc
            SET_CONTRAST, 0xff,         # maximum
            SET_ENTIRE_ON,              # output follows RAM contents
            SET_NORM_INV,               # not inverted
            SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
            SET_DISP | 0x01):           # on
            self.write_cmd(cmd)
        self.fill(0xff)
        self.show()
    def fill(self, c):
        for i in range(len(self.buffer)):
            self.buffer[i] = c
    def poweroff(self):
        self.write_cmd(SET_DISP | 0x00)
    def poweron(self):
        self.write_cmd(SET_DISP | 0x01)
    def contrast(self, contrast):
        self.write_cmd(SET_CONTRAST)
        self.write_cmd(contrast)
    def invert(self, invert):
        self.write_cmd(SET_NORM_INV | (invert & 1))
    def show(self):
        x0 = 0
        x1 = self.width - 1
        if self.width == 64:
            x0 += 32
            x1 += 32
        self.write_cmd(SET_COL_ADDR)
        self.write_cmd(x0)
        self.write_cmd(x1)
        self.write_cmd(SET_PAGE_ADDR)
        self.write_cmd(0)
        self.write_cmd(self.pages - 1)
        self.write_data(self.buffer)
class SSD1306_I2C(SSD1306):
    def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
        self.i2c = i2c
        self.addr = addr
        self.temp = bytearray(2)
        super().__init__(width, height, external_vcc)
    def write_cmd(self, cmd):
        self.temp[0] = 0x80 # Co=1, D/C#=0
        self.temp[1] = cmd
        self.i2c.writeto(self.addr, self.temp)
    def write_data(self, buf):
        self.temp[0] = self.addr << 1
        self.temp[1] = 0x40         # Co=0, D/C#=1
        self.i2c.start()
        self.i2c.write(self.temp)
        self.i2c.write(buf)
        self.i2c.stop()
#------------------------------------------------------------
oled = SSD1306_I2C(128, 64, i2c, addr=0x3c)
#oled.text('Hello world!', 0, 0)
#oled.text('OLED test', 0, 50)
#oled. show()
#------------------------------------------------------------
# END OF FILE : TESTI2C.PY
#============================================================

  下面是在OLED初始化过程中写入1024 个字节的过程,过程异常的缓慢。

▲ 图1.2.2  刷新OLED过程

▲ 图1.2.2 刷新OLED过程

  之所以这么慢,通过示波器测试SCL,SDA的波形,可以看到此时的波特率只有400Hz, 与初始化的波特率相差很多。

▲ 图1.2.3 I2C总线的写过程

▲ 图1.2.3 I2C总线的写过程

 

试总结 ※


  于从MindMotion SuYong发送过来的带有SoftI2C 的移植版本进行测试。初步证明了该SoftI2C移植功能。 利用OLED显示测试,可以看到该版本的SoftI2C的外部总线的命令非常慢。

  经过测试,可以看到该版本的SoftI2C对于输出时钟的控制没有准备好。


■ 相关文献链接:

● 相关图表链接:

版权声明
本文为[卓晴]所创,转载请带上原文链接,感谢
https://blog.csdn.net/zhuoqingjoking97298/article/details/121538923

随机推荐