要移植操作系统,汇编是道不得不跨过去的坎。所以承接上篇的思路,我准备用汇编写一个简单的闪烁LED灯的程式。以此练习汇编,为操作系统做准备。

第一步,还是和上篇一样,建立一个空的文件夹。

第二步,因为是要用汇编来写程式,所以不需要启动代码,这里选择否。

第三步,建立一个.s文件,并把文件添加到工程中。

第四步,在LED.s文件中添加如下代码。

LED0 EQU 0x422101a0

RCC_APB2ENR EQU 0x40021018

GPIOA_CRH EQU 0x40010804

Stack_Size EQU 0x00000400

AREA STACK, NOINIT, READWRITE, ALIGN=

Stack_Mem SPACE Stack_Size

__initial_sp

AREA RESET, DATA, READONLY

__Vectors DCD __initial_sp ; Top of Stack

DCD Reset_Handler ; Reset Handler

AREA |.text|, CODE, READONLY

THUMB

REQUIRE8

PRESERVE8

ENTRY

Reset_Handler

BL LED_Init

MainLoop BL LED_ON

BL Delay

BL LED_OFF

BL Delay

B MainLoop

LED_Init

PUSH {R0,R1, LR}

LDR R0,=RCC_APB2ENR

ORR R0,R0,#0x04

LDR R1,=RCC_APB2ENR

STR R0,[R1]

LDR R0,=GPIOA_CRH

BIC R0,R0,#0x0F

LDR R1,=GPIOA_CRH

STR R0,[R1]

LDR R0,=GPIOA_CRH

ORR R0,R0,#0x03

LDR R1,=GPIOA_CRH

STR R0,[R1]

MOV R0,#

LDR R1,=LED0

STR R0,[R1]

POP {R0,R1,PC}

LED_ON

PUSH {R0,R1, LR}

MOV R0,#

LDR R1,=LED0

STR R0,[R1]

POP {R0,R1,PC}

LED_OFF

PUSH {R0,R1, LR}

MOV R0,#

LDR R1,=LED0

STR R0,[R1]

POP {R0,R1,PC}

Delay

PUSH {R0,R1, LR}

MOVS R0,#

MOVS R1,#

MOVS R2,#

DelayLoop0

ADDS R0,R0,#

CMP R0,#

BCC DelayLoop0

MOVS R0,#

ADDS R1,R1,#

CMP R1,#

BCC DelayLoop0

MOVS R0,#

MOVS R1,#

ADDS R2,R2,#

CMP R2,#

BCC DelayLoop0

POP {R0,R1,PC}

; NOP

END

///

代码的简单讲解

1,预定义

LED0 EQU 0x422101a0 ;PA8的Bit-Bond地址。

RCC_APB2ENR EQU 0x40021018

GPIOA_CRH EQU 0x40010804

为方便操作,给每个需要用到的寄存器地址定义一个名字,类似于C语言的#define。PA8的Bit-Bond地址的计算方法可按上篇文章中C语言的算法算出。后面的两个地址时固定的,可从STM32的手册查询,或者根据ST官方的库文件查找计算。

2,分配栈空间

Stack_Size EQU 0x00000400

AREA STACK, NOINIT, READWRITE, ALIGN=3

Stack_Mem SPACE Stack_Size

__initial_sp

这一段摘自启动文件。要读懂这段代码,首先要了解两个命令。

AREA命令:AREA 命令指示汇编器汇编一个新的代码段或数据段。段是独立的、指定的、不可见的代码或数据块,它们由链接器处理。格式如下:

AREA 段名,段属性1,段属性2,段属性3。。。

AREA STACK, NOINIT, READWRITE, ALIGN=3

NOINIT: = NO Init,不初始化。

READWRITE : 可读,可写。

ALIGN =3 : 2^3 对齐,即8字节对齐。

SPACE命令:SPACE 命令保留一个用零填充的存储器块。

所以整段的意思为:分配一个STACK段,该段不初始化,可读写,按8字节对齐。分配一个大小为Stack_Size的存储空间,并使栈顶的地址为__initial_sp。

3,分配向量表

AREA RESET, DATA, READONLY

__Vectors DCD __initial_sp ; Top of Stack

DCD Reset_Handler ; Reset Handler

这里的向量可参考我之前写的《STM32向量表详细分析》。

4,开始代码段

AREA |.text|, CODE, READONLY

通知汇编器,开始代码段。

THUMB

REQUIRE8

PRESERVE8

这段的意思是,汇编器支持THUMB指令,代码段按8字节对齐。

ENTRY命令:声明整个程式的入口点,入口点有且仅有一个。不管哪种语言,编译器都得有个入口点,这没什么好说的。

5,程序正式开始。

后面的代码,皆用标准的THUMB2汇编指令。首先了解下代码中用到的指令。

BL:带链接的跳转指令。当使用该指令跳转时,当前地址(PC)会自动送入LR寄存器。

B:无条件跳转。

PUSH和POP:可以看到,所有的子程序都是由PUSH和POP包起来的。借用一张图解释下这两个指令。

据上可知,PUSH {R0,R1, LR}的意思即把R0,R1,LR中的值放入堆栈中。由于主程式中使用BL跳转指令,所以LR中的值实际上就是当前PC的值。而POP {R0,R1,PC}的意思即是将栈中之前存的R0,R1,LR的值返还给R0,R1,PC。这样就完成了子程序的返回。

LDR和STR:寄存器的装载和存储指令。

LDR是把地址装载到寄存器中(比如R0)。

STR是把值存储到寄存器所指的地址中。

举个例子:

MOV R0,#1 ;将立即数1送入R0.

LDR R1,=LED0;将PA8 bit-bond的地址送入R1.

STR R0,[R1];将R0的值,也就是1,送给R1中的值所指向的地址中,也就是PA8的bit-bond地址。

上面三句话的意思即是将PA8置1。

ORR和BIC:

ORR 按位或操作。ORR R0,R0,#0x04意思即将R0中的数或上0x04,再将结果送往R0中。实际意思就是将R0的第二位置1,其他位不变。

BIC 先把立即数取反,再按位与。

CMP和BCC:CMP是比较两个数,相等或大于则将标志位C置位,否则将C清零。BCC是个组合指令,实际为B+CC,意思是如果C=0则跳转。

CMP R2,#15; 计算R2-15的值,若是R2<15,则C=0;若是R2>=15,则C=1。

BCC DelayLoop0;若是C=0,则跳到DelayLoop0,若是c=1,则不跳转。

以上就是代码段相关指令的介绍,相信了解了这些指令的含义,要理解代码并不困难。

整个代码的结构和上篇用C语言写的基本是一样的。可参照理解

第五步,编译,下载。

编译后,会有一个警告 No section matches pattern……可不用管。下载后,LED灯正常闪烁。

最简单的STM32入门教程----闪烁LED

本文讲述的是如何从零开始,使用keil建立一个简单的STM32的工程,并闪烁LED灯,给小白看. 第零步,当然首先你得有一个STM32的板子,其IO口上接了一个LED... 第一步,建立一个文件夹0. ...

ARM汇编程序闪烁灯与其反汇编代码比较

/* *LED闪烁 *led.s */ #define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start //把 _start ...

STM32点亮闪烁LED灯

详解请看其他博客: http://www.cnblogs.com/whik/p/6672730.html http://www.51hei.com/bbs/dpj-38605-1.html /*本程序 ...

AVR单片机教程——闪烁LED

上次我们把LED点亮了.你可能已经试过把 LED_RED 换成其他灯,也可能已经用 led_on() 把所有LED一起点亮了.但是LED点亮以后,程序就退出了,之后LED一直没有暗,直到没有供电.这一 ...

iOS简单动画效果:闪烁、移动、旋转、路径、组合

#define kDegreesToRadian(x) (M_PI * (x) / 180.0) #define kRadianToDegrees(radian) (radian*180.0)/(M_ ...

stm32点亮LED 测试代码及目录结构

. main.c - 使用PB12, PB13, PB14, PB15, PB5, PB6, PB7 这七个PB口点亮LED. 注意PB3和PB4是特殊口, 直接调用无效. #include &quo ...

CC2640R2F&amp&semi;TI-RTOS 拿到 TI CC2640R2F 开发板 第三件事就是使用 TI-RTOS 创建 一个任务 和 使用 信号量 超时来闪烁 LED灯

/* * data_process.c * * Created on: 2018年7月5日 * Author: admin */ #include

【Linux 驱动】简单字符设备驱动架构&lpar;LED驱动&rpar;

本文基于icool210开发板,内核版本:linux2.6.35: 驱动代码: (1)头文件:led.h #ifndef __LED_H__ #define __LED_H__ #define LED ...

STM32点亮LED

原理图 测试灯,接GPIO外设B,Pin 12 举例 前提,工程模版建立好 #include "stm32f10x.h" void delay(u32 i) { while(i-- ...

随机推荐

Intellij idea 和android studio 代码给混淆

Intellij idea 和android studio 代码给混淆 一.指令说明-optimizationpasses 5 # 指定代码的压缩级别 -dontusemixedcaseclassna ...

BlockCanary 一个轻量的,非侵入式的性能监控组件(阿里)

开发者博客: BlockCanary — 轻松找出Android App界面卡顿元凶 开源代码:moduth/blockcanary BlockCanary对主线程操作进行了完全透明的监控,并能输出有 ...

poj 1364 King&lpar;差分约束&rpar;

题目:http://poj.org/problem?id=1364 #include #include #include

yii2 日志(log)的配置与使用

keil8个led灯闪烁c语言程序,简单的STM32 汇编程序—闪烁LED相关推荐

  1. 自动感光调节LED灯亮度C语言程序,单片机PWM调节LED灯亮度

    刚搞完飞思卡尔智能车,昨天我一起做车的搭档跑来跟我说魏老师(我们系的前主任,不知道他们怎么认识的....)叫他帮忙做个可通过无线遥控调节LED灯亮度的设计方案,问我有没有兴趣做做,主要是魏老师也是受他 ...

  2. 自动感光调节LED灯亮度C语言程序,PWM控制LED灯的亮度(C 语言)

    控制LED灯的亮度,通过调节电压的方式可以达到,但不理想,而且可调的范围很小,电压稍高,还容易把LED烧毁,唯一可行的方法就是通过PWM(脉冲宽度调节)来控制其亮度. 以下程序是在单片机中控制LED. ...

  3. 中断1控制LED左移C语言程序,51单片机控制P2口8位LED灯左移C语言程序

    此程序控制P2.0~P2.7口8个LED(P2.0~P2.7)灯逐个依次点这,又从(P2.7~P2.0)这样的顺序一直到全部被点亮. #include //头文件 void delay(unsigne ...

  4. 自动感光调节LED灯亮度C语言程序,红外感应LED亮度调节(附单片机程序).doc

    西南科技大学毕业设计第 PAGE 25页 共 22页西南科技大学毕业设计第 PAGE 1页 共19页 摘 要为了解决长明灯所造成的能源浪费而设计出了利用红外热释传感器控制楼道灯开关的电路.当白天光照很 ...

  5. 点亮led灯c语言程序,求最简单点亮LED灯单片机c语言程序

    /*    添加包含芯片的头文件    */ #include  /*  头文件 */ //由原理图得知,给LED一个低电平,LED亮.否则LED不亮. #define         LED1_ON ...

  6. 单片机控制灯光亮度c语言程序,STC89C52RC单片机按键控制PWM输出LED灯亮度C语言程序...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 //以下是源程序,只需修改定义IO口就可以使用, #include < reg52.h > #include < intrins.h & ...

  7. 单片机流水灯全亮c语言程序,终极流水灯单片机C语言程序.doc

    终极流水灯单片机C语言程序 #include #include #define uint unsigned int sbit beep=P2^3; void ji_ou(); void sx(); v ...

  8. 单片机利用Proteus进行仿真点亮一个LED灯(C语言和汇编语言)

    Proteus仿真图: c语言程序: #include <reg51.h> sbit LED=P0^0;//给P0^0引脚赋别名 void main() //主函数 {LED=0; //P ...

  9. led灯串怎么摆造型_一元包邮的家用LED日光灯泡,究竟是怎么做到的?

    在某电商平台看到在卖的 LED 灯泡,价格令人震惊,1 元包邮! 这邮费都不够吧!好奇做到这价格,究竟是什么用料,什么做工.于是买回来,就为了看看里面的电路.几天后到货了,包装比较简陋,快递单直接贴在 ...

最新文章

  1. 我在 GitHub 上看到了一个丧心病狂的开源项目!治好了我的拖延症
  2. python 每分钟运行一次_调度Python脚本以准确地每小时运行一次
  3. linux 如何运行.sql文件
  4. python如何定义一个简单的队列
  5. 怎么用spss做冗余分析_用SPSS进行医学统计信度分析——【杏花开医学统计】
  6. centos下修改mysql默认端口_CentOS下修改Apache默认端口80
  7. ios程序内发送邮件的代码
  8. CVPR 2020 | 以局部焦点进行渐进式面部表情编辑
  9. 成为 Linux 终端高手的七种武器
  10. [BZOJ 2659] [Beijing wc2012] 算不出的算式
  11. shell command 输入时的快捷键
  12. mysql查询优化not in,mysql not in如何优化
  13. Trick(二)——获取一个网页的 title 信息
  14. Day_05显示鼠标
  15. 转载 侃一侃编译原理的“文法” 作者 :博客网 my笔触
  16. 【3D相册】零基础完成3D相册并配上背景音乐
  17. CentOS7 KVM虚拟化技术 详解
  18. VMware ESXi 7.0 U3 SLIC 2.6 Unlocker 集成 Intel NUC 网卡、USB 网卡和 NVMe 驱动
  19. (原创)[短小精悍系列]RGB(RGI/RGV)颜色明度(亮度)计算公式 (又称灰度公式,彩色照片转黑白照片时能派上用场)
  20. word文档中的毕业论文的页眉与页脚设置

热门文章

  1. 通过Navicat 学术伙伴计划我白嫖了一年Navicat 15
  2. python构造函数指定的参数不起作用,构造类不需要参数的可能原因
  3. 【Flutter】Android、Flutter 折叠屏适配 ( 展开大屏 | 折叠主屏 | 折叠副屏 | 静态展示 | 动态热切换适配 | 拉伸布局 | X 轴自适应适配 | 布局重构 )
  4. mysql ibd 附加_MySQL笔记-ibd文件格式初步分析(仅数据块笔记)
  5. 教钢琴安排指法的基本规律有哪些
  6. php qq远程桌面共享,QQ远程桌面共享
  7. 常用的神经干细胞标记物
  8. 【一颗不甘的心】今天,说说自己 -- 2017/5/17更新
  9. python字体类型arial_Arial Narrow字体是Arial的()
  10. 微信小程序预览多张图片