zl程序教程

您现在的位置是:首页 >  后端

当前栏目

测试MM32 MicroPython测试电路板的基本功能

MicroPython测试 基本功能
2023-09-11 14:15:19 时间

简 介: 对于来自于逐飞的MM32 MicroPython模块进行补充测试。总结了现在一些缺少的功能。

关键词 MicroPythonMM32逐飞灵动单片机

测试板简介
目 录
Contents
改进下载软件
SD卡中的示例程序
将REPL的RX连接到B11
测试模块
UART测试
SERVO测量
LCD180测试
CCD测试
编码器
测试总结

 

§01 试板简介


  在 测试逐飞的MM32F3277 MicroPython开发板的基本功能 中对于来自于逐飞的MM32 MicroPython测试模块的基本功能进行了初步测试。包括GPIO, ADC, PWM以及Timer的功能。下面对于该模块的其它功能进行逐一测试。

一、改进下载软件

  使用 STM32 Bootloader 利用串口REPL功能对于测试板进行程序下载。将测试板上的SD卡去掉之后,复位之后模块自动进REPL状态。改进后的软件通过检测 “>>> ”字符串确定是否开始发送 CTRL+E。利用这种条件提高了STM32 Bootloader下载的成功率。

▲ 图1.1.1 下载MicroPython的过程

▲ 图1.1.1 下载MicroPython的过程

二、SD卡中的示例程序

  在模块内部的SD中包括以下几个示例程序:

  • ADC.py
  • CCD.py
  • ENCODER.py
  • GPIO.py
  • LCD180.py
  • main.py
  • MicroPython驱动层接口定义.xlsx
  • PWM.py
  • SERVO.py
  • TIMER.py
  • UART.py

三、将REPL的RX连接到B11

1、开发板改造

  为了能够在后面测试中实现MicroPython程序与REPL之间的交互,将调试端口RX连接到B11(UART,RX)。这主要是在移植后的MicroPython中没有实现Input函数,所以通过UART3接收来自于REPL的字符,可以方便面后期的测试。

2、STM32命令

  使用如下tsp 命令可以从UART3接收到字符:

stm32cmd('SENDC%s‘%string)

  有MicroPython通过如下子程序接收到string.

while True:
    if uart.any():
        uart_str = uart.read()
        print(uart_str)
        servo.angle(int(uart_str))        

 

§02 试模块


一、UART测试

1、UART 模块

  UART1使用了MCU 的UART3。

UART参数:
端口:UART3
RX:B11
TX:B10

▲ 图2.1.1 UART模块的基本信息

▲ 图2.1.1 UART模块的基本信息

▲ 图2.1.2 B10,B11在背板上的位置

▲ 图2.1.2 B10,B11在背板上的位置

2、测试代码

  循环输出‘U’,应该对应0b01010101 字符。

from seekfree               import UART,GPIO

uart = UART(115200)

def delay(loop=50000):
    for _ in range(loop):
        pass

print('Test UART.')
while True:
    uart.write('U')
    delay(100000)

3、测量结果

  在B10(TX)测量到输出字符‘U’对应的电压波形:

▲ 图2.1.3 B10 输出的信号波形

▲ 图2.1.3 B10 输出的信号波形

  但是同时,在REPL接收到‘1’字符的输出。下面是REPL UART输出的波形。

▲ 图2.1.4 REPL输出波形

▲ 图2.1.4 REPL输出波形

  将发送的字符信息修改成“HELLO”,则在REPL输出会得到‘5’。这说明每当uart输出时,会同时在REPL端口输出UART送出的字符的个数。

  提示:这应该是原来移植过程中的调试信息,需要被去掉。

while True:
    uart.write('HELLO')
    delay(100000)

4、测试输入输出

  将B10,B11短接起来,这样便可以接收到自行发送的字符。

(1)测试代码

from seekfree               import UART,GPIO

uart = UART(115200)

def delay(loop=50000):
    for _ in range(loop):
        pass

print('Test UART.')
while True:
    if uart.any():
        uart_str = uart.read()
        print(uart_str)

    uart.write('HELLO')
    delay(100000)

(2)REPL输出

▲ 图2.1.5 REPL窗口输出结果

▲ 图2.1.5 REPL窗口输出结果

二、SERVO测量

1、硬件端口

舵机的输出接口:
MCU端口:A15

▲ 图2.2.1 SERVO 基本特性

▲ 图2.2.1 SERVO 基本特性

2、输出信号

(1)Angle=0输出脉冲

  angle=0时,输出脉冲宽度为0.5ms。
▲ 图2.2.2 angle = 0 对应的servo 的脉冲

▲ 图2.2.2 angle = 0 对应的servo 的脉冲

(2)Angle=180输出脉冲

  angle = 180,输出脉冲的宽度为2.5ms。

▲ 图2.2.3 angle = 180 对应的servo 的脉冲

▲ 图2.2.3 angle = 180 对应的servo 的脉冲

3、测试不同的angle

  通过设置angle 从0 ~ 180,测量 SERVO脉冲平均电压。如下图所示。

  可以看到除了少数的测量抖动之外,输出的电压平均值随着angle线性上升。
▲ 图2.2.4 不同的ANGLE设置下测量SERVO脉冲平均电压

▲ 图2.2.4 不同的ANGLE设置下测量SERVO脉冲平均电压

解释:后面通过试验证明,上述曲线中的往下的三次抖动,来源于接受字符串没有能够完整接收到设置参数的3个字符。如果将判断 改成 uart.any() >= 3,便可以消除这方面的抖动了。

4、带动舵机

(1)测试代码

from seekfree               import SERVO,GPIO,UART

servo = SERVO(50)
uart = UART(115200)

dir = 1
n = 0
count = 0x2ff

led1 = GPIO(0x1d, 1, 0)
led2 = GPIO(0x72, 1, 0)

servo.angle(180)
print("Test Servo..")

flag = 1
while True:
    if uart.any():
        uart_str = uart.read()
        print(uart_str)
        servo.angle(int(uart_str))

    #--------------------------------------------------------
    while count != 0:
        count -= 1

    count = 0x2ff

    if flag == 0:
        led1.high()
        led2.low()
        flag = 1
    else:
        led1.low()
        led2.high()
        flag = 0

    #--------------------------------------------------------

    if dir == 1:
        n += 1
        if n >= 180:
            dir = 0
    else:
        n -= 1
        if n <= 0:
            dir = 1

    servo.angle(n)

(2)舵机运动

▲ 图2.2.5  控制舵机运动

▲ 图2.2.5 控制舵机运动

三、LCD180测试

1、HELP信息

module : LCD180
---------------------------------------------------------------------------------
func                           |  explain
---------------------------------------------------------------------------------
LCD180()                       |  Parameter up to one, at least zero.
LCD180(dir)                    |  dir[[0-PORTAIT_U,1-PORTAIT_D,2-CROSSWISE_R,3-CROSSWISE_L]], default dir = 0.
LCD180(dir, pen_color)         |  pen_color[RGB565], default pen_color = BLACK<0x0000>.
LCD180(dir, pen_color, bgcolor)|  bgcolor[RGB565], default bgcolor = WHITE<0xFFFF>.
---------------------------------------------------------------------------------
LCD180.help()                  |  No parameter. Module prompt.
---------------------------------------------------------------------------------
LCD180.info()                  |  No parameter. Module parameter info.
---------------------------------------------------------------------------------
LCD180.full()                  |  Parameter up to one, at least zero.
LCD180.full(color)             |  color[RGB565]
                               |  Enter with no Parameter will full whith bgcolor.
---------------------------------------------------------------------------------
LCD180.show_image \           |  Parameter up to six, at least three.
(img, length, wide, x, y, zoom)|  img     - image, must be entered.
                               |  length  - image length, must be entered.
                               |  wide    - image wide, must be entered.
                               |  x       - display offset for x axial, default 0, should be less than X_MAX.
                               |  y       - display offset for y axial, default 0, should be less than Y_MAX.
                               |  zoom    - the ratio of display reduction, default 0, scale down the length and width.
---------------------------------------------------------------------------------
LCD180.show_wave \            |  Parameter up to six, at least three.
(wave, length, max,            |  wave    - wave, must be entered.
 x, y, zoom_x, zoom_y)         |  length  - wave length, must be entered.
                               |  max     - wave max value, must be entered.
                               |  x       - display offset for x axial, default 0, should be less than X_MAX.
                               |  y       - display offset for y axial, default 0, should be less than Y_MAX.
                               |  zoom_x  - the ratio of display reduction, default 0, scale down the length.
                               |  zoom_y  - the ratio of display reduction, default 0, scale down the max.
---------------------------------------------------------------------------------
LCD180.show_str \             |  Parameter up to six, at least three.
(str, x, y, color, sparency)   |  str     - string, must be entered.
                               |  x       - display offset for x axial, default 0, should be less than X_MAX.
                               |  y       - display offset for y axial, default 0, should be less than Y_MAX.
                               |  color   - string color, RGB565 data, default bgcolor.
                               |  sparency- background transparent, default is 0-disable, set 1-enable.
---------------------------------------------------------------------------------

2、填充颜色

from seekfree               import GPIO,UART,LCD180

dis = LCD180(0)

def delay(loop=50000):
    for _ in range(loop):
        pass

while True:
    delay()
    dis.full(dis.BLUE)
    delay()
    dis.full(dis.RED)
    

▲ 图2.3.1  重复填充颜色

▲ 图2.3.1 重复填充颜色

3、显示字符串

from seekfree               import GPIO,UART,LCD180

dis = LCD180(0)
dis.full(dis.BLUE)

def delay(loop=50000):
    for _ in range(loop):
        pass

dis.show_str('hello', 0, 0)
count = 0
while True:
    dis.show_str('COUNT:%04d'%count, 10, 100)
    count += 1
    delay(10000)

▲ 图2.3.2  显示字符串

▲ 图2.3.2 显示字符串

4、显示电压波形

  从ADC读取电压,并显示在LCD中。

from seekfree               import GPIO,UART,LCD180,ADC

adc = ADC(0)
adc.channel_init(adc.A4)

dis = LCD180(1)
dis.full(dis.WHITE)

def delay(loop=50000):
    for _ in range(loop):
        pass

dis.show_str('hello', 0, 0)
count = 0

buf = [0] * 128

while True:
    for i in range(128):
        value = adc.value(adc.A4)
        buf[i] = value//16
        delay(100)

    dis.show_wave(bytes(buf), 128, 0xff, 0, 0, 0, 2)
    delay(10000)

▲ 图2.3.3  显示的波形

▲ 图2.3.3 显示的波形

四、CCD测试

1、硬件接口

▲ 图2.4.1 CCD接口

▲ 图2.4.1 CCD接口

▲ 图2.4.2 CCD接口

▲ 图2.4.2 CCD接口

▲ 图2.4.3 CCD接口

▲ 图2.4.3 CCD接口

2、显示采集结果

1测试代码

from seekfree               import GPIO,UART,LCD180,ADC,CCD

dis = LCD180(1)
dis.full(dis.WHITE)

def delay(loop=50000):
    for _ in range(loop):
        pass

ccd = CCD(1)

while True:
    dis.show_wave(ccd, 128, 0xff, 0, 0, 0, 2)

    delay(10000)

(2)测试结果

▲ 图2.4.4  使用LCD显示CCD采集到的数据

▲ 图2.4.4 使用LCD显示CCD采集到的数据

五、编码器

1、编码器接口

▲ 图2.5.1 编码器接口

▲ 图2.5.1 编码器接口

▲ 图2.5.2 编码器接口

▲ 图2.5.2 编码器接口

▲ 图2.5.3 编码器接口

▲ 图2.5.3 编码器接口

▲ 图A2.5.4 编码接口

▲ 图A2.5.4 编码接口

2、正交编码信号

由直流电机的HALL编码器获得对应的速度信号。

▲ 图2.5.4 直流电机输出速度信号

▲ 图2.5.4 直流电机输出速度信号

▲ 图2.5.6 直流电机

▲ 图2.5.6 直流电机

STM32毕业设计:基于stm32c8t6的坡道行驶巡线小车制作教程 中给出了此种电机的基本参数。

  • 型号MG513 p30 12v
  • 转动一圈390个脉冲
  • 减速比1比30

▲ 图2.5.5 两路正交速度编码信号

▲ 图2.5.5 两路正交速度编码信号

--------------------------------------------------------------------------------
module : ENCODER
---------------------------------------------------------------------------------
func                     |  explain
---------------------------------------------------------------------------------
ENCODER(ch, mode)        |  Constructor, ch [1-2], mode[1-2]<QuadDec, Incremental>.
---------------------------------------------------------------------------------
ENCODER.help()           |  No parameter. Module prompt.
---------------------------------------------------------------------------------
ENCODER.value()          |  No parameter. Get encoder count.
---------------------------------------------------------------------------------
ENCODER.reset()          |  No parameter. Reset encoder count.
---------------------------------------------------------------------------------
ENCODER.enable()        |  No parameter. Module enable.
---------------------------------------------------------------------------------
ENCODER.disable()        |  No parameter. Module disable.
---------------------------------------------------------------------------------

3、测试代码

(1)基本测试代码

from seekfree               import ENCODER,GPIO,TIMER

encoder1 = ENCODER(2, 1)

n = 0
flag = 0
def time1_callback(s):
    global n, flag

    n = encoder1.value()
    encoder1.reset()
    flag = 1

time1 = TIMER(500)
time1.callback(time1_callback)

while True:
    if flag:
        flag = 0
        print(n)

(2)交互测试代码

from seekfree               import ENCODER,GPIO,TIMER,UART

encoder1 = ENCODER(2, 1)

n = 0
flag = 0

uart1 = UART(115200)

def time1_callback(s):
    global n, flag

    n = encoder1.value()
    encoder1.reset()
    flag = 1

time1 = TIMER(100)
time1.callback(time1_callback)

while True:
    if uart1.any() >= 1:
        strread = uart1.read()
        print('%c'%0)
        print(n)

4、不同电压对应不同的速度

对于待测的电机施加不同的电压,测量对应的编码器读出的速度信号。

from headm import *
from tsmodule.tsvisa        import *
from tsmodule.tsstm32       import *

data = stm32data()

dh1766volt(0)
time.sleep(5)

vdim = linspace(0, 12, 100)
sdim = []

for v in vdim:
    dh1766volt(v)
    time.sleep(.5)
    data = stm32data()[0]

    printff(v, data)
    sdim.append(data)

    tspsave('measure', vdim=vdim, sdim=sdim)

plt.plot(vdim, sdim)
plt.xlabel("Voltage(V)")
plt.ylabel("Speed")
plt.grid(True)
plt.tight_layout()
plt.show()

▲ 图2.5.7 不同的电压对应的不同的速度

▲ 图2.5.7 不同的电压对应的不同的速度

5、测定转速比

▲ 图2.5.9  测量电机输出轴的转速

▲ 图2.5.9 测量电机输出轴的转速

▲ 图2.5.10 HALL输出波形

▲ 图2.5.10 HALL输出波形

测量输出轴HALL磁场强度变化频率:6.15Hz。

测量电机的HALL输出脉冲频率:2.216kHz。

因此,脉冲个数与输出轴自转一周的比值: 2.216 6.15 = 360.3 {{2.216} \over {6.15}} = 360.3 6.152.216=360.3

▲ 图2.5.11 电机HALL输出波形

▲ 图2.5.11 电机HALL输出波形

 

试总结 ※


  对于来自于逐飞的MM32 MicroPython 的测试电路板进行附加的测试。除了Encoder之外,其它的模块都相对工作正常。

  到现在为止的测试,可以看到该移植版本还存在一下待确定的问题:

  • 直接在MicroPython环境内对于SD卡文件进行操作;
  • 进行浮点数、MATH相关的函数;
  • 对于MCU中的SPI,I2C,CAN,内部FLASH操作还缺乏支持;
  • 缺少对于MCU内的寄存器直接访问,这样可以在除了支持功能之外,添加其它附加功能;


■ 相关文献链接:

● 相关图表链接: