6:编写启动代码
启动代码是确保芯片顺利启动的关键,一般都是用汇编语言编写。在单片机编程中启动代码的编写似乎有一个定式,就是先设置向量表,然后写一段初始化代码,最后调用C语言的_main函数。首先要处理的就是向量表,向量表一定是在单片机程序执行的起始位置处(大多数情况下都是0x0000)。它可以看成是一个为硬件提供的指针数组,在特定的时候硬件会通过这个指针数组中指针调用特定的处理。在单片机中,第一个向量最重要,这就是复位向量,也就是启动的时候第一个执行的语句,硬件会把这个位置的数据放到PC指针中,之后的处理就在这个指向的地区了。
对于H8的向量表,芯片说明书中有介绍
这张粗略的图上告诉我们的东西不多,第一就是复位中断是在0x0000位置,第二就是整个中断向量表为0x00F3大小,即代码不得写在这个区域。
关于实现向量表,使用汇编往往会很方便,因为汇编可以主动的设置代码的内存地址,将预设好的代码指定到0x0000开头的区域就可以成功设置好向量。
下面的一段代码就是启动代码
1 .CPU 300HA
2 .SECTION V,CODE,LOCATE=H'000000
3 .IMPORT _main
4 .IMPORT _usb_int
5
6 .DATA.L _start
7
8 .SECTION P,CODE,ALIGN=2
9 _start:
10 mov.l #H'0FFFF10,er7
11 mov.l #H'8000, er0
12 mov.l #H'0FFEF10, er1
所以我们修改了脚本代码和初始化代码如下
1 OUTPUT TestH8
2 PRINT TestH8
3 INPUT start,main,led_sw,lcd
4 LIB C:\DevelopKit\H8\ASM\c38hab
5 START V(0),C,D,P(200),B,R(0FFEF10)
6 ;定义向量表从0x0000开始
7 ;静态常数,数据区,代码起始位置都是0x200
8 ;可变数据区和栈起点为0xFFEF10
9 ROM (D,R)
10 EXIT
1 .CPU 300HA
2 .SECTION V,CODE ;向量表中没有对V设置LOCATE的代码
4 .IMPORT _main ;告诉编译器main是外面的一个函数
5 .DATA.L _start ;向量表,每个DATA.L表示一个长整
6 ;形,4BYTE,它指向一个叫start的
7 ;函数
8 .DATA.L int_error
9 .DATA.L int_error
10 .DATA.L int_error
11 .DATA.L int_error
12 .DATA.L int_error
13 .DATA.L int_error
14 .DATA.L int_error
15 .DATA.L int_error
16 .DATA.L int_error
17 .DATA.L int_error
18 .DATA.L int_error
19 IRQ0: .DATA.L int_error
20 IRQ1: .DATA.L int_error
21 IRQ2: .DATA.L int_error
22 IRQ3: .DATA.L int_error
23 IRQ4: .DATA.L int_error
24 IRQ5: .DATA.L int_error
25
26 .SECTION P,CODE,ALIGN = 2
27 _start:
28 mov.l #H'0FFEF10,er7 ;在H8中er7寄存器是保
29 ;存栈起始地址的
30 jmp @_main ;因为是用C语言编程,没
31 ;有D段数据,所以不用拷
32 ;贝到RAM中初始化。
33 int_error:
34 rte
35
36 .EXPORT _EnableInterrupt, _DisableInterrupt
37
38 _EnableInterrupt:
39 andc.b #H'3f,ccr
40 rts
41
42 _DisableInterrupt:
43 orc.b #H'c0,ccr
44 rts
45
46 .SECTION D,DATA
47 .SECTION B,DATA
48
49 DATA_END: .RES.W 1
50 .END
51
初始代码写好后就可以写C代码了。
(以上)