利用mem数组完成MicroPython中UART1的(REPL)的交互

Posted 卓晴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用mem数组完成MicroPython中UART1的(REPL)的交互相关的知识,希望对你有一定的参考价值。

简 介: 利用了UART中的CSR的RXVAL标志位,可以判断有新的byte从REPL中获得,通过查询该标志位,可以实现通过REPL(UART1)上位机发送的信息。进而可以提高软件调试效率。

关键词 memREPLRXVAL

mem访问REPL
文章目录
基本想法
初步测试
UART1的交互
测试其他模块
测试APA102C
测试DAC
测试总结

§01 mem访问REPL


   通过mem函数在MicroPython中访问模块寄存器 可以实现对UART1,也就是用于MicroPython REPL 的串口输入的访问,但很可惜,无法对于发送过来的字符进行同步。下面希望通过特殊的交换协议来完成对于UART的输入信息的读取同步。

一、基本想法

  由于无法确定现在UART1的输入寄存器是否被更新,所以可以采用一下两个方式:

  • 第一个方式,就是把读入的UART1的接收寄存器修改成与当前值不同的数据,后面在进行判断;
  • 第二中方式,就是使用特殊的分隔符号,比如0x0,作为分隔符号,没两次0x0之间为新的数据;
  • 第三种方式:通过UART_CSR,当前状态寄存器来确定是否接收到了字符。

  由于在MicroPython中最快的轮询的时间间隔为1ms,所以对于从PC发送的机制,也需要保证每个字符之间的时间间隔大于1ms。

二、初步测试

1、测试修改UART1接收寄存器

(1)测试代码

from machine                import Pin,mem32
import utime
from micropython            import const

APB2PERIPH_BASE = const(0x40010000)
APB1PERIPH_BASE = const(0x40000000)

UART1_BASE    = const(APB2PERIPH_BASE + 0x3800)
UART1_RDR       = const(UART1_BASE + 1*4)

print("Test UART.")

mem32[UART1_RDR] = 0xff

while True:
    mem32[UART1_RDR] = 0xff
    print("%08x"%mem32[UART1_RDR])
    utime.sleep_ms(250)

(2)测试结果

  读取的mem32[UART1_RDR] 仍然是 0x4,与写入的字符无关。因此可以知道,UART1的RDR是无法被改写的。

  下面是数据手册中表明RXREG为只读。

▲ 图1.2.1 MM32F3277的UART 的 RDR为只读

2、测试CSR寄存器

  利用UART_CSR中的RXAVL来判断是否接收到字符。

▲ 图1.2.2 MM32F3277 UART_CSR功能定义

(1)测试代码

from machine                import Pin,mem32
import utime
from micropython            import const

APB2PERIPH_BASE = const(0x40010000)
APB1PERIPH_BASE = const(0x40000000)

UART1_BASE    = const(APB2PERIPH_BASE + 0x3800)
UART1_RDR     = const(UART1_BASE + 1*4)
UART1_CSR     = const(UART1_BASE + 2*4)

print("Test UART.")

mem32[UART1_RDR] = 0xff

while True:

    if (mem32[UART1_CSR] & 0x2):
        print("%c"%mem32[UART1_RDR])
    utime.sleep_ms(10)

(2)测试结果

▲ 图1.2.3 可以接收到字符

三、UART1的交互

1、交互程序

  下面是交互程序,是将UART1接收到的字符转换成整型数字显示出来。

from machine                import Pin,mem32
import utime
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)

print("Test UART.")

replbuf = bytes(0)
def procREPL():
    global replbuf

    if mem32[UART1_CSR] & 0x2:
        replbuf += bytes([mem32[UART1_RDR]])

        if replbuf[-1:] == b'\\r':
            print(int(replbuf[:-1]))

            replbuf = bytes(0)

while True:
    procREPL()
    utime.sleep_ms(10)

  测试结果,上述命令是可以正常运行。

2、改在STM32 Bootloader

  由于在MicroPython中对于UART1的轮询最快是1ms,所以在STM32 Bootloader中增加一个发送字符间隔为1ms的命令。

(1)增加SNDCD命令

if(strncmp(szString, "SNDCD", 5) == 0) 
    int nLength = strlen(szString);
    int i;
    for(i = 5; i < nLength; i ++) 
        SendChar(szString[i], PORT1);
        Sleep(1);
    

    return;

(2)测试SNDCD

Ⅰ.MicroPython程序
#------------------------------------------------------------
replbuf = bytes(0)
def procREPL():
    global replbuf

    if mem32[UART1_CSR] & 0x2:
        replbuf += bytes([mem32[UART1_RDR]])

        if replbuf[-1:] == b'\\r':
            print(int(replbuf[:-1]))

            replbuf = bytes(0)

#------------------------------------------------------------
while True:
    procREPL()
    utime.sleep_ms(1)
Ⅱ.测试结果
  • 使用"SENDC100\\r" 无法获得结果;
  • 使用“SNDCD100\\r” 可以正常显示100的结果。

3、加快轮询

  如果在 while程序中,将1ms的等待去除,可以加快轮询的速度。

while True:
    procREPL()
#    utime.sleep_ms(1)

  通过测试可以看到无论使用 “SENDC”,还是“SNDCD”命令,都可以正常获得测试结果。

 

§02 试其他模块


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)

replbuf = bytes(0)
def procREPL(f):
    global replbuf

    if mem32[UART1_CSR] & 0x2:
        replbuf += bytes([mem32[UART1_RDR]])

        if replbuf[-1:] == b'\\r':
            f(replbuf[:-1])
            replbuf = bytes(0)

def f(s):
    print(s)

while True:
    procREPL(f)

一、测试APA102C

1、MicroPython程序

from machine                import UART,mem32,SPI
from micropython            import const

from machine                import Pin,SPI
import utime

spi = SPI(0, baudrate=100000, polarity=1, phase=1)
led = Pin('PB2', Pin.OUT_PUSHPULL)

def led3buf(l1,l2,l3):
    '''
    led3buf: Construct three APA102C LED data
    Param l1: LED 1 (rgb)
    Param l2: LED 2 (rgb)
    Param l3: LED 3 (rgb)
    Return: buf : 8+4*3=20bytess
    '''
    return bytes([0]*4) + bytes((0xff,l1[2],l1[1],l1[0])) + bytes((0xff,l2[2],l2[1],l2[0])) + bytes((0xff,l3[2],l3[1],l3[0])) + bytes([0xff]*4)

def led3light(l1,l2,l3):
    return bytes([0]*4) + bytes((0xff,0, 0, l1)) + bytes((0xff,0,l2, 0)) + bytes((0xff,l3,0,0)) + bytes([0xff]*4)

APB2PERIPH_BASE = const(0x40010000)
UART1_BASE    = const(APB2PERIPH_BASE + 0x3800)
UART1_RDR     = const(UART1_BASE + 1*4)
UART1_CSR     = const(UART1_BASE + 2*4)

replbuf = bytes(0)
def procREPL(f):
    global replbuf

    if mem32[UART1_CSR] & 0x2:
        replbuf += bytes([mem32[UART1_RDR]])

        if replbuf[-1:] == b'\\r':
            f(replbuf[:-1])
            replbuf = bytes(0)

def f(s):
    count1 = int(s)
    if count1 > 255: count1 = 255
    
    count2 = count3 = count1

    print(count1, count2, count3)
    buf = led3light(count1,count2,count3)
    spi.write(buf)

print('Test APA102C.')

while True:
    procREPL(f)

2、Python程序

from headm import *
from tsmodule.tsstm32       import *

count = 0
while True:
    count += 10

    if count >= 255: count = 0
    stm32cmd('SNDCD%d\\r'%count)
    time.sleep(.1)

3、测试结果

▲ 图2.1.1 APA102C变化亮度

二、测试DAC

1、MicroPython程序

from machine                import UART,mem32,DAC
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)

dac0 = DAC(0以上是关于利用mem数组完成MicroPython中UART1的(REPL)的交互的主要内容,如果未能解决你的问题,请参考以下文章

利用mem数组在MM32 MicroPython中实现COMP的功能

MM32F3277 MicroPython的 mem 函数对于MCU内存访问

通过mem32函数来提高MM32 MicroPython 输出PWM 频率的精度

MicroPython+ESP8266:UART串口通信

MicroPython内核开发笔记书内软件用例 :UART相关实验

MicroPython内核开发笔记书内软件用例 :MEM相关实验用例