测试逐飞的MM32F3277 MicroPython开发板的基本功能

简 介: 对于给定的MicroPython移植版本进行了初步的测试。对比之下,MCU中还有很多的模块尚未支持。这些工作需要近期尽快补充测试完毕。

关键词 MM32MicroPython

MicroPython开发
目 录
Contents
背景介绍
开发板硬件
MicroPython功能
功能测试
GPIO测试
ADC测试
PWM测试
Timer测试
测试总结

 

§01 MicroPython开发


一、背景介绍

  为了能够在第十七届 全国大学生智能车竞赛 中引入基于 MicroPython 开发模式,适合非电子专业背景的同学能够参与智能车竞赛的锻炼。实际上在之前比赛中,基于NXP的OpenMV,OpenART模块都以及采用了MicroPython开发模式,只是这些模块还无法提供更多的端口来满足智能车竞赛车模作品的开发。

1、硬件模块

  下面是逐飞科技提供的基于灵动单片机MM32F3277的开发模块,其中已经初步抑制了MicroPython的环境。

  在 调试来自于逐飞的MM32F3277移植有MicroPython开发板 介绍了该开发板的相关信息,并建立了通过REPL进行交互式开发的工具链。

▲ 图1.1.1  逐飞寄送过来的基本模块

▲ 图1.1.1 逐飞寄送过来的基本模块

2、开发模式

  利用 STM32 Bootloader 软件组成MicroPython的REPL交互式界面,并可以将剪切板上的MicroPython程序下载到MM32进行直接。同时可以将REPL输出的信息进行显示。

二、开发板硬件

1、实验板操作说明

  下面是逐飞科技发送过来关于开发版硬件操作说明。

测试准备:

  连接正常的主板一块,寄过去的板子已接上屏幕并插入SD卡;

▲ 图1.2.1  开发板硬件正面

▲ 图1.2.1 开发板硬件正面

  请使用电池或稳压源从电源线供电,电压为推荐8V(超过6V即可)。
  或者可以使用黑色核心板上Type-C进行供电,但仅使用Type-C进行供电时不可以接入舵机。

▲ 图1.2.2 开发版背后的SD卡槽

▲ 图1.2.2 开发版背后的SD卡槽

  背面是SD卡插座,已接入SD卡,上电默认运行卡内main.py,现象是黑色核心板上LED闪烁。

连接与环境设置:

▲ 图1.2.3 开发板调试端口下载界面

▲ 图1.2.3 开发板调试端口下载界面

  串口连接黑色核心板的下载调试接口的串口,波特率为115200,上电后通过这里进行RPEL交互,需要注意的是,如果SD卡内已有main.py那么会优先运行main.py:

▲ 图1.2.4 串口终端PuTTY界面

▲ 图1.2.4 串口终端PuTTY界面

  此时运行的是SD卡内的main.py文件,我们附带的SD卡中该Python程序不设置退出,所以无法进入RPEL。

  需要将SD卡中main.py删除或者将文件内循环删除,这里我们选择将文件删除,重新插卡并复位:

▲ 图1.2.5 进入REPL进行调试状态

▲ 图1.2.5 进入REPL进行调试状态

  此时进入RPEL,并输出了MicroPython版本。

尝试进行Python语句执行:

  基于附带的示例py文件,可以尝试运行显示效果

▲ 图1.2.6 运行LCD180.help()后的结果

▲ 图1.2.6 运行LCD180.help()后的结果

  运行以上语句,对应会电量LCD屏幕刷新为全屏红色并显示SEEKFREE字样。

2、实验板原理图

  原理可以如下链接下载: MM32F3277主板原理图

(1)核心主板

▲ 图1.2.7 核心主板管脚定义

▲ 图1.2.7 核心主板管脚定义

(2)背板功能定义

▲ 图1.2.8 背板接口定义

▲ 图1.2.8 背板接口定义

(3)背板分电路图

▲ 图1.2.9 5V 电源原理图

▲ 图1.2.9 5V 电源原理图

  电路板上有3个3.3V电源分别提供通用3.3V,摄像头,运放的电源。
▲ 图1.2.10 摄像头3.3V电源

▲ 图1.2.10 摄像头3.3V电源

▲ 图1.2.11 舵机电源

▲ 图1.2.11 舵机电源

▲ 图1.2.12 部分接口管脚定义

▲ 图1.2.12 部分接口管脚定义

▲ 图1.2.13 部分接口管脚定义

▲ 图1.2.13 部分接口管脚定义

▲ 图1.2.14 部分接口管脚定义

▲ 图1.2.14 部分接口管脚定义

三、MicroPython功能

  如下是MM32F3277中已经移植好的MicroPython功能。本文对于这些功能进行初步的测试。
▲ 图1.3.1  现在已经移植好的MicroPython辅助功能

▲ 图1.3.1 现在已经移植好的MicroPython辅助功能

 

§02 能测试


一、GPIO测试

1、GPIO输出

(1)测试代码

from seekfree               import GPIO

pinpg1 = GPIO(0x67, 1, 1)

print("Test GPIO .")
while True:
    pinpg1.low()
    pinpg1.high()

(2)测试结果

  使用示波器测量MM32模块的G7管脚波形。

▲ 图2.1.1 使用示波器测量MM32模块的G7管脚波形

▲ 图2.1.1 使用示波器测量MM32模块的G7管脚波形

▲ 图2.1.2 G7端口输出的波形

▲ 图2.1.2 G7端口输出的波形

  通过上述测试,可以看到MicroPython下对于端口操作的周期大约为:22.28 μ s \mu s μs

  由于上述代码最终是一个死循环,所以需要通过MM32复位才能够从死循环中调出。

(3)修改调试端口

  为了能够从软件上控制MM32复位,在原来调试端口增加NRST控制线。

▲ 图2.1.3 修改调试端口,增加RST控制端口

▲ 图2.1.3 修改调试端口,增加RST控制端口

  对于STM32的MPDLD命令中增加了MM32复位过程。

if(strncmp(szString, "MPDLD", 5) == 0) {   // MicroPython Dlownload
    char szString[0x8000];

    strcpy(szString, "");
    Clipboard()->GetTextBuf(szString, sizeof(szString) - 1);

    ClearInfor();
    ShowInfor("Reset MicroPython...");
    RTSEnable(1, PORT1);
    Sleep(100);
    ClearPort(PORT1);
    RTSEnable(0, PORT1);

    ShowInfor("Wait for MicroPython comeback...");
    double lfStart = GetDosTime();
    int nGreatCount = 0;
    int nGreatFlag = 0;
    for(;;) {
        if(GetDosTime() - lfStart > 2) break;
        char c;
        if(ReceChar(&c, PORT1) == 0) {
            if(c == '>') nGreatCount ++;
            if(c == ' ') {
                if(nGreatCount >= 3) {
                    nGreatFlag = 1;
                    break;
                }
            }
        }
    }

    int nLength = strlen(szString);
    int i;

    int nLine = 0;
    for(i = 0; i < nLength; i ++) {
        if(szString[i] == '\r') nLine ++;
    }

    char szTemp[512];
    sprintf(szTemp, "Download MicroPython : %d lines/%d characters.", nLine, nLength);
    ShowInfor(szTemp);
    ShowInfor("Begin to download programm...");
    Sleep(200);

    if(nGreatFlag == 0) {
        MessageBeep(0);
        SendChar(0x2, PORT1);       // Send CTRL+B
        Sleep(100);
    }
    SendChar(0x5, PORT1);       // Send CTRL+A
    Sleep(100);

    for(i = 0; i < nLength; i ++) {
        ProgressBar1->Position = (i + 1) * 100 / nLength;
        SendChar(szString[i], PORT1);
    }

    for(;;) {
        char c;
        if(ReceCharL(&c, PORT1, 20) > 0) break;
    }

    ShowInfor("-------------------------------------------------------------------------");
    SendChar(0x4, PORT1);      // Send CTRL+B

    return;
}

  修改完之后,对于循环程序,也可以很方便自动下载程序了。

(4)测试toggle
from seekfree               import GPIO

pinpg1 = GPIO(0x67, 1, 1)

print("Test GPIO .")
while True:

    pinpg1.toggle()

▲ 图2.1.4 toggle()函数对应的输出波形

▲ 图2.1.4 toggle()函数对应的输出波形

  从上述波形来看, toggle( )运行时间稍微比low(), high()慢一些。

2、LED

  现在模块中居然没有time模块,这个模块可以提供延时操作。因此,只能够通过软件延时来实现间隔。

  将无线串口HEADER中的C6,C7,GND,+5V引出,测试GPIO输出控制LED。

from seekfree               import GPIO

led1 = GPIO(0x26, 1, 1)
led2 = GPIO(0x27, 1, 0)

print('Test LED.')

while True:

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

    led1.high()
    led2.low()
    delay(20000)
    led1.low()
    led2.high()
    delay(20000)

▲ 图2.1.5  LED延时闪烁

▲ 图2.1.5 LED延时闪烁

3、测试按钮

▲ 图2.1.6  电路板上的按键与开关

▲ 图2.1.6 电路板上的按键与开关

(1)硬件

  根据前面硬件电路图所示,电路板上集成了四个按键:G0,G1,G2,G3。它们对应的端口为:GPIOG0, G1,G2,G3。

▲ 图2.1.7 开发板上的四个按键

▲ 图2.1.7 开发板上的四个按键

(2)测试软件
from seekfree               import GPIO

led1 = GPIO(0x26, 1, 1)
led2 = GPIO(0x27, 1, 0)

btn1 = GPIO(0x60, 0, 1)
btn2 = GPIO(0x61, 0, 1)
btn3 = GPIO(0x62, 0, 1)
btn4 = GPIO(0x63, 0, 1)

print('Test LED.')

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

while True:
    print([btn1.value(), btn2.value(), btn3.value(), btn4.value()])
    delay(50000)

4、测试拨码开关

  电路板上还有两个拨码开关,分别对应的D14,D15。通过GPIO可以读出它们的状态。测试的方式与上面按键相同。

from seekfree               import GPIO

print('Test LED.')
def delay(loop=50000):
    for _ in range(loop):
        pass

led1 = GPIO(0x26, 1, 1)
led2 = GPIO(0x27, 1, 0)

btn1 = GPIO(0x60, 0, 1)
btn2 = GPIO(0x61, 0, 1)
btn3 = GPIO(0x62, 0, 1)
btn4 = GPIO(0x63, 0, 1)

sw1 = GPIO(0x3e, 0, 1)
sw2 = GPIO(0x3f, 0, 1)

while True:
    print([btn1.value(), btn2.value(), btn3.value(), btn4.value(), sw1.value(), sw2.value()])
    delay(50000)

▲ 图2.1.8  测量按键与拨码开关

▲ 图2.1.8 测量按键与拨码开关

二、ADC测试

1、ADC.help()

▲ 图2.2.1 ADC.help() 显示信息

▲ 图2.2.1 ADC.help() 显示信息

2、adc.value()

  将电磁模块接口的引到面包板上,利用电位器获得不同的电压,发送到A4。

▲ 图2.2.2 采集到1024 个ADC数值

▲ 图2.2.2 采集到1024 个ADC数值

  数据的方差: 5。

  由于MicroPython不支持浮点运算。所以需要采用整形数完成相关的计算。

from seekfree               import ADC,GPIO

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

print('Test ADC.')

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

def sqrt(x):
    left = 0
    right = x//2+1
    while left < right:
        middle = left + (right-left+1)//2
        square = middle * middle

        if square > x:
            right = middle-1
        else: left = middle

    return left

SAMPLE_NUM = 1024
adcdim = [0]*SAMPLE_NUM

for i in range(SAMPLE_NUM):
    adcdim[i] = adc.value(adc.A4)

print(adcdim)

count = 0
for s in adcdim:
    count += s

average = count//SAMPLE_NUM

sigma = 0
for s in adcdim:
    ss = s - average
    sigma += ss**2

print(sqrt(sigma//SAMPLE_NUM))

三、PWM测试

  测试版上的PWM分别通过A0,A1,A2,A3输出。

1、基本测试

from seekfree               import PWM,GPIO

pwm = PWM(16000)
pwm.channel_init(pwm.A0, 5000)

print("Test PWM")
  • duty = 5000
    ▲ 图2.3.1 A0输出PWM波形
    ▲ 图2.3.1 A0输出PWM波形
  • duty = 500

▲ 图2.3.2 A0输出PWM波形

▲ 图2.3.2 A0输出PWM波形

2、利用ADC改变PWM

from seekfree               import PWM,GPIO,ADC

pwm = PWM(16000)
pwm.channel_init(pwm.A0, 500)

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

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

print('Test PWM...')
while True:
    adcvalue = adc.value(adc.A4)
    pwmvalue = adcvalue*10000//0x1000
    print(adcvalue, pwmvalue)
    pwm.duty(pwm.A0, pwmvalue)

    delay(10000)

▲ 图2.3.3  抖动的PWM

▲ 图2.3.3 抖动的PWM

  通过对采集到ADC进行平均之后,在控制PWM,波形就非常稳定了。

from seekfree               import PWM,GPIO,ADC

pwm = PWM(16000)
pwm.channel_init(pwm.A0, 5000)

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

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

print('Test PWM...')

while True:

    sigma = 0
    for i in range(256):
        sigma  += adc.value(adc.A4)

    adcvalue = sigma//256
    pwmvalue = adcvalue*10000//0x1000

    pwm.duty(pwm.A0, pwmvalue)

    delay(1000)

▲ 图2.3.4  通过ADC改变PWM占空比

▲ 图2.3.4 通过ADC改变PWM占空比

四、Timer测试

1、基本测试

  设置定时器的回调函数。

from seekfree               import TIMER,GPIO

led1 = GPIO(0x26, 1, 1)
led2 = GPIO(0x27, 1, 0)

def timer_callback(s):
    led1.toggle()
    print(s.count())

tim = TIMER(200)
tim.callback(timer_callback)

while True:
    pass

 

试总结 ※


  于MM32的MicroPython移植版本进行了初步的测试。也能够看到这个版本的移植工作还需要一定的丰富。

  • 缺少对于SPI, I2C,CAN总线的支持。
  • 缺少对于浮点数运算的支持;
  • 缺少对于SD卡文件访问支持;

  上述功能需要通过后期的补充进一步改善。


■ 相关文献链接:

● 相关图表链接:

  • 10
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卓晴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值