AKI-H8启动代码实战

启动代码是确保单片机顺利启动的关键,一般都是用汇编语言编写。在32位的系统里面,编写启动代码是一件很困难的事情,这也是为什么U-BOOT,VIVI会非常流行的原因的,但是在单片机编程中启动代码的编写似乎有一个定式:

1:设置向量表

2:初始化寄存器,

3:调用C语言的_main函数

4:创建中断开闭函数_EI(),_DI()(可选)

以上就是这几个步骤,首先要处理的就是向量表,向量表一定是在单片机程序执行的起始位置处(大多数情况下都是0x0000)。它可以看成是一个为硬件提供的指针数组,在特定的时候硬件会通过这个指针数组中指针调用特定的处理。在单片机中,第一个向量最重要,这就是复位向量,也就是启动的时候第一个执行的语句,硬件会把这个位置的数据放到PC指针中,之后的处理就在这个指向的地区了。

   对于H8的向量表,芯片说明书中有介绍,在0x0000到0x00FF之间每个对应的中断都已经定义完毕,找到自己想处理的中断,然后向对应的中断向量中写入自己编写的中断处理函数地址就行了。

 

例如:

.CPU 300HA .SECTION V,CODE,LOCATE=H'000000 .IMPORT _main .IMPORT _usb_int .DATA.L _start .SECTION P,CODE,ALIGN=2 _start: mov.l #H'0FFFF10,er7 mov.l #H'8000, er0 mov.l #H'0FFEF10, er1

 

上面代码就可以看到,程序首先定义了一个V也就是向量表的段,其实编译器并不关心V代表什么意思,只要是一个标识符就行了。LOCATE是制定代码的绝对位置,这个标签可以将汇编代码精确的放到内存的任意的地方。在另一个段P里没有LOCATE,那它把代码放在哪里呢?在5中,我们设置连接脚本的时候定义了P的位置,这个时候的P和那个P的位置信息是一样的,同样我们可以推导出,V也可以在脚本中定义,而不适用LOCATE标签,实际上这是对的而且是推荐的方法,在连接脚本和汇编代码中双重制定位置绝对不是什么好的方法。

 

所以我们修改了脚本代码和初始化代码如下:

脚本代码:

OUTPUT TestH8 PRINT TestH8 INPUT start,main,led_sw,lcd LIB C:/DevelopKit/H8/ASM/c38hab START V(0),C,D,P(200),B,R(0FFEF10) ;定义向量表从0x0000开始 ;静态常数,数据区,代码起始位置都是0x200 ;可变数据区和栈起点为0xFFEF10 ROM (D,R)10 EXIT

 

初始化代码:

  .CPU 300HA .SECTION V,CODE ;向量表中没有对V设置LOCATE .IMPORT _main ;告诉编译器main是外面的一个函数 .DATA.L _start ;向量表,每个DATA.L表示一个长整 ;形,4BYTE,它指向一个叫start的 ;函数 .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error .DATA.L int_error IRQ0: .DATA.L int_error IRQ1: .DATA.L int_error IRQ2: .DATA.L int_error IRQ3: .DATA.L int_error IRQ4: .DATA.L int_error IRQ5: .DATA.L int_error .SECTION P,CODE,ALIGN = 2 _start: mov.l #H'0FFEF10,er7 ;在H8中er7寄存器是保 ;存栈起始地址的 jmp @_main ;因为是用C语言编程没 ;有D段数据,所以不用 ;拷贝到RAM中初始化。int_error: rte .EXPORT __EI, __DI __EI: andc.b #H'3f,ccr rts __DI: orc.b #H'c0,ccr rts .SECTION D,DATA .SECTION B,DATA DATA_END: .RES.W 1 .END

 

 

这样的代码写成后就可以使用C语言编程了,从我们熟悉的main开始。

你可能感兴趣的:(AKI-H8启动代码实战)