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

简 介: 本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的 mem32 软件用例部分内容。

关键词 MicroPythonMM32F3277mem32

书稿内容
目 录
Contents
模拟比较器模块
改变PWM频率精度
PWM频率误差补偿
总 结

§01 稿内容


利用 MicroPython 中一组可以直接访问 MCU 内存的函数,mem8、mem16、mem32,可以分别按4字节、2字节、1字节访问内存空间。 MCU 中的绝大多数功能模块所对应的控制寄存器都分布在 ARM 内核存储空间里,因此 借助于这组内存访问函数,不仅可以直接绕过 MicroPython 内核对MCU进行操作,提高软件运行速度,更重要的是,能够实现在 MicroPython内核中尚不具备的功能,或者部分功能存在缺陷需要修正。

下面通过一些具体示例来展示这方面的应用。

一、模拟比较器模块

在 MM32F3277 内核中,具有两个 模拟比较器:COMP1,COMP2,它们挂载在内部 APB2 总线上。

▲ 图1.1.1  MM32F3277 内部功能模块以及访问总线

▲ 图1.1.1 MM32F3277 内部功能模块以及访问总线

在现在的 MicroPython 内核中,并没有将模拟比较器的相关功能实现。可以通过 mem32 函数来对模拟比较器进行初始化,并读取比较器输出状态。

1、初始化模拟比较器

模拟比较器挂载在 APB2总线上,在使用之前,需要通过RCC控制器使能COMP1,COMP2的时钟。

下面代码是通过 APB2寄存器使能 模拟比较器时钟。

RCC_BASE    = const(0x40021000)
APB2ENR     = const(RCC_BASE+11*4)
APB1ENR     = const(RCC_BASE+12*4)

mem32[APB2ENR] |= 0x8000

根据 MM32F3277 数据手册,查到模拟比较器对应的控制器存内部功能定义。具体如下图所示。
▲ 图1.1.2  模拟比较器的控制寄存器

▲ 图1.1.2 模拟比较器的控制寄存器

通过改变该寄存器设置,可以选择模拟比较器的输入管脚,输出管脚,以及工作模式。详细情况可以参见MM32F3277数据手册。 模拟比较器的输出(OUT)位于比较控制寄存器的第30位。

下面代码使能 COMP1,2。

COMP_BASE = const(0x40014000)
COMP_CSR1 = const(COMP_BASE+0xc)
COMP_CSR2 = const(COMP_BASE+0x10)
COMP_CRV  = const(COMP_BASE+0x18)
COMP_POLL1 = const(COMP_BASE+0x1c)
COMP_POLL2 = const(COMP_BASE+0x20)
mem32[COMP_CSR1] |= 0x1
mem32[COMP_CSR2] |= 0x1

2、测试模拟比较器

根据上面设置,两个模拟比较器的输入分别为 PA0(正向输入端)、PA4(反向输入端)。 通过以下代码可以查看两个比较器的输出。

print('%08x'%mem32[COMP_CSR1])
print('%08x'%mem32[COMP_CSR2])

设置 PA0 为高电平, PA4 为低电平。查看比较器的输出为:

40000001
40000001

可以看到结果中 30 位是 1,表示比较器输出高电平。

设置 PA0 为低电平,PA4为高电平。查看比较器的输出为:

00000001
00000001

结果中的 30位是0, 比较比较器输出为低电平。可以看到 CSR 中的 OUT 位置反映了外部电压比较的结果。

上面给出了通过 mem32 直接访问单片机模拟比较器控制寄存器,实现比较器工作的方法。大家也可以进一步研究 MM32F3277 数据手册,开发模拟比较器的新的使用方法。

二、改变PWM频率精度

1、PWM信号频率误差

在当前 MicroPython 中 PWM功能实现中,存在一个缺点,那就是 PWM 频率精度会出现比较大的误差。其中的原因就是 PWM 定时器的 ARR 被固定在 999,定时器的 CNT 的计数范围是 0 ~ 999。 通过设置 PWM 的 duty 数值,可以使得 PWM 的占空比的变化精度为 1/1000。但这也带来了 PWM 频谱与设置频率之间存在着较大的误差。

下图给出了设置 PWM 的频率从 500 到 2000Hz 之间变化,通过外部频率计实际测量输出信号的频率,它们之间的绝对误差随着设定频率的不同而发生变化。特别是当设定频率越高,可能产生的误差越大。

▲ 图1.2.1  PWM信号频率误差随着频率设定值产生的变化

▲ 图1.2.1 PWM信号频率误差随着频率设定值产生的变化

产生误差的原因来自于 PWM 定时器中的分配计数器只能取整数。 假设单片机定时器的工作频率来自于 MCU 主频,对应频率为 f o s c = 120 M H z f_{osc} = 120MHz fosc=120MHz 。对于 A R R = 999 ARR = 999 ARR=999 ,PWM 的频率是由 TIM3/TIM4 预分频计数器的数值决定。 f P W M = f o s c ( 1 + P S C ) ⋅ ( A R R + 1 ) f_{PWM} = { {f_{osc} } \over {\left( {1 + PSC} \right) \cdot \left( {ARR + 1} \right)}} fPWM=(1+PSC)(ARR+1)fosc 由于 PSC 必须采用整数,所以对应输出 f P W M f_{PWM} fPWM 会存在一定的误差。

三、PWM频率误差补偿

如果针对 PWM 频率误差,同时调整 ARR 的取值,使其能够补偿由于 PSC 取整所带来的的误差。下面代码利用了 mem32 函数直接对定时器中的 ARR 进行修改,使其补偿频率误差。

#------------------------------------------------------------
from micropython            import const
APB1PERIPH_BASE = const(0x40000000)
TIM3_BASE       = const(APB1PERIPH_BASE + 0x0400)
TIM4_BASE       = const(APB1PERIPH_BASE + 0x0800)
TIM_TYPE_CR1    = const(0*4)
TIM_TYPE_CR2    = const(1*4)
TIM_TYPE_SR     = const(4*4)
TIM_TYPE_CNT    = const(9*4)
TIM_TYPE_PSC    = const(10*4)
TIM_TYPE_ARR    = const(11*4)
TIM_TYPE_CCR1   = const(13*4)
TIM_TYPE_CCR2   = const(14*4)
TIM_TYPE_CCR3   = const(15*4)
TIM_TYPE_CCR4   = const(16*4)

def pwmFreq(f, pwm):
    fosc = 96e6
    psc = int(fosc/f/1000) - 1
    arr = int(fosc/(1+psc)/f) - 1

    if pwm < 4: base = TIM3_BASE
    else: base = TIM4_BASE

    mem32[base+TIM_TYPE_PSC] = psc
    mem32[base+TIM_TYPE_ARR] = arr

    return arr

经过实际测量,PWM 的输出频率与设定频率之间的误差基本上在 0.1% 左右,这就极大提高的 PWM 频率的精度。

  结 ※


本文给出了 MicroPython内核开发笔记:书内嵌入实验任务 中的 mem32 软件用例部分内容。


■ 相关文献链接:

● 相关图表链接:

猜你喜欢

转载自blog.csdn.net/zhuoqingjoking97298/article/details/125566164