创客百科

姿势共享,有节操无门槛参与的创客百科,创客动力之源 \ (^_^) /

用户工具

站点工具


pyboard:tutorial:assembler

这是本文档旧的修订版!


A PCRE internal error occured. This might be caused by a faulty plugin

====== 内联汇编 ====== 此章节中,您将学习如何在MicroPython中写入内联汇编。 **Note**: 此章节是为已对微控制器和汇编语言有所了解的用户的进阶级教程。 MicroPython可以内联汇编,其允许您将汇编程序作为Python函数写入,其命名方式类似于常规Python函数的命名。 ===== 返回一个值 ===== 内联汇编函数由一个特殊的函数装饰器表示。我们从最简单的示例开始: <code> @micropython.asm_thumb def fun(): movw(r0, 42) </code> 您可在脚本或REPL中键入此。此函数无需任何参数,并返回数字42。 ''%%r0%%'' 为一个寄存器,且函数返回的此寄存器中的值即为返回值。 MicroPython通常将 ''%%r0%%'' 解译为一个整数,并为调用方将其转换为一个整数对象。 若您运行 ''%%print(fun())%%'' ,您将看到其打印出42。 ===== 访问外设 ===== 对于略微复杂的内容,我们先打开一个LED: <code> @micropython.asm_thumb def led_on(): movwt(r0, stm.GPIOA) movw(r1, 1 << 13) strh(r1, [r0, stm.GPIO_BSRRL]) </code> 这一代码使用了一些新概念: <HTML><blockquote> * ''%%stm%%'' 是一个为轻松访问pyboard的微控制器的寄存器提供了一系列常量的模块。 尝试运行''%%import stm%%'' ,然后在REPL中 运行 ''%%help(stm)%%'' 。其功能为提供所有可用常量的列表。 * ''%%stm.GPIOA%%'' 是GPIOA外设的地址。在pyboard中,红色LED在端口A、引脚PA13。 * ''%%movwt%%'' 将一个32位的数字移入寄存器。 这是一个可轻松转换为2个thumb指令的函数:先是 ''%%movw%%'' , 然后是 ''%%movt%%''. ''%%movt%%'' 也会将当前值右移16位。 * ''%%strh%%'' 储存了一个半字(16位)。 上述指令将 ''%%r1%%'' 较低的16位存入内存中的 ''%%r0 + stm.GPIO_BSRRL%%'' 位置。其作用为将所有端口A上的引脚设置为高, 即 ''%%r0%%'' 中的相应位所设置的。在上述示例中, ''%%r0%%'' 中的第13位已设置,因此PA13被拉高。这就点亮了红色LED。 </blockquote></HTML> ===== 接受参数 ===== 内联汇编函数可接受多达4个参数。若使用这4个参数,则须将之命名为 ''%%r0%%'', ''%%r1%%'', ''%%r2%%'' 和 ''%%r3%%'' ,以反映寄存器和调用惯例。 这是一个添加参数的函数: <code> @micropython.asm_thumb def asm_add(r0, r1): add(r0, r0, r1) </code> 此即执行计算 ''%%r0 = r0 + r1%%''。由于结果 写作 ''%%r0%%'',此即返回的结果。尝试 ''%%asm_add(1, 2)%%'',其应返回3。 ====== 循环 ====== 我们可用 ''%%label(my_label)%%'' 为标签赋值,并使用 ''%%b(my_label)%%'' 或 类似于 ''%%bgt(my_label)%%'' 的条件分支将其分化为支。 以下示例使绿色LED闪烁 ''%%r0%%'' 次。 : <code> @micropython.asm_thumb def flash_led(r0): # get the GPIOA address in r1 获取r1中的GPIOA地址 movwt(r1, stm.GPIOA) # get the bit mask for PA14 (the pin LED #2 is on) 获取PA14的位掩码(LED #2所在的引脚) movw(r2, 1 << 14) b(loop_entry) label(loop1) # turn LED on 开启LED strh(r2, [r1, stm.GPIO_BSRRL]) # delay for a bit movwt(r4, 5599900) label(delay_on) sub(r4, r4, 1) cmp(r4, 0) bgt(delay_on) # turn LED off strh(r2, [r1, stm.GPIO_BSRRH]) # delay for a bit 延迟1位 movwt(r4, 5599900) label(delay_off) sub(r4, r4, 1) cmp(r4, 0) bgt(delay_off) # loop r0 times sub(r0, r0, 1) label(loop_entry) cmp(r0, 0) bgt(loop1) </code>

本页面的其他翻译:
pyboard/tutorial/assembler.1548930319.txt.gz · 最后更改: 2019/01/31 18:25 (外部编辑)