ARM裸机:一步步点亮LED(汇编)
硬件工作原理及原理图查阅
-
LED物理特性介绍
LED本身有2个接线点,一个是LED的正极,一个是LED的负极。LED这个硬件的功能就是点亮或者不亮,物理上想要点亮一颗LED只需要给他的正负极上加正电压即可,要熄灭一颗LED只需要去掉电压即可。 -
查阅原理图了解板载LED硬件接法
查阅原理图,发现开发板上一共有5颗LED。其中一颗D26的接法是:正极接5V,负极接地。因此这颗LED只要上电就会常亮。因此我们分析这颗LED是电源指示灯。
剩下4颗LED的接法是:正极接3.3V,负极接了SoC上的一个引脚(GPIO),具体详细接法是:
D22:GPJ0_3
D23:GPJ0_4
D24:GPJ0_5
D25:PWMTOUT1(GPD0_1)



- 分析如何点亮及熄灭LED(GPIO)
分析:LED点亮的要求是:正极和负极之间有正向电压差。
思考:在开发板上如何为LED制造这个电压差让它点亮呢?
解答:因为正极已经定了(3.3V),而负极接在了SoC的引脚上,可以通过SoC中编程来控制负极的电压值,因此我们可以通过程序控制负极输出低电平(0V),这样在正负极上就有了压差,LED即可点亮。
数据手册查阅及相关寄存器浏览
-
GPIO概念的引入
GPIO:general purpose input output 通用输入输出
GPIO就是芯片的引脚(芯片上的引脚有些不是GPIO,只有一部分是),作为GPIO的这类引脚,他的功能和特点是可以被编程控制它的工作模式,也可以编程控制他的电压高低等。
通过之前的分析我们知道,我们设计电路时就把LED接在了一个GPIO上,这样我们就可以通过编程控制GPIO的模式和输入输出值来操控LED亮还是灭;如果你当时设计电路时把LED接在非GPIO上那就不可能了。 -
阅读数据手册中有关部分
当我们想要通过编程操控GPIO来操作LED时,我们首先需要通读一下S5PV210的数据手册中有关于GPIO的部分,这部分在数据手册的Section2.2中。
《S5PV210_UM_REV1.1.pdf》

-
GPIO相关的寄存器介绍
回忆下之前说过的,软件操作硬件的接口是:寄存器。
我们当前要操作的硬件是LED,但是LED实际是通过GPIO来间接控制的,所以当前我们实际要操作的设备其实是SoC的GPIO。要操作这些GPIO,必须通过设置他们的寄存器。

查阅数据手册可知,GPJ0相关的寄存器有以下:
GPJ0CON, (GPJ0 control)GPJ0控制寄存器,用来配置各引脚的工作模式
GPJ0DAT, (GPJ0 data)当引脚配置为input/output模式时,寄存器的相应位和引脚的电平高低相对应。
GPJ0PUD, (pull up down)控制引脚内部弱上拉、下拉
GPJ0DRV, (driver)配置GPIO引脚的驱动能力
GPJ0CONPDN,(记得是低功耗模式下的控制寄存器)
GPJ0PUDPDN (记得是低功耗模式下的上下拉寄存器)
注:在驱动LED点亮时,应该将GPIO配置为output模式。实际上真正操控LED的硬件,主要的有:GPJ0CON, GPJ0DAT 这么2个。
如何点亮LED,编程的步骤是:
1、操控GPJ0CON寄存器中,选中output模式
2、操控GPJ0DAT寄存器,相应的位设置为0
开始手写汇编点亮LED
D22:GPJ0_3
D23:GPJ0_4
D24:GPJ0_5


GPJ0CON(0xE0200240)寄存器和GPJ0DAT(0xE0200244)寄存器
第一步:设置引脚模式为输出模式(向GPxCON寄存器写入0001)
第二步:写入控制的数据(向GPxDAT寄存器写入0输出低电平,LED亮;1输出高电平,LED灭)
文件目录:

led.S:
_start://把0x1111 1111 写入 GPJ0CON(0xE0200240)//这里 ldr 是Load Register(加载寄存器)的缩写,//用于从给定的地址加载数据到处理器寄存器r0。//=0x11111111是一个立即数常量,//表示存储在内存中的十六进制数值 11111111ldr r0, =0x11111111 //ldr伪指令,编译器判断立即数是否合法//将立即数 0xE0200240加载到寄存器r1中ldr r1, =0xE0200240//str是Store Register(存储寄存器)的缩写,//它将寄存器r0中的值存储到[r1]所指向的位置。//这里的[r1]是对另一个内存地址的操作符,//意味着将r0的内容放到r1当前内容指明的那个内存位置//将r0的值存储到r1指向的内存地址处str r0, [r1] //寄存器间接寻址去; //LED灭:将0xff放到GPJ0DAT(0xE0200244)寄存器; ldr r0, =0xff; ldr r1, =0xE0200244; str r0, [r1]//LED亮:将 0x0 放到GPJ0DAT(0xE0200244)寄存器ldr r0, =0x0ldr r1, =0xE0200244str r0, [r1]//结束死循环
falt:b falt //直到CPU断电关机
编译结果:
LED常亮
使用位运算实现复杂点亮要求
-
如何只点亮中间1颗(两边是熄灭的)LED
//LED亮:将 0xf7 放到GPJ0DAT(0xE0200244)寄存器 亮1颗
中间一颗:0xEF
最后一颗:0xdf -
常用位运算:与、或、非、移位
位与(&) 位或(|) 位非(取反 ~) 移位(左移<< 右移>>) -
使用位运算实现功能
1<<3 等于 0b1000
1<<5 等于 0b100000
(1<<3)|(1<<5) 等于 0b101000 -
扩展一下:如何只熄灭中间1颗而点亮旁边2颗
ldr r0, =((0<<3) | (1<<4) | (0<<5))
汇编编写延时函数并实现LED闪烁效果
延时就是编写一些没有目的的代码,占用CPU的时间。
//延时函数
delay:ldr r2, =0x900000ldr r3, =0x0
delay_loop:cmp r3, r2//比较r3 r2 会影响Z标志位 如果r2==r3 则Z=1 下一句当中的ne就会成立sub r2, r2, #1 //r2=r2-1bne delay_loop //如果r2==r3 就不会执行这句mov pc, lr //函数调用返回
#define GPJ0CON 0xE0200240
#define GPJ0DAT 0xE0200244
//3、添加链接属性添加
.globl _start //将-start 修改为外部链接属性,其他文件就能找到_start
_start://把0x1111 1111 写入 GPJ0CON(0xE0200240)//这里 ldr 是Load Register(加载寄存器)的缩写,//用于从给定的地址加载数据到处理器寄存器r0。//=0x11111111是一个立即数常量,//表示存储在内存中的十六进制数值 11111111ldr r0, =0x11111111 //ldr伪指令,编译器判断立即数是否合法//将立即数 0xE0200240加载到寄存器r1中ldr r1, =GPJ0CON//str是Store Register(存储寄存器)的缩写,//它将寄存器r0中的值存储到[r1]所指向的位置。//这里的[r1]是对另一个内存地址的操作符,//意味着将r0的内容放到r1当前内容指明的那个内存位置//将r0的值存储到r1指向的内存地址处str r0, [r1] //寄存器间接寻址delay_loop_ok://熄灭中间1颗而点亮旁边2颗ldr r0, =((0<<3) | (1<<4) | (0<<5))ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delayldr r0, =((1<<3) | (0<<4) | (1<<5))ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delay; bne delay_loop_okb delay_loop_ok //死循环
再难一点的流水灯效果
12321的点亮LED
#define GPJ0CON 0xE0200240
#define GPJ0DAT 0xE0200244
//3、添加链接属性添加
.globl _start //将-start 修改为外部链接属性,其他文件就能找到_start
_start://把0x1111 1111 写入 GPJ0CON(0xE0200240)//这里 ldr 是Load Register(加载寄存器)的缩写,//用于从给定的地址加载数据到处理器寄存器r0。//=0x11111111是一个立即数常量,//表示存储在内存中的十六进制数值 11111111ldr r0, =0x11111111 //ldr伪指令,编译器判断立即数是否合法//将立即数 0xE0200240加载到寄存器r1中ldr r1, =GPJ0CON//str是Store Register(存储寄存器)的缩写,//它将寄存器r0中的值存储到[r1]所指向的位置。//这里的[r1]是对另一个内存地址的操作符,//意味着将r0的内容放到r1当前内容指明的那个内存位置//将r0的值存储到r1指向的内存地址处str r0, [r1] //寄存器间接寻址delay_loop_ok:ldr r0, =((0<<3) | (1<<4) | (1<<5))ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delayldr r0, =((1<<3) | (0<<4) | (1<<5))ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delayldr r0, =((1<<3) | (1<<4) | (0<<5))ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delayldr r0, =((1<<3) | (0<<4) | (1<<5))ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delay; bne delay_loop_okb delay_loop_ok //死循环//结束死循环 2、高级点的死循环b . //直到CPU断电关机 .:当前指令的地址//延时函数
delay:ldr r2, =0x900000ldr r3, =0x0
delay_loop:cmp r3, r2//比较r3 r2 会影响Z标志位 如果r2==r3 则Z=1 下一句当中的ne就会成立sub r2, r2, #1 //r2=r2-1bne delay_loop //如果r2==r3 就不会执行这句mov pc, lr //函数调用返回
位取反操作:
//1、使用宏定义
#define GPJ0CON 0xE0200240
#define GPJ0DAT 0xE0200244
//3、添加链接属性添加
.globl _start //将-start 修改为外部链接属性,其他文件就能找到_start
_start://把0x1111 1111 写入 GPJ0CON(0xE0200240)//这里 ldr 是Load Register(加载寄存器)的缩写,//用于从给定的地址加载数据到处理器寄存器r0。//=0x11111111是一个立即数常量,//表示存储在内存中的十六进制数值 11111111ldr r0, =0x11111111 //ldr伪指令,编译器判断立即数是否合法//将立即数 0xE0200240加载到寄存器r1中ldr r1, =GPJ0CON//str是Store Register(存储寄存器)的缩写,//它将寄存器r0中的值存储到[r1]所指向的位置。//这里的[r1]是对另一个内存地址的操作符,//意味着将r0的内容放到r1当前内容指明的那个内存位置//将r0的值存储到r1指向的内存地址处str r0, [r1] //寄存器间接寻址delay_loop_ok:ldr r0, =~(1<<3)ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delayldr r0, =~(1<<4)ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delayldr r0, =~(1<<5)ldr r1, =GPJ0DATstr r0, [r1]//延时一下:bl delay; bne delay_loop_okb delay_loop_ok //死循环//结束死循环 2、高级点的死循环b . //直到CPU断电关机 .:当前指令的地址//延时函数
delay:ldr r2, =0x900000ldr r3, =0x0
delay_loop:cmp r3, r2//比较r3 r2 会影响Z标志位 如果r2==r3 则Z=1 下一句当中的ne就会成立sub r2, r2, #1 //r2=r2-1bne delay_loop //如果r2==r3 就不会执行这句mov pc, lr //函数调用返回
反汇编工具objdump的使用简介
反汇编的原理&为什么要反汇编
arm-linux-objdump -D led.elf > led_elf.dis
objdump是gcc工具链中的反汇编工具,作用是由编译链接好的elf格式的可执行程序反过来得到汇编源代码
-D表示反汇编 > 左边的是elf的可执行程序(反汇编时的原材料),>右边的是反汇编生成的反汇编程序
- 反汇编的原因
1、逆向破解
2、调试,理解程序链接脚本、链接地址
3、理解C语言和汇编语言的关系
(汇编 assembly 反汇编 Disassembly)
标号的实质是地址
指令被转换为机器码
地址池实现非法立即数

bin文件内部是机器码,机器码会有指定的指令地址,使用ld链接在一起
总结
1、知道LED点亮原理
2、查看原理图知道接线方式
3、查看数据手册知道寄存器地址
4、开始编程
5、编译可执行文件
6、下载到设备上
7、添加延时达到流水灯
8、位操作增加可读性,同时比较简略
9、反汇编工具objdump可以帮助理解程序
学习记录,侵权联系删除。
来源:朱老师物联网大课堂
相关文章:
ARM裸机:一步步点亮LED(汇编)
硬件工作原理及原理图查阅 LED物理特性介绍 LED本身有2个接线点,一个是LED的正极,一个是LED的负极。LED这个硬件的功能就是点亮或者不亮,物理上想要点亮一颗LED只需要给他的正负极上加正电压即可,要熄灭一颗LED只需要去掉电压即可…...
【单链表】05 有一个带头结点的单链表L,设计一个算法使其元素递增有序。
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux算法题上机准备 😘欢迎 ❤️关注 👍点赞 🙌收藏 ✍️留言 题目 有一个带头结点的单链表L,设计一个算法使其元素递增有序。 算法思路 解决办法有很多&…...
C语言入门基础题:奇偶 ASCII 值判断(C语言版)和ASCII码表,什么是ASCII码,它的特点和应用?
1.题目描述: 任意输入一个字符,判断其 ASCII 是否是奇数,若是,输出 YES ,否则,输出 NO例如,字符 A 的 ASCI 值是 65 ,则输出 YES ,若输入字符 B(ASCII 值是 66)ÿ…...
Numpy的广播机制(用于自动处理不同形状的数组)
NumPy 广播是一种强大的机制,允许 NumPy 在执行元素级运算时自动处理不同形状的数组。广播的规则使得无需显式地创建匹配形状的数组,直接进行运算,大大简化了代码并提高了效率。 基本概念 广播的基本思想是让较小的数组在需要的维度上进行扩…...
计算机图形学入门24:材质与外观
1.前言 想要得到一个漂亮准确的场景渲染效果,不只需要物理正确的全局照明算法,也要了解现实中各种物体的表面外观和在图形学中的模拟方式。而物体的外观和材质其实就是同一个意思,不同的材质在光照下就会表现出不同的外观,所以外观…...
FTP、http 、tcp
HTTP VS FTP HTTP :HyperText Transfer Protocol 超文本传输协议,是基于TCP协议 FTP: File Transfer Protocol 文件传输协议, 基于TCP协议, 基于UDP协议的FTP 叫做 TFTP HTTP 协议 通过一个SOCKET连接传输依次会话数…...
【虚幻引擎】UE4初学者系列教程开发进阶实战篇——生存游戏案例
一、课程体系 1 学前必读 2 Character类相关基础 -人物移动控制 -动画蓝图 3 常见游戏机制基础 -碰撞器、触发器 -物体使用接口 -视角切换 4其他相关设计 -背包系统 -锻造系统 -物体破碎效果 -简易种植系统 -互动物体动画 5课程结语 二、UI部分 思维导图部分 实操部分 …...
认识并理解webSocket
今天逛牛客,看到有大佬分享说前端面试的时候遇到了关于webSocket的问题,一看自己都没见过这个知识点,赶紧学习一下,在此记录! WebSocket 是一种网络通信协议,提供了全双工通信渠道,即客户端和服…...
Scissor算法-从含有表型的bulkRNA数据中提取信息进而鉴别单细胞亚群
在做基础实验的时候,研究者都希望能够改变各种条件来进行对比分析,从而探索自己所感兴趣的方向。 在做数据分析的时候也是一样的,我们希望有一个数据集能够附加了很多临床信息/表型,然后二次分析者们就可以进一步挖掘。 然而现实…...
Linux-磁盘空间不足的清理步骤(详细版本)
当 Linux 服务器出现 “no space left on device” 错误时,意味着磁盘空间已满,需要采取一些措施来清理磁盘,可以根据下面步骤依次清理: 1. 检查磁盘使用情况 首先,使用 df 和 du 命令检查磁盘使用情况,找出哪些目录占用了大量空间。 可以通过如下命令来查询 df -h举例…...
go-redis源码解析:连接池原理
1. 执行命令的入口方法 redis也是通过hook执行命令,initHooks时,会将redis的hook放在第一个 通过hook调用到process方法,process方法内部再调用_process 2. 线程池初始化 redis在新建单客户端、sentinel客户端、cluster客户端等,…...
蓝桥杯备赛攻略(怒刷5个月拿省一)
十五届蓝桥杯结束,up也在这次比赛中获得了不错的成绩,为了帮助大家在25年蓝桥杯上获得好的成绩,我将根据今年的经验写一份蓝桥杯的备赛攻略,希望能帮到大家。 参赛准备 蓝桥杯算法赛必须指定一个编程语言赛道报名,也就…...
springboot项目jar包修改数据库配置运行时异常
一、背景 我将软件成功打好jar包了,到部署的时候发现jar包中数据库配置写的有问题,不想再重新打包了,打算直接修改配置文件,结果修改配置后,再通过java -jar运行时就报错了。 二、问题描述 本地项目是springBoot项目…...
倒计时 2 周!CommunityOverCode Asia 2024 IoT Community 专题部分
CommunityOverCode 是 Apache 软件基金会(ASF)的官方全球系列大会,其前身为 ApacheCon。自 1998 年以来,在 ASF 成立之前,ApacheCon 已经吸引了各个层次的参与者,在 300 多个 Apache 项目及其不同的社区中探…...
使用OpenCV在按下Enter键时截图并保存到指定文件夹
使用OpenCV在按下Enter键时截图并保存到指定文件夹 在这篇博客中,我们将介绍如何使用OpenCV库来实现一个简单的功能:在按下Enter键时从摄像头截图并保存到指定的文件夹中。这个功能可以用于各种应用,例如监控系统、视频捕捉等。 前置条件 …...
汇川伺服 (4)FFT、机械特性、闭环、惯量、刚性、抑制振动
一、参数解释 二、FFT 三、机械特性分析 四、多级配方与对象字典 对机组网配方 对象字典 五、InoServoShop 主要是用于调试620P620N将压缩报解压后不需要安装就可以直接使用 六、InoDriveWorkShop 主要是调试660 670 810 520 等系列 惯量识别 Etune Stune 惯量比调试 大惯…...
Unity3D中使用并行的Job完成筛选类任务详解
在Unity3D开发中,处理大量数据或执行复杂计算时,性能往往成为制约因素。为了提升游戏或应用的性能,Unity提供了强大的Job System,它允许开发者利用多线程和并行计算来优化数据处理过程。本文将详细介绍如何在Unity中使用并行的Job…...
汽车信息安全--欧盟汽车法规
目录 General regulation 信息安全法规 R155《网络安全及网络安全管理系统》解析 R156《软件升级与软件升级管理系统》解析 General regulation 欧洲的汽车行业受到一系列法律法规的约束,包括 各个方面包括: 1.安全要求:《通用安全条例&a…...
@SpringBootApplication 注解
什么是 SpringBootApplication SpringBootApplication 是 Spring Boot 提供的一个核心注解,它是一个组合注解,用于简化 Spring Boot 应用程序的配置。这个注解通常标注在主类上,用于标识一个 Spring Boot 应用的入口。通过这个注解ÿ…...
java项目总结4
目录 1.正则表达式 2.爬虫 3.时间 4.包装类 5.工具类之Arrays 6.Lambda 1.正则表达式 用于验证字符串是否满足自己所需要的规则。方法:matches 注意:\在Java中有特殊涵义,是将其它的意思本来化,假设"是用来引…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
