在Arduino UNO上运行汇编程序

在Arduino UNO上运行汇编程序

在Microchip Studio中运行Arduino的汇编语言代码,你可以按照以下步骤进行:

  1. 安装和打开Microchip Studio:首先,确保你已经安装了Microchip Studio,这是Microchip提供的集成开发环境,用于嵌入式系统的开发,包括对AVR单片机的支持。

  2. 新建项目:在Microchip Studio中,选择“File”->“New”->“Project”,创建一个新的项目。选择项目类型为“Assembler(汇编)”项目。

  3. 选择设备类型:在新建项目时,选择对应的Arduino板子对应的MCU型号,例如,如果使用的是Arduino Uno R3,那么对应的MCU型号为ATmega328P。

  4. 编写汇编代码:在新建的项目中,将你的汇编代码写入到main.asm文件中。例如,你可以编写控制LED闪烁的汇编代码。

  5. 配置项目:在项目属性中,确保选择了正确的工具链和优化设置。如果需要仿真,还需要设置仿真器。

  6. 编译代码:配置完成后,选择“Build”->“Build Solution”来编译你的汇编代码。编译成功后,会生成HEX文件,这是烧录到Arduino板子上的文件。

  7. 烧录程序:使用AVRDUDE工具将编译生成的HEX文件烧录到Arduino板子上。你可以在Microchip Studio中配置External Tools参数,或者在命令行中使用AVRDUDE命令进行烧录。

  8. 调试和运行:烧录完成后,你可以将Arduino板子连接到计算机,并在Microchip Studio中进行调试和运行。

请注意,这个过程可能需要根据你的具体硬件和软件环境进行适当的调整。确保你的Microchip Studio版本支持你的Arduino板子,并且你有正确的AVRDUDE配置文件和路径设置。

一、AVRDUDE的下载

AVRDUDE(AVR Downloader Uploader)是一个用于下载和上传Microchip的AVR微控制器芯片内存的程序。它可以编程Flash和EEPROM,并且在编程协议支持的情况下,它还可以编程熔丝位和锁定位。AVRDUDE还提供了一个直接指令模式,允许用户向AVR芯片发出任何编程指令,无论AVRDUDE是否实现了某个特定芯片的特定功能。

在https://github.com/avrdudes/avrdude/releases/tag/v8.0中下载AVRDUDE v8.0,下载的文件是avrdude-v8.0-windows-x64.zip,并将其解压。avrdude-v8.0-windows-x64.zip对应的是Windows MSVC 64 bit。

二、配置MicroChip Studio开发环境

Atmel公司被MicroChip公司收购以后,Atmel Studio 就改名为MicroChip Studio软件,在Arduino Uno上配置汇编语言程序运行环境和运行汇编语言程序的过程基本没有什么变化。

1. 在External Tools中配置AVRDUDE运行环境

(1)打开MicroChip Studio软件,然后选择Tools下的External Tools菜单项,如图1所示。 弹出External Tools窗体如图2所示。

在这里插入图片描述

图1 Tools菜单

在这里插入图片描述

图2 External Tools窗体

(2)设置图2中窗体的各项内容如下:

  • Title:Arduino UNO avrdude
  • Command: D:\atmel studio\avrdude-v8.0-windows-x64\avrdude.exe
  • Arguments: -v -P COM3 -c arduino -e -p m328p -U flash:w:$(TargetName).hex
  • Initial Directory: $(TargetDir)

然后,勾选Use Output Window复选框。其中,Command项的设置为下载并解压的avrdude.exe文件所在路径,根据文件解压路径进行修改。Arguments中的各参数如下所示:

  • -v:启用详细输出。
  • -P:连接Arduino Uno的串行端口号(COM端口)
  • -c:编程器硬件类型。
  • -e:在编程之前擦除目标MCU的闪存和EEPROM存储器。 这是强制性的。
  • -p:要编程的器件的短名称
  • -U:memtype:op:filename [:format]:将指定的十六进制文件的内容写入闪存

本例中,“COM3”是Arduino Uno控制器连接到计算机后的COM端口号,可以在设备管理器中查询,如图3所示。

在这里插入图片描述

图3 设备管理器中的COM端口号

设置后的External Tools窗体上的各项内容如图所示。点击OK,保存设置的各项参数。
在这里插入图片描述

图4 Arduino UNO avrdude的配置

(3)设置完成后,打开Tools菜单,则Arduino UNO avrdude出现在菜单中,如图5所示。

在这里插入图片描述

图5 Arduino UNO avrdude在Tools菜单中的位置

(4)运行Arduino UNO avrdude

选择菜单File>New>Project,弹出的窗口中的installed选项下选择Assembler,如图6所示。点击OK按钮,弹出Device Selectin窗体,在Device Family中选择ATmega328P,如图7所示。再点击OK按钮,进入编辑界面。
在这里插入图片描述

图6 新建汇编语言工程窗口

在这里插入图片描述

图7 器件设置为ArduinoUno的ATmega328P控制器

(5)打开Tools菜单,点击Arduino UNO avrdude项,则出现如图所示的提示。

Avrdude version 8.0
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

System wide configuration file is D:\atmel studio\avrdude-v8.0-windows-x64\avrdude.conf

Using port      : COM6
Using programmer   : arduino
AVR part       : ATmega328P
Programming modes   : SPM, ISP, HVPP, debugWIRE
Programmer type    : Arduino
Description      : Arduino bootloader using STK500 v1 protocol
HW Version      : 3
FW Version      : 4.4

AVR device initialized and ready to accept instructions
Device signature = 1E 95 0F (ATmega328P, ATA6614Q, LGT8F328P)
Erased chip
Reading 32 bytes for flash from input file AssemblerApplication4.hex
in 1 section [0, 0x1f]: 1 page and 96 pad bytes
Writing 32 bytes to flash
Writing | ################################################## | 100% 0.04s
Reading | ################################################## | 100% 0.02s
32 bytes of flash verified

Avrdude done. Thank you.

表明avrdude已经配置成功。

二、汇编语言程序的编译和烧录

1. 汇编语言程序的编译

在main.asm中输入如下代码。

main:
  sbi 0x04, 5       ; PORTB5 output
loop:               ; main loop begin
  sbi 0x05, 5       ; PORTB5 high
  call delay_1000ms ; delay 1s
  cbi 0x05, 5       ; 5 PORTB5 low
  call delay_1000ms ; delay 1s
  rjmp  loop        ; main loop

delay_1000ms:       ; subroutine for 1s delay
                    ; initialize counters
  ldi r18, 0xFF     ; 255
  ldi r24, 0xD3     ; 211
  ldi r25, 0x30     ; 48
inner_loop:
  subi  r18, 0x01   ; 1
  sbci  r24, 0x00   ; 0
  sbci  r25, 0x00   ; 0
  brne  inner_loop
  ret

选择“Build”->“Build Solution”来编译你的汇编代码。编译成功后,会生成HEX文件,这是烧录到Arduino板子上的文件。编译结果如图8所示。

在这里插入图片描述

图8 汇编语言编译完成

在output窗口输出如下:

Build started.
Project "AssemblerApplication1.asmproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "D:\atmel studio\7.0\Vs\Assembler.targets" from project "c:\users\78468\Documents\Atmel Studio\7.0\AssemblerApplication1\AssemblerApplication1\AssemblerApplication1.asmproj" (target "Build" depends on it):
	Task "RunAssemblerTask"
		D:\atmel studio\7.0\toolchain\avr8\avrassembler\avrasm2.exe -fI -o "AssemblerApplication1.hex"  -m "AssemblerApplication1.map"  -l "AssemblerApplication1.lss"  -S "AssemblerApplication1.tmp"  -W+ie -I"D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc"  -im328pdef.inc -d "c:\users\78468\Documents\Atmel Studio\7.0\AssemblerApplication1\AssemblerApplication1\Debug\AssemblerApplication1.obj"  "c:\users\78468\Documents\Atmel Studio\7.0\AssemblerApplication1\AssemblerApplication1\main.asm"  -I "D:\atmel studio\7.0\toolchain\avr8\avrassembler\Include" 
		AVRASM: AVR macro assembler 2.2.7 (build 69 Jul 26 2017 16:25:06)
		Copyright (C) 1995-2017 ATMEL Corporation
		[builtin](2): Including file 'D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc'
		[builtin](2): Including file 'D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.3.300\avrasm\inc\m328pdef.inc'
		"ATmega328P" memory use summary [bytes]:
		Segment   Begin    End      Code   Data   Used    Size   Use%
		---------------------------------------------------------------
		[.cseg] 0x000000 0x000020     32      0     32   32768   0.1%
		[.dseg] 0x000100 0x000100      0      0      0    2048   0.0%
		[.eseg] 0x000000 0x000000      0      0      0    1024   0.0%
		Assembly complete, 0 errors. 0 warnings
	Done executing task "RunAssemblerTask".
Done building target "CoreBuild" in project "AssemblerApplication1.asmproj".
Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').
Target "Build" in file "D:\atmel studio\7.0\Vs\Avr.common.targets" from project "c:\users\78468\Documents\Atmel Studio\7.0\AssemblerApplication1\AssemblerApplication1\AssemblerApplication1.asmproj" (entry point):
Done building target "Build" in project "AssemblerApplication1.asmproj".
Done building project "AssemblerApplication1.asmproj".

Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========

2. 烧录程序

使用AVRDUDE工具将编译生成的HEX文件烧录到Arduino板子上。点击菜单Tools->Arduino UNO avrdude,使用AVRDUDE命令进行烧录。烧录结束后,output窗口显示如下结果,表明烧录成功。

Avrdude version 8.0
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

System wide configuration file is D:\atmel studio\avrdude-v8.0-windows-x64\avrdude.conf

Using port            : COM3
Using programmer      : arduino
AVR part              : ATmega328P
Programming modes     : SPM, ISP, HVPP, debugWIRE
Programmer type       : Arduino
Description           : Arduino bootloader using STK500 v1 protocol
HW Version            : 3
FW Version            : 4.4

AVR device initialized and ready to accept instructions
Device signature = 1E 95 0F (ATmega328P, ATA6614Q, LGT8F328P)
Erased chip
Reading 32 bytes for flash from input file AssemblerApplication1.hex
in 1 section [0, 0x1f]: 1 page and 96 pad bytes
Writing 32 bytes to flash
Writing | ################################################## | 100% 0.04s
Reading | ################################################## | 100% 0.02s
32 bytes of flash verified

Avrdude done.  Thank you.

烧录成功后,arduino Uno的板载LED会闪烁。

3. 汇编程序的解释

这段代码是用汇编语言编写的,用于AVR微控制器。它的作用是控制一个连接到PORTB5(即PORTB的第5位)的LED灯,使其以1秒的间隔闪烁。下面是代码的逐行解释:

main:
 sbi 0x04, 5       ; 设置PORTB的第5位为输出模式
loop:              ; 主循环开始
 sbi 0x05, 5       ; 将PORTB的第5位设置为高电平(1),点亮LED
 call delay_1000ms ; 调用1秒延时子程序
 cbi 0x05, 5       ; 将PORTB的第5位设置为低电平(0),熄灭LED
 call delay_1000ms ; 再次调用1秒延时子程序
 rjmp loop         ; 无限循环回到主循环开始处

delay_1000ms:      ; 1秒延时子程序
                   ; 初始化计数器
 ldi r18, 0xFF     ; 将寄存器r18设置为255
 ldi r24, 0xD3     ; 将寄存器r24设置为211
 ldi r25, 0x30     ; 将寄存器r25设置为48

inner_loop:
 subi r18, 0x01    ; r18减1
 sbci r24, 0x00    ; r24减0(因为subi可能影响进位标志,所以用sbci)
 sbci r25, 0x00    ; r25减0(同上)
 brne inner_loop   ; 如果结果不是零,则跳回inner_loop继续循环
 ret               ; 返回到调用延时子程序的地方

这段代码中,sbi(Set Bit)和cbi(Clear Bit)指令分别用于设置和清除特定的端口位。ldi(Load Immediate)指令用于将立即数加载到寄存器中。subi(Subtract Immediate)和sbci(Subtract with Carry Immediate)指令用于减法操作,其中sbci考虑了进位标志。brne(Branch if Not Equal)指令用于在寄存器值不为零时跳转到指定的标签。

delay_1000ms子程序通过三次嵌套的循环来实现大约1秒的延时。这种延时方法依赖于微控制器的时钟频率,因此实际的延时时间可能会因不同的时钟设置而异。在实际应用中,这种延时方法不够精确,通常会使用定时器中断来实现更准确的延时。

在arduino Uno上运行汇编语言的门槛较高,比较小众。若深入了解微控制器的工作原理,还是可以深入学习的。后面列出了3本书可供参考。其他可自行在道客巴巴上查找,这个网站山峰的英文原版书确实很好!

参考书目

  1. Make; AVR Programming; Learning to Write Software for Hardware Williams 2014 Textbook - 道客巴巴
  2. Some Assembly Required; Assembly Language Programming with the AVR Microcontroller Margush 2011
  3. AVR Microcontroller and Embedded Systems Using Assembly and C - 道客巴巴
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值