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是一个立即数常量,
	//表示存储在内存中的十六进制数值 11111111
	ldr 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, =0x0
	ldr r1, =0xE0200244
	str 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, =0x900000
	ldr r3, =0x0
delay_loop:
	cmp r3, r2
	//比较r3 r2  会影响Z标志位  如果r2==r3 则Z=1 下一句当中的ne就会成立
	sub r2, r2, #1 //r2=r2-1
	bne 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是一个立即数常量,
	//表示存储在内存中的十六进制数值 11111111
	ldr 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, =GPJ0DAT
	str r0, [r1]

	//延时一下:
	bl delay

	ldr r0, =((1<<3) | (0<<4) | (1<<5))
	ldr r1, =GPJ0DAT
	str r0, [r1]

	//延时一下:
	bl delay

	; bne delay_loop_ok
	b 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是一个立即数常量,
	//表示存储在内存中的十六进制数值 11111111
	ldr 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, =GPJ0DAT
	str r0, [r1]

	//延时一下:
	bl delay

	ldr r0, =((1<<3) | (0<<4) | (1<<5))
	ldr r1, =GPJ0DAT
	str r0, [r1]

	//延时一下:
	bl delay

	ldr r0, =((1<<3) | (1<<4) | (0<<5))
	ldr r1, =GPJ0DAT
	str r0, [r1]


	//延时一下:
	bl delay

	ldr r0, =((1<<3) | (0<<4) | (1<<5))
	ldr r1, =GPJ0DAT
	str r0, [r1]

	//延时一下:
	bl delay
	
	; bne delay_loop_ok
	b delay_loop_ok //死循环



//结束死循环 2、高级点的死循环
	b .  //直到CPU断电关机 .:当前指令的地址


//延时函数
delay:
	ldr r2, =0x900000
	ldr r3, =0x0
delay_loop:
	cmp r3, r2
	//比较r3 r2  会影响Z标志位  如果r2==r3 则Z=1 下一句当中的ne就会成立
	sub r2, r2, #1 //r2=r2-1
	bne 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是一个立即数常量,
	//表示存储在内存中的十六进制数值 11111111
	ldr 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, =GPJ0DAT
	str r0, [r1]
	//延时一下:
	bl delay

	ldr r0, =~(1<<4)
	ldr r1, =GPJ0DAT
	str r0, [r1]
	//延时一下:
	bl delay

	ldr r0, =~(1<<5)
	ldr r1, =GPJ0DAT
	str r0, [r1]
	//延时一下:
	bl delay


	; bne delay_loop_ok
	b delay_loop_ok //死循环



//结束死循环 2、高级点的死循环
	b .  //直到CPU断电关机 .:当前指令的地址


//延时函数
delay:
	ldr r2, =0x900000
	ldr r3, =0x0
delay_loop:
	cmp r3, r2
	//比较r3 r2  会影响Z标志位  如果r2==r3 则Z=1 下一句当中的ne就会成立
	sub r2, r2, #1 //r2=r2-1
	bne 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可以帮助理解程序

学习记录,侵权联系删除。
来源:朱老师物联网大课堂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/787908.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

字节码编程javassist之生成带有注解的类

写在前面 本文看下如何使用javassist生成带有注解的类。 1&#xff1a;程序 测试类 package com.dahuyou.javassist.huohuo.cc;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import ja…

JVM原理(二四):JVM虚拟机锁优化

高效并发是从JDK 5升级到JDK 6后一项重要的改进项&#xff0c;HotSpot虛 拟机开发团队在这个版本上花费了大量的资源去实现各种锁优化技术&#xff0c;如适应性自旋( Adaptive Spinning)、锁消除( Lock Elimination)、锁膨胀(Lock Coarsening)、轻量级锁(Lightweight Locking)、…

了解PPO算法(Proximal Policy Optimization)

Proximal Policy Optimization (PPO) 是一种强化学习算法&#xff0c;由 OpenAI 提出&#xff0c;旨在解决传统策略梯度方法中策略更新过大的问题。PPO 通过引入限制策略更新范围的机制&#xff0c;在保证收敛性的同时提高了算法的稳定性和效率。 PPO算法原理 PPO 算法的核心…

LAMP万字详解(概念、构建步骤)

目录 LAMP Apache 起源 主要特点 软件版本 编译安装httpd服务器 编译安装的优点 操作步骤 准备工作 编译 安装 优化执行路径 添加服务 守护进程 配置httpd 查看 Web 站点的访问情况 虚拟主机 类型 部署基于域名的虚拟主机 为虚拟主机提供域名解析&#xff…

ESP32的I2S引脚及支持的音频标准使用说明

ESP32 I2S 接口 ESP32 有 2 个标准 I2S 接口。这 2 个接口可以以主机或从机模式&#xff0c;在全双工或半双工模式下工作&#xff0c;并且可被配置为 8/16/32/48/64-bit 的输入输出通道&#xff0c;支持频率从 10 kHz 到 40 MHz 的 BCK 时钟。当 1 个或 2 个 被配置为主机模式…

db期末复习自用[应试向 附习题]

第一章 数据库系统实现整体数据的结构化&#xff0c;主要特征之一&#xff0c;是db区别于文件系统的本质区别。 数据库系统三个阶段&#xff1a;人工、文件、数据库系统。 数据库管理系统的功能&#xff1a;数据库定义、操纵 、&#xff08;保护、存储、维护&#xff09;、数…

大模型/NLP/算法面试题总结2——transformer流程//多头//clip//对比学习//对比学习损失函数

用语言介绍一下Transformer的整体流程 1. 输入嵌入&#xff08;Input Embedding&#xff09; 输入序列&#xff08;如句子中的单词&#xff09;首先通过嵌入层转化为高维度的向量表示。嵌入层的输出是一个矩阵&#xff0c;每一行对应一个输入单词的嵌入向量。 2. 位置编码&…

020-GeoGebra中级篇-几何对象之点与向量

本文概述了在GeoGebra中如何使用笛卡尔或极坐标系输入点和向量。用户可以通过指令栏输入数字和角度&#xff0c;使用工具或指令创建点和向量。在笛卡尔坐标系中&#xff0c;示例如“P(1,0)”&#xff1b;在极坐标系中&#xff0c;示例如“P(1;0)”或“v(5;90)”。文章还介绍了点…

SpringBoot + MyBatisPlus 实现多租户分库

一、引言 在如今的软件开发中&#xff0c;多租户(Multi-Tenancy)应用已经变得越来越常见。多租户是一种软件架构技术&#xff0c;它允许一个应用程序实例为多个租户提供服务。每个租户都有自己的数据和配置&#xff0c;但应用程序实例是共享的。而在我们的Spring Boot MyBati…

刷代码随想录有感(130):动态规划——编辑距离

题干&#xff1a; 代码&#xff1a; class Solution { public:int minDistance(string word1, string word2) {vector<vector<int>>dp(word1.size() 1, vector<int>(word2.size() 1));for(int i 0; i < word1.size(); i)dp[i][0] i;for(int j 0; j …

使用Mplayer实现MP3功能

核心功能 1. 界面设计 项目首先定义了一个clearscreen函数&#xff0c;用于清空屏幕&#xff0c;为用户界面的更新提供了便利。yemian函数负责显示主菜单界面&#xff0c;提供了包括查看播放列表、播放控制、播放模式选择等在内的9个选项。 2. 文件格式支持 is_supported_f…

数据抓取技术在视频内容监控与快速读取中的应用

引言 在数字化时代&#xff0c;视频内容的快速读取和监控对于内容提供商来说至关重要。思通数科的OPEN-SPIDER抓取技术为这一需求提供了高效的解决方案。 OPEN-SPIDER技术概述 OPEN-SPIDER是思通数科开发的一种先进的数据抓取技术&#xff0c;它能够&#xff1a; - 高效地从各…

Qt 音频编程实战项目

一Qt 音频基础知识 QT multimediaQMediaPlayer 类&#xff1a;媒体播放器&#xff0c;主要用于播放歌曲、网络收音 机等功能。QMediaPlaylist 类&#xff1a;专用于播放媒体内容的列表。 二 音频项目实战程序 //版本5.12.8 .proQT core gui QT multimedia greate…

基于深度学习的电影推荐系统

1 项目介绍 1.1 研究目的和意义 在电子商务日益繁荣的今天&#xff0c;精准预测商品销售数据成为商家提升运营效率、优化库存管理以及制定营销策略的关键。为此&#xff0c;开发了一个基于深度学习的商品销售数据预测系统&#xff0c;该系统利用Python编程语言与Django框架&a…

在RockyLinux上安装Solr8.11(新版本)

在RockyLinux上安装Solr8.11&#xff08;新版本&#xff09; 安装准备安装java环境 安装Solr下载修改配置开放端口验证一下 安装准备 安装java环境 搜索提供可安装的包 yum search java 我们在这里看到有很多&#xff0c;我这里安装的1.8版本。我们这里选择描述为Runtime en…

斯坦福大学博士在GitHub发布的漫画机器学习小抄,竟斩获129k标星

斯坦福大学数据科学博士Chris Albon在GitHub上发布了一份超火的机器学习漫画小抄&#xff0c;发布仅仅一天就斩获GitHub榜首标星暴涨120k&#xff0c;小编有幸获得了一份并把它翻译成中文版本&#xff0c;今天给大家分享出来&#xff01; 轻松的画风配上让人更容易理解的文字讲…

万字总结GBDT原理、核心参数以及调优思路

万字总结GBDT原理、核心参数以及调优思路 在机器学习领域&#xff0c;梯度提升决策树&#xff08;Gradient Boosting Decision Tree, GBDT&#xff09;以其卓越的预测性能和强大的模型解释能力而广受推崇。GBDT通过迭代地构建决策树&#xff0c;每一步都在前一步的残差上进行优…

【力扣高频题】042.接雨水问题

上一篇我们通过采用 双指针 的方法解决了 经典 容器盛水 问题 &#xff0c;本文我们接着来学习一道在面试中极大概率会被考到的经典题目&#xff1a;接雨水 问题 。 42. 接雨水 给定 n 个非负整数&#xff0c;表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子…

【高校科研前沿】中国农业大学姚晓闯老师等人在农林科学Top期刊发表长篇综述:深度学习在农田识别中的应用

文章简介 论文名称&#xff1a;Deep learning in cropland field identification: A review&#xff08;深度学习在农田识别中的应用&#xff1a;综述&#xff09; 第一作者及单位&#xff1a;Fan Xu&#xff08;中国农业大学土地科学与技术学院&#xff09; 通讯作者及单位&…

【电路笔记】-C类放大器

C类放大器 文章目录 C类放大器1、概述2、C类放大介绍3、C类放大器的功能4、C 类放大器的效率5、C类放大器的应用:倍频器6、总结1、概述 尽管存在差异,但我们在之前有关 A 类、B 类和 AB 类放大器的文章中已经看到,这三类放大器是线性或部分线性的,因为它们在放大过程中再现…