没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
STM8 与汇编语言(1)
不知是心血来潮,还是其它因素,突然又想起玩汇编语言了。这几年也没
少跟单片机打交道,包括 51 系列,430 系列,ARM 系列,但都是用 C 语言来
开发。不过由于使用 C 语言,实际上对这些 CPU 的了解还是不够深刻,当然
除了 51 之外,因为那是我多年前曾经用汇编开发过的芯片。尽管当今 C 语言
已经在嵌入式产品的开发过程中成为主流,但我个人依然认为,要想真正了解
CPU 的特点,还得用汇编语言。不知道这种观点是对还是错,也许是因为自己
从硬件做起,写过机器码,用汇编语言做过优化,因此对汇编语音有一种特殊
的偏爱。
51 系列的芯片用多了,感觉有时写起程序来不太方便,因此总想寻找一些
其它的 8 位单片机玩玩,正好手头有一个 ST 的三合一开发板,那是 09 年参加
ST 研讨会上买的,一直躺在那里,与其躺在那里,不如拿出来玩玩。
这几年,ST 在国内推广 STM32,力度不小,不过我一直没有用过,只是
初步地看看资料。原因在于在 32 位单片机方面,我一直在用 Luminary 公司的
LM3S1138,感觉不错,一直都很顺利。09 年 ST 举办的研讨会上,ST 除了介
绍 STM32 外,也介绍了 STM8,当时听了以后,觉得还行。尤其是会上的低功
耗演示给我留下了很深刻的印象。
基于这些,我决定好好地玩一下 STM8 芯片,并将玩的结果拿出来与大家
共享。
STM8 与汇编语言(2)
第一次打开 STM8 的手册时发现,CPU 中的寄存器只有 6 个,即
A、X、Y、SP、PC 和 CC。这几个寄存器,看上去特象早年苹果机使用的微处
理器 6502。在眼下都是多寄存器的 RISC 潮流下,不知 ST 推出的这种 CPU 架
构有什么意图?这样的芯片能否与 Microchip 或者 Atmel 的 RISC 结构的 MCU
竞争呢?在此我无意做评论,我只想了解这颗芯片。
通过仔细研究,我发现由于 STM8 采用了 32 位宽度的程序存储器结构,使
得大部分的指令都能在一个周期内取出,并且采用了哈佛结构和流水线,相当
多的指令也都是单周期完成的。这样的话,虽然 CPU 是 CISC 架构的,但也基
本上达到了单周期指令的效果,就像手册上说的,CPU 的性能达到了
20MISP◎24MHZ。就这一点来说,我个人感觉 STM8 还真不错。
举个例子来说,如果我们要完成内存中的 2 个 8 位无符号数相加,结果还
保存到内存中,用 C 语言描述成:
unsigned char a,b,c;
c = a + b;
这一段程序,用 STM8 汇编可以写成如下代码:
LDA, $1000
ADDA, $1001
LD$1002, A
这里假设 a,b,c 这 3 个变量分别存储在内存中,地址为 1000,1001 和
1002。从 STM8 的手册上可以查到,这 3 条指令都是单周期的,完成一个加法,
只需要 3 个时钟周期,可见 STM8 的 CPU 执行速度还是相当快的。
在这种传统的所谓 CISC 架构中,我特别关心累加器 A 与内存的访问速度,
因为如果累加器与内存的访问速度是单周期的话,实际上我们就可以将内存当
寄存器来看,这样写程序时就相当于拥有了一个大的寄存器阵列,或者说我们
也就没必要再去考虑变量在内存中还是在寄存器中。也正是因为这一点,我对
STM8 越来越感兴趣了。
STM8 与汇编语言(3)
STM8 的开发环境用起来还是不错的,可以到 ST 的网站上下载安装程序
ST_Toolset.exe。利用该环境可以开发用汇编语言写的程序,而且与 ST 的三
合一开发板配合起来,确实非常方便。
不过如果要想用 C 语言来开发,稍微有点麻烦,得去别的公司下载 C 的编
译器(CXSTM8_16K.exe),而且下载完以后,还得去注册,等待许可文件。
实际上,我也按照 ST 介绍的方法做了,但始终都没有收到许可文件,也许本
人实在愚笨。但不管怎么说,我觉得 ST 这一点做得相当不好,实在有点抠门。
既然是免费的,为什么不一起打包提供给客户,这么麻烦,多耽误客户使用,
得少卖多少 STM8 的芯片。
言归正传,还回到正题。用汇编语言开发程序,最简单的就是利用 ST 开
发环境中提供的汇编程序框架自动生成功能。打开开发环境后,在 File 菜单中
选择 New Workspace,点击 Create workspace and project 图标,然后就可以建
立项目,在工具链中选 ST Assembler Linker,最后选择 MCU 的型号,点击
OK,就完成了一个项目的建立。这个环境与微软的 VC6 开发环境很象,点开
项目文件中的 Source Files,能看到系统自动生成好了一个汇编语言的框架,
我们编写程序只要在这框架基础上就可以了。其实不用编写任何一条指令,这
个框架程序是能够编译通过,并下载运行的。
自动生成的项目中包含 3 个重要的文件:mapping.inc,mapping.asm 和
main.asm。
mapping.inc 文件中定义的是一些常量,mapping.asm 文件中定义的是一
些内存的分配,主要的汇编代码都在 main.asm。
下面是 main.asm 中的汇编代码及注释。
stm8/
#include "mapping.inc"
segment 'rom'
;下面是定义一个标号,ST 汇编的写法,有点不习惯
;这里的 main 标号是复位后的第一条指令,与后面的中断向量表中
;的名字是对应的
main.l
; initialize SP
ldw X,#stack_end
ldw SP,X;设置堆栈指针
#ifdef RAM0
;如果定义了 RAM0,则要汇编以下代码’
; clear RAM0
ram0_start.b EQU $ram0_segment_start
ram0_end.b EQU $ram0_segment_end
ldw X,#ram0_start;寄存器 X 指向要清除的内存起始地址’’’
clear_ram0.l;这是一个标号定义,用于后面的跳转指令
clr (X);对应的内存单元清 0
incw X;寄存器 X+1,指向下一个单元’’
cpw X,#ram0_end;比较寄存器 X 是否等于内存的最后一个地址’
jrule clear_ram0;若不等于,则循环
#endif
#ifdef RAM1
;如果定义了 RAM1,则要汇编以下代码,代码含义与上面完全一样’
; clear RAM1
ram1_start.w EQU $ram1_segment_start
ram1_end.w EQU $ram1_segment_end
ldw X,#ram1_start
clear_ram1.l
clr (X)
incw X
cpw X,#ram1_end
jrule clear_ram1
#endif
; clear stack
;将堆栈区的内存单元清 0,代码含义与上面完全一样’
stack_start.w EQU $stack_segment_start
stack_end.w EQU $stack_segment_end
ldw X,#stack_start
clear_stack.l
clr (X)
incw X
cpw X,#stack_end
jrule clear_stack
infinite_loop.l;定义一个标号
;由于是一个框架,初始化内存后,进入一个死循环
jra infinite_loop
;下面代码写的是一段中断服务程序,不过也是空的
interrupt NonHandledInterrupt
NonHandledInterrupt.l
;当进入中断服务程序后,无其它动作,直接返回
iret
;下面这张表很重要,定义了 STM8 所有的硬件中断对应的中断
;服务程序的入口地址
segment 'vectit'
dc.l {$82000000+main}; reset
dc.l {$82000000+NonHandledInterrupt}; trap
dc.l {$82000000+NonHandledInterrupt}; irq0
dc.l {$82000000+NonHandledInterrupt}; irq1
dc.l {$82000000+NonHandledInterrupt}; irq2
dc.l {$82000000+NonHandledInterrupt}; irq3
dc.l {$82000000+NonHandledInterrupt}; irq4
dc.l {$82000000+NonHandledInterrupt}; irq5
dc.l {$82000000+NonHandledInterrupt}; irq6
dc.l {$82000000+NonHandledInterrupt}; irq7
dc.l {$82000000+NonHandledInterrupt}; irq8
dc.l {$82000000+NonHandledInterrupt}; irq9
dc.l {$82000000+NonHandledInterrupt}; irq10
dc.l {$82000000+NonHandledInterrupt}; irq11
dc.l {$82000000+NonHandledInterrupt}; irq12
dc.l {$82000000+NonHandledInterrupt}; irq13
dc.l {$82000000+NonHandledInterrupt}; irq14
dc.l {$82000000+NonHandledInterrupt}; irq15
dc.l {$82000000+NonHandledInterrupt}; irq16
dc.l {$82000000+NonHandledInterrupt}; irq17
dc.l {$82000000+NonHandledInterrupt}; irq18
dc.l {$82000000+NonHandledInterrupt}; irq19
dc.l {$82000000+NonHandledInterrupt}; irq20
dc.l {$82000000+NonHandledInterrupt}; irq21
dc.l {$82000000+NonHandledInterrupt}; irq22
dc.l {$82000000+NonHandledInterrupt}; irq23
dc.l {$82000000+NonHandledInterrupt}; irq24
dc.l {$82000000+NonHandledInterrupt}; irq25
dc.l {$82000000+NonHandledInterrupt}; irq26
dc.l {$82000000+NonHandledInterrupt}; irq27
dc.l {$82000000+NonHandledInterrupt}; irq28
dc.l {$82000000+NonHandledInterrupt}; irq29
end
把这个项目 Build 后,点击 Debug 中的 Start Debugging 就可以将程序下
载到 ST 的三合一板上了,然后点击 Run,程序就运行起来了,不过由于框架
程序是一个空程序,初始化内存后就进入死循环了,因此什么效果也看不见。
因此我们必须在框架程序的基础上,编写自己的程序。后面的程序例子都是在
这个框架程序的基础上编写的。
STM8 与汇编语言(4)
今天要做的实验是在 ST 的三合一开发板上,用汇编语言写一个程序,驱
动板上的 LED 指示灯闪烁。
开发板上的 LED1 接在 STM8 的 PD3 上,因此要将 PD3 设置成输出模式,
为了提高高电平时的输出电流,要将其设置成推挽输出方式。这主要通过设置
对应的 DDR/CR1/CR2 寄存器实现。
还是利用 ST 的开发工具,先生成一个汇编程序的框架,然后修改其中的
main.asm,修改后的代码如下。
编译通过后,下载到开发板,运行程序,可以看到 LED1 在闪烁,且闪烁
的频率为 5HZ。
剩余63页未读,继续阅读
资源评论
老帽爬新坡
- 粉丝: 83
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功