一、编译下载运行04-Software/ch02/CH02-1-20220118
1、导入工程,选定目标文件
2、点击编译,编译工程
3、点击下载,串口更新,进行设备连接,导入机器码文件,点击一更新
程序显示灯闪烁次数与灯亮状态
如下图,按十进制整型输出
定义字符串标号后
可以用形如下面的指令打印字符串。
而对于打印变量的值,则要先将标号取到r0寄存器,再将变量的值取到r1寄存器,这样来完成变量值的打印
二、修改main.s源码
1、在第一行显示“广州大学”字样
定义字符串标号
打印字符串
2、编写一个1+2+..+10的程序,将求和结果存入名为“sumresult”的内存单元中,并将求和结果用printf显示出来。
定义变量
通过循环进行1+2+...+10,并将结果存入sumresult变量中
打印最终结果
重新编译文件,运行程序
程序在bl.停止,不再进行后续指令的执行
//=====================================================================
//文件名称:main.s
//功能概要:汇编编程调用GPIO构件控制小灯闪烁(利用printf输出提示信息)
//版权所有:SD-ARM(sumcu.suda.edu.cn)
//版本更新:20180810-20191018
//=====================================================================
.include "include.inc" //头文件中主要定义了程序中需要使用到的一些常量
//(0)数据段与代码段的定义
//(0.1)定义数据存储data段开始,实际数据存储在RAM中
.section .data
//(0.1.1)定义需要输出的字符串,标号即为字符串首地址,\0为字符串结束标志
show:
.ascii "广州大学32106200050\n\0"
hello_information: //字符串标号
.ascii "-------------------------------------------------------\n"
.ascii "金葫芦提示: \n"
.ascii "1、本程序用来示范如何输出指令所在flash单元的地址以及指令 \n"
.ascii "所对应的机器码。 \n"
.ascii "2、Debug文件夹中的.lst文件可搜索汇编指令找到对应的机器码。\n"
.ascii "3、printf函数可根据输出格式输出参数的值。 \n"
.ascii "------------------------------------------------------\n\0"
data_format:
.ascii "%d\n\0" //printf使用的数据格式控制符
data_format1:
.ascii "%08x:%02x\n\0" //printf使用的数据格式控制符,其中8表示输出位数,
//0表示将输出的前面补上0,直到占满指定列宽为止
light_show1:
.ascii "LIGHT_BLUE:ON--\n\0" //灯亮状态提示
light_show2:
.ascii "LIGHT_BLUE:OFF--\n\0" //灯暗状态提示
light_show3:
.ascii "闪烁次数mLightCount=\0" //闪烁次数提示
result_show:
.ascii "1+2+3+4+5+6+7+8+9+10求和结果sumresult=\0" //闪烁次数提示
//(0.1.2)定义变量
.align 4 //.word格式四字节对齐
mMainLoopCount: //定义主循环次数变量
.word 0
mFlag: //定义灯的状态标志,1为亮,0为暗
.byte 'A'
.align 4
mLightCount:
.word 0
sumresult: //定义求和结果
.word 0
//(0.2)定义代码存储text段开始,实际代码存储在Flash中
.section .text
.syntax unified //指示下方指令为ARM和thumb通用格式
.thumb //Thumb指令集
.type main function //声明main为函数类型
.global main //将main定义成全局函数,便于芯片初始化之后调用
.align 2 //指令和数据采用2字节对齐,兼容Thumb指令集
//--------------------------------------------------------------------
//main.c使用的内部函数声明处
//--------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
main:
//(1)======启动部分(开头)主循环前的初始化工作======================
//(1.1)声明main函数使用的局部变量
//(1.2)【不变】关总中断
cpsid i
//(1.3)给主函数使用的局部变量赋初值
//(1.4)给全局变量赋初值
//(1.5)用户外设模块初始化
// 初始化蓝灯, r0、r1、r2是gpio_init的入口参数
ldr r0,=LIGHT_BLUE //r0指明端口和引脚(用=,因常量>=256,需用ldr)
mov r1,#GPIO_OUTPUT //r1指明引脚方向为输出
mov r2,#LIGHT_OFF //r2指明引脚的初始状态为亮
bl gpio_init //调用gpio初始化函数
// 初始化串口UART_User1
mov r0,#UART_User //串口号
ldr r1,=UART_BAUD //波特率
bl uart_init //调用uart初始化函数
//(1.6)使能模块中断
mov r0,#UART_User //串口号
bl uart_enable_re_int //调用uart中断使能函数
//(1.7)【不变】开总中断
cpsie i
//显示hello_information定义的字符串
ldr r0,=show //显示“广州大学”
bl printf
ldr r0,=hello_information //待显示字符串首地址
bl printf //调用printf显示字符串
mov r1,#1
mov r2,#2
//循环
loop:
add r1,r2
add r2,#1
cmp r2,#11
blO loop //未达到,继续循环
ldr r3,=sumresult //总和存入sumresult
ldr r4,[r3]//取
mov r4,r1
str r4,[r3]//存
ldr r0,=result_show //显示“求和结果sumresult=”
bl printf
ldr r0,=data_format //显示值
ldr r3,=sumresult
ldr r1,[r3]
bl printf
bl . //在此打桩(.表示当前地址),理解发光二极管为何亮起来了?