Introduction: Test the migrated version with SoftI2C sent from MindMotion SuYong. The porting function of the SoftI2C is preliminarily proved. Using OLED display test, you can see that the command of the external bus of this version of SoftI2C is very slow. After testing, it can be seen that this version of SoftI2C is not ready for the control of the output clock.
Keywords: I2C, MM32, micropathon
§01 MM32F3277 MicroPython
today (November 25, 2021), I received a porting version from MindMotion SuYong to add I2C bus function to the microphoton of MM32F3277.
Bluish[SY]: Mr. Zhuo, only such a ghost came out these two days Bluish[SY]: Hardware i2c Driver, I think I need to operate the knife myself Bluish[SY]: If soft i2c If it works, I'll start with the hardware first spi Optimization and pwm Channel expansion Bluish[SY]: This can also be done for us i2c Hardware driven colleagues take a moment to let her adjust the code, or ask for help from zhufei
- Download address: firmware-2021-11-25
test this version below.
1, Test micro Python
1. Download micro Python to MCU
▲ figure 1.1.1 download microphoton to MM32F32772. Preliminary test
(1) REPL test machine module
>>> import machine >>> dir(machine) ['__name__', 'ADC', 'DAC', 'PWM', 'Pin', 'SDCard', 'SPI', 'SoftI2C', 'SoftSPI', 'UART', 'freq', 'mem16', 'mem32', 'mem8'] >>>
3. Programming test
for the documents on I2C programming of micropathon, see: MicroPython class I2C
▲ figure 1.1.2 I2C use case(1) Preliminary test
I. test procedure
from machine import I2C import utime i2c = I2C(freq400000) i2c.scan() i2c.writeto(42, b'123')
Ⅱ. Output results
>> 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
I. test code
from machine import Pin,SoftI2C i2c = SoftI2C(freq400000) i2c.scan() i2c.writeto(42, b'123')
Ⅱ. Output results
>> Download MicroPython : 22 lines/524 characters. >> ------------------------------------------------------------------------- Traceback (most recent call last): File "<stdin>", line 10, in <module> ImportError: module not found >>>
4. Test port
2, Test I2C OLED
in Lexin esp8266 module micro Python development board MQTT IOT artificial intelligence minimum system The I2C OLED module has been tested. Next, connect it to MM32F3277.
1. Connecting OLED s
▲ figure 1.2.1 connect the OLED to the test board on the bread board2. Preliminary test
(1) Scan bus
I. test code
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)
Ⅱ. Output results
>> Download MicroPython : 26 lines/584 characters. >> ------------------------------------------------------------------------- Test I2C [60] >>>
The Slave address of I2C obtained from the scan above is 60 (0x3C), which is different from that in Lexin esp8266 module micro Python development board MQTT IOT artificial intelligence minimum system The given address is consistent.
(2) Test write
I. test code
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.')
Ⅱ. Output results
>> Download MicroPython : 34 lines/760 characters. >> ------------------------------------------------------------------------- [60] 2 Test end. >>>
you can see that two bytes are written.
3. Initialize 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 #============================================================
the following is the process of writing 1024 bytes during OLED initialization. The process is abnormally slow.
▲ figure 1.2.2 refresh OLED processthe reason why it is so slow is that the baud rate at this time is only 400Hz, which is much different from the initialized baud rate by testing the waveforms of SCL and SDA through the oscilloscope.
▲ figure 1.2.3 writing process of I2C bus
※ test summary ※
test the transplanted version with SoftI2C sent from MindMotion SuYong. The porting function of the SoftI2C is preliminarily proved. Using OLED display test, you can see that the command of the external bus of this version of SoftI2C is very slow.
after testing, it can be seen that this version of SoftI2C is not ready for the control of the output clock.
■ links to relevant literature:
- firmware-2021-11-25
- MicroPython class I2C
- Lexin esp8266 module micro Python development board MQTT IOT artificial intelligence minimum system
● relevant chart links: