MicroPython内核开发笔记书内软件用例 :基于 print的程序调试
Posted 卓晴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MicroPython内核开发笔记书内软件用例 :基于 print的程序调试相关的知识,希望对你有一定的参考价值。
简 介: 本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的第四章软件用例部分内容。
关键词
: MicroPython,MM32F3277,print
- 本书稿内容隶属于 MicroPython内核开发笔记:书内嵌入实验任务 中的内容。
§01 书稿内容
一、基本实验
在嵌入式软件开发中,下载-测试模式是常用的软件开发方法。首先软件从最简单功能编写完成,然后下载测试,如果功能正常,然后在继续增加软件功能,直道软件开发完毕。使用 print 函数在软件关键节点输出信息是判断软件是否运行正常,检查软件运行状态常用到的方法。除此之外,也可以利用嵌入式开发板上其他信息输出资源,比如 LED、LCD 、DAC 端口等来测试程序是否运行正常。
在 MicroPython 软件开发中,使用 print, dir 命令可以帮助我们查看对象属性以及可以使用的函数。 比如:
from machine import Pin,UART
import machine
import time
print(Pin(1))
print(UART(1))
dir(machine)
dir(time)
上面代码运行可以获得 Pin(1),UART(1) 对应的管脚资源,获得 machine, time 中可以使用的函数。下面是程序运行对应的输出。
Pin(PE3)
UART(1): baudrate=9600 on RX(PA3), TX(PA2)
['__name__', 'sleep', 'sleep_ms', 'sleep_us', 'ticks_add', 'ticks_cpu', 'ticks_diff', 'ticks_ms', 'ticks_us']
['__name__', 'ADC', 'DAC', 'I2C', 'PWM', 'Pin', 'SDCard', 'SPI', 'SoftI2C', 'SoftSPI', 'Timer', 'UART', 'freq', 'mem16', 'mem32', 'mem8', 'reset']
利用 print 可以查看变量内容以及输出计算结果。 比如下面小程序可以输出列表 a 的内容以及打印出 杨辉三角形的阵列。
a = list(range(10))
print(a)
b = [1]
for i in range(10):
strout = ' '.join([str(s) for s in b])
print(' '*((32-len(strout))//2) + strout)
b = [1] + [b[n]+b[n+1] for n in range(len(b)-1)] + [1]
程序运行的结果如下:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
二、获得用户输入
1、存在的问题
MicroPython 利用 REPL 开发机制,也体现了这种交互式开发的特点。巧妙利用 REPL 建立程序与外部练习,可以加快程序的开发。
程序使用 print 函数可以输出信息,但如果希望获得用户通过 REPL 输入的信息则需要另外的方案。REPL 通常情况下使用了单片机硬件 UART0,最直接的想法就是通过 UART0 读取用户通过 REPL 发送的字符。但很遗憾,MicroPython屏蔽了 UART0 的 read 命令。
比如下面程序演示了通过 UART0 读取用户输入字符的过程。
from machine import UART,Pin
import time
uart0 = UART(0,115200)
print(uart0)
dir(uart0)
while True:
if uart0.any() > 0:
inb = uart0.read(uart0.any())
print(inb)
time.sleep_ms(200)
下面是程序执行时输出信息。当用户在 REPL 交互窗口中键入任何字符,程序判断 uart0 存在可以接收的字符,执行后面的 read 语句时,可以看到出现 OSError : UART(0) can’t read 的错误提示。
UART(0): baudrate=115200 on RX(PA10), TX(PA9)
['__next__', 'any', 'read', 'readinto', 'readline', 'write', 'PARITY_EVEN', 'PARITY_NONE', 'PARITY_ODD', 'init']
Traceback (most recent call last):
File "<stdin>", line 19, in <module>
OSError: UART(0) can't read
>>>
2、解决的方法
解决 MicroPython 内核禁止读取 UART0 的问题,可以使用 MicroPython 中的内存直接访问函数 mem32,mem16,mem8。关于 MicroPython 内存直接访问将会在后面第十七章专门进行讲述。下面给出基于 mem32 读取用户 REPL 输入信息的方法。
下面程序中使用 mem32 直接访问 UART1_RDR,可以读取当前输入的字符,然后利用 init 函数对串口重新进行初始化。主程序通过循环调用 procREPL 函数,读取用户通过 REPL 串口发送的字符串,知道获得回车符 b‘\\r’,便将接收到的字符串使用函数 f(s) 完成处理。
from machine import UART,mem32
from micropython import const
APB2PERIPH_BASE = const(0x40010000)
UART1_BASE = const(APB2PERIPH_BASE + 0x3800)
UART1_RDR = const(UART1_BASE + 1*4)
UART1_CSR = const(UART1_BASE + 2*4)
uart0 = UART(0, 115200)
replbuf = bytes(0)
def procREPL(f):
global replbuf
if uart0.any() > 0:
replbuf += bytes([mem32[UART1_RDR]])
uart0.init(115200)
if replbuf[-1:] == b'\\r':
f(replbuf[:-1])
replbuf = bytes(0)
def f(s):
print(s)
while True:
procREPL(f)
程序运行后,在 REPL 输入窗口输入任何字符串,按动回车键之后,程序便显示用户刚刚输入的字符串。
b'Test REPL'
b'Hello world.'
基于这个程序框架,可以开发出很多交互式程序应用。
3、控制LED灯
将上面交互代码中间部分修改一下,可以完成用户通过 REPL 输入命令,动态改变 PLUS-F3270 实验板上 三色LED颜色。
代码修改包括:
- 增加了三个 LED 控制端口;
- 在函数 f(s) 中,根据接收到的字符串对应三位数字分别设置三个 LED 的状态;
led1 = Pin('PA1', Pin.OUT_PUSHPULL, value=1)
led2 = Pin('PA2', Pin.OUT_PUSHPULL, value=1)
led3 = Pin('PA3', Pin.OUT_PUSHPULL, value =1)
def f(s):
sn = int(s)
if sn%10 == 1: led1(0)
else: led1(1)
sn //= 10
if sn%10 == 1: led2(0)
else: led2(1)
sn //= 10
if sn%10 == 1: led3(0)
else: led3(1)
程序运行后,用户输入三个数字分别控制三个 LED 点亮状态。 111 表示全部点亮;000 表示全部熄灭;001 表示点亮第一个 LED, 其它功能以此类推。
※ 总 结 ※
本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的第四章软件用例部分内容。
下面是最后一个测试程序的完整代码。
from machine import UART,mem32,Pin
from micropython import const
APB2PERIPH_BASE = const(0x40010000)
UART1_BASE = const(APB2PERIPH_BASE + 0x3800)
UART1_RDR = const(UART1_BASE + 1*4)
UART1_CSR = const(UART1_BASE + 2*4)
uart0 = UART(0, 115200)
replbuf = bytes(0)
def procREPL(f):
global replbuf
if uart0.any() > 0:
replbuf += bytes([mem32[UART1_RDR]])
uart0.init(115200)
if replbuf[-1:] == b'\\r':
f(replbuf[:-1])
replbuf = bytes(0)
led1 = Pin('PA1', Pin.OUT_PUSHPULL, value=1)
led2 = Pin('PA2', Pin.OUT_PUSHPULL, value=1)
led3 = Pin('PA3', Pin.OUT_PUSHPULL, value =1)
def f(s):
sn = int(s)
if sn%10 == 1: led1(0)
else: led1(1)
sn //= 10
if sn%10 == 1: led2(0)
else: led2(1)
sn //= 10
if sn%10 == 1: led3(0)
else: led3(1)
while True:
procREPL(f)
■ 相关文献链接:
以上是关于MicroPython内核开发笔记书内软件用例 :基于 print的程序调试的主要内容,如果未能解决你的问题,请参考以下文章
MicroPython内核开发笔记书内软件用例 :MEM相关实验用例
MicroPython内核开发笔记书内软件用例 :浮点数相关实验
MicroPython内核开发笔记书内软件用例 :DAC相关实验
MicroPython内核开发笔记书内软件用例 :Timer相关实验