通过mem函数在MicroPython中访问模块寄存器

举报
tsinghuazhuoqing 发表于 2021/12/25 23:55:33 2021/12/25
【摘要】 简 介: 通过mem函数直接访问MCU内部的寄存器,可以完成一些在原来的MicroPython中内核没有实现的模块。通过测试可以看到,通过mem访问GPIO并没有明显增加访问的速度。使用mem访问C...

简 介: 通过mem函数直接访问MCU内部的寄存器,可以完成一些在原来的MicroPython中内核没有实现的模块。通过测试可以看到,通过mem访问GPIO并没有明显增加访问的速度。使用mem访问CRC,验证了它的工作机制,但对比Online CRC计算结果发现他们之间存在差异。对于UART的访问,可以获得UART1,作为REPL接收可以直接读取来自于RDR中的内容。

关键词 memMM32CRCUART

mem操作模块
文章目录
为什么使用
mem函数?
操作GPIO
CRC计算
基本测试
UART访问
读取UART1接
收数据寄存器
测试总结

 

§01 mem操作模块


一、为什么使用mem函数?

  在博文 MM32F3277 MicroPython的 mem 函数对于MCU内存访问 测试了利用MicroPython中的mem函数直接访问MCU的 Flash, RAM, 内部特殊寄存器等。最初使用mem来直接访问和操作MCU的寄存器的目的是希望能够加快运行。下面将会通过一些特定的实验来检查这方面的差异。

二、操作GPIO

1、使用Pin操作

(1)测试代码

from machine                import Pin,mem32,mem16
import utime

print("Test IO operating.")

pin0 = Pin('PA0', Pin.OUT_PUSHPULL)
led  = Pin('PB2', Pin.OUT_PUSHPULL)

while True:
    pin0(1)
    pin0(0)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

(2)测试结果

  测量PA0的波形如下图所示。 对应的频率为24.31kHz。

▲ 图1.2.1 测量PA0的波形与频率

▲ 图1.2.1 测量PA0的波形与频率

(3)使用函数high,low

  使用high(), low() 函数改变GPIO。

while True:

    pin0.high()
    pin0.low()

  
 
  • 1
  • 2
  • 3
  • 4

  PA0的波形如下图所示。对应的频率为:20.78kHz。
▲ 图1.2.2 测量PA0的波形和频率

▲ 图1.2.2 测量PA0的波形和频率

2、使用mem操作

(1)测试代码

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

print("Test IO operating.")

pin0 = Pin('PA0', Pin.OUT_PUSHPULL)
led  = Pin('PB2', Pin.OUT_PUSHPULL)

AHBPERIPH_BASE  = const(0x40020000)

GPIOA_BASE    = const(AHBPERIPH_BASE + 0x0020000)
GPIOB_BASE    = const(AHBPERIPH_BASE + 0x0020400)
GPIOC_BASE    = const(AHBPERIPH_BASE + 0x0020800)
GPIOD_BASE    = const(AHBPERIPH_BASE + 0x0020C00)
GPIOE_BASE    = const(AHBPERIPH_BASE + 0x0021000)
GPIOF_BASE    = const(AHBPERIPH_BASE + 0x0021400)
GPIOG_BASE    = const(AHBPERIPH_BASE + 0x0021800)
GPIOH_BASE    = const(AHBPERIPH_BASE + 0x0021C00)

ODR = const(GPIOA_BASE+3*4)

while True:
    mem32[ODR] ^= 1

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

(2)测试结果

  测试上述操作对应的PA0的输出方波频率:23.54kHz。
▲ 图1.2.3 PA0信号波形与频率

▲ 图1.2.3 PA0信号波形与频率

(3)使用幅值操作GPIO

while True:
    mem32[ODR] = 0
    mem32[ODR] = 1

  
 
  • 1
  • 2
  • 3

  PA0的输出波形与频率如下图所示。
▲ 图1.2.4 PA0的波形与频率

▲ 图1.2.4 PA0的波形与频率

■ 测试结论

  通过上面测试,可以看到使用mem访问GPIO进行操作,实际上比起直接使用Pin的函数并没有快多少。

 

§02 CRC计算


一、基本测试

1、测试程序

from machine                import mem32
import utime
from micropython            import const

AHBPERIPH_BASE  = const(0x40020000)
CRC_BASE        = const(AHBPERIPH_BASE + 0x3000)
CRC_DR      = const(CRC_BASE + 0)   # CRC data register
CRC_IDR     = const(CRC_BASE + 4)   # CRC independent data register
CRC_CR      = const(CRC_BASE + 8)   # CRC control register
CRC_MIR     = const(CRC_BASE + 12)  # Middle data register

RCC_BASE    = const(AHBPERIPH_BASE + 0x1000)
RCC_AHB1    = const(RCC_BASE+10*4)
mem32[RCC_AHB1] |= 0x1000           # Enable CRC clock

mem32[CRC_CR] = 0x1                 # Reset CRC
print('CRC CR: %08x'%mem32[CRC_CR])
print('CRC DR: %08x'%mem32[CRC_DR])

mem32[CRC_DR] = 1
mem32[CRC_DR] = 2
print('CRC DR: %08x'%mem32[CRC_DR])         # Caculate the CRC

mem32[CRC_DR] = mem32[CRC_DR]       # Check CRC
print('CRC DR: %08x'%mem32[CRC_DR])

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

2、测试结果

CRC CR: 00000000
CRC DR: -0000001
CRC DR: 298be7ba
CRC DR: 00000000

  
 
  • 1
  • 2
  • 3
  • 4

  可以看到对于1,2 进行CRC计算之后,如果重新将CRC结果输入到DR,最终可以得到输出的DR为0。

▲ 图2.1.1 CRC 控制寄存器的定义

▲ 图2.1.1 CRC 控制寄存器的定义

  通过测试,发现CRC_BITSEL只能选择00,对应32位,最终的CRC校验才能够归零。至于为什么,现在不清楚。

3、Online CRC计算

  在 CRCCALC 中给出了在线的CRC计算。通过它的计算对比MM32的计算结果。

▲ 图2.1.2 在线Online CRC 计算

▲ 图2.1.2 在线Online CRC 计算

  通过测试,发现通过Online的计算结果与MM32计算的结果没有能够对应上。

  x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1

 

§03 UART访问


  于现在MicroPython不提供对于UART1的接受访问,这个端口用于REPL。 那么是否可以通过mem直接访问呢?

一、读取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)
UART2_BASE    = const(APB1PERIPH_BASE + 0x4400)
UART3_BASE    = const(APB1PERIPH_BASE + 0x4800)
UART4_BASE    = const(APB1PERIPH_BASE + 0x4C00)
UART5_BASE    = const(APB1PERIPH_BASE + 0x5000)
UART6_BASE    = const(APB2PERIPH_BASE + 0x3C00)
UART7_BASE    = const(APB1PERIPH_BASE + 0x7800)
UART8_BASE    = const(APB1PERIPH_BASE + 0x7C00)

UART1_RDR       = const(UART1_BASE + 1*4)

print("Test UART.")

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

  输出的结果为:就是刚刚输入的字符结果。

2、使用UART1

print("Test UART.")

uart1 = UART(0,115200)
print(dir(uart1))

oldany = uart1.any()

while True:
    if uart1.any() != oldany:
        oldany = uart1.any()
        print("%c"%mem32[UART1_RDR])

    utime.sleep_ms(20)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

  通过测试,发现:

  • UART1 无法使用 uart.read() : 这个函数应该放开;
  • UART1只能够接收到有限个字符,希望能够扩展到128个字符。

 

试总结 ※


  过mem函数直接访问MCU内部的寄存器,可以完成一些在原来的MicroPython中内核没有实现的模块。通过测试可以看到,通过mem访问GPIO并没有明显增加访问的速度。使用mem访问CRC,验证了它的工作机制,但对比Online CRC计算结果发现他们之间存在差异。

  对于UART的访问,可以获得UART1,作为REPL接收可以直接读取来自于RDR中的内容。


■ 相关文献链接:

● 相关图表链接:

文章来源: zhuoqing.blog.csdn.net,作者:卓晴,版权归原作者所有,如需转载,请联系作者。

原文链接:zhuoqing.blog.csdn.net/article/details/121704275

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。