SAM8系列单片机及其软件设计
时间:08-31
来源:互联网
点击:
3 混合编程的软件设计
在对SAM8系列单片机进行软件开发过程中,用C语言编程具有开发周期短、可读性强、可移植性好和修改方便等优点,但是C程序反汇编生成的汇编代码往往较长。若直接用汇编语言编程,虽然编制的程序较短,但开发周期长,修改也不方便,所以,较好的解决方法是把程序的框架或主体部分用C语言编写,而将执行效率要求较高的部分用汇编语言来编写。下面主要介绍针对SAM8系列单片机进行混合编程的软件设计方法。
3.1 IAR C语言编译器的函数参数传送规则
IAR C语言编译器规定函数参数传递有2种方式,即寄存器传递和堆栈传递。传递顺序是从左至右,具体采用哪种方式传递取决于函数参数的类型。
IAR C语言编译器把单片机的寄存器分成2组,其中高速暂存器组(R10-R15)中的函数参数由左至右依次传入R15至R10,直至这些寄存器点满,而其余函数参加由堆栈来传递。由迂些寄存器是暂存器,用完就释放掉,所以应用过程中不用保护。第二组为普通寄存器(R1、R4-R9),这组寄存器主要用作寄存器变量和保存中间变量,应用过程不必须对其进行保护,但在C语言函数编写中可以不体现,而由编译器自动完成。
当函数参数为以下2种类型时,应当选用堆栈方式传递:第一种是传递参数为struct或union大于4字节的参数类型。第二种是长度可变函数的未命名参数类型。
函数参数通常放在由堆栈指针指定的位置为起始的主存储器中,被调用函数的参数则由左至右依次存放在被指定的堆栈中,当被调用函数返回调用函数时,堆栈自动清零,主存储器空间被释放,以供下次供传递函数使用。
函数返回值可根据其类型放在R15或R15:R14寄存器对中。若返回值是struct或union类型,则返回R15中的值是存放返回结果的堆栈指针起始位置。
C语言编译器也是编译中断函数时会自动保护所用到的寄存器(包括R10-R15),状态寄存器FLAGS的保护也是在中断处理过程中自动完成的。中断过程中用到的寄存器都使用PUSH Rn的指令进行保护,而采用POP Rn指令恢复。当用IRET指令自动恢复状态寄存器FLAGS时,可以从中断中返回。
3.2 对汇编语言函数的约定
对于一个可以被C语言函数调用的汇编程序来说,使用时必须满足以下3点:
1)符合C语言参数传递规则;
2)有PUBLIC函数入口标志;
3)在C语言函数中用extern声音为外部函数。
参加传递规则和C语言函数一样,所不同的是,要在汇编语言函数编写过程中具体体现出来。
4 应用实例
明确了以上调用规则,混合编程就比较容易了,归纳起来有以下几点:
1)在C语言源文件中用“extern”关键字导入被汇编语言源文件导出的标号;
2)在汇编语言源文件用“PUBLIC”关键字把标号导出到C语言源文件;
3)在汇编语言中用“EXTERN”关键字导入被C语言函数源文件导出的关键字;
4)用C语言把标号导出给汇编语言,这一步不需要关键字;
5)把编辑好的C语言和汇编语言源文件导入设计系统,并用各自调用函数的指令调用。
下面以笔者在校音器设计中用到的2个例子来具体说明。
4.1 C语言和汇编语言相互调用
在该例中,用C语言函数main()调用汇编语言函数get_rand()以得到一个随机数,接着,用汇编语言函数get_rand()调用C语言库函数rand()再得到一个整型机随机数,然后用调用C语言函数mult()的方法把这个随机值的高位乘以main()函数传递给自己的实参,同时把乘积值返回给main()参数。
4.2 汇编语言写中断服务程序
为了提高系统响应速度,设计时往往要求中断服务程序的执行时间较短,执行速度较快。因此,最好的方法就是用汇编语言编写中断服务程序。但要注意以下2点:
1)中断函数不传递参数和返回结果;
2)中断过程中用到的寄存器都要进行保护。
本例中用汇编语言编写看门狗定时器的中断服务程序,而用C语言编写主程序。
![](../img/eec-mcu/mcu-172020etrd5lrm14q.jpg)
5 结束语
以上方法已经应用于笔者参与设计的校音器设计中并取得良好的效果。但也要注意调试过程中编译器选项的设置对程序运行结果有一定的影响,因此,对SAM8系统中不同的核,一定要选用不同的内核版本号,否则,寄存器传递的参数可能会错位,从而导致参数传递错误,给调试带来不便。
在对SAM8系列单片机进行软件开发过程中,用C语言编程具有开发周期短、可读性强、可移植性好和修改方便等优点,但是C程序反汇编生成的汇编代码往往较长。若直接用汇编语言编程,虽然编制的程序较短,但开发周期长,修改也不方便,所以,较好的解决方法是把程序的框架或主体部分用C语言编写,而将执行效率要求较高的部分用汇编语言来编写。下面主要介绍针对SAM8系列单片机进行混合编程的软件设计方法。
3.1 IAR C语言编译器的函数参数传送规则
IAR C语言编译器规定函数参数传递有2种方式,即寄存器传递和堆栈传递。传递顺序是从左至右,具体采用哪种方式传递取决于函数参数的类型。
IAR C语言编译器把单片机的寄存器分成2组,其中高速暂存器组(R10-R15)中的函数参数由左至右依次传入R15至R10,直至这些寄存器点满,而其余函数参加由堆栈来传递。由迂些寄存器是暂存器,用完就释放掉,所以应用过程中不用保护。第二组为普通寄存器(R1、R4-R9),这组寄存器主要用作寄存器变量和保存中间变量,应用过程不必须对其进行保护,但在C语言函数编写中可以不体现,而由编译器自动完成。
当函数参数为以下2种类型时,应当选用堆栈方式传递:第一种是传递参数为struct或union大于4字节的参数类型。第二种是长度可变函数的未命名参数类型。
函数参数通常放在由堆栈指针指定的位置为起始的主存储器中,被调用函数的参数则由左至右依次存放在被指定的堆栈中,当被调用函数返回调用函数时,堆栈自动清零,主存储器空间被释放,以供下次供传递函数使用。
函数返回值可根据其类型放在R15或R15:R14寄存器对中。若返回值是struct或union类型,则返回R15中的值是存放返回结果的堆栈指针起始位置。
C语言编译器也是编译中断函数时会自动保护所用到的寄存器(包括R10-R15),状态寄存器FLAGS的保护也是在中断处理过程中自动完成的。中断过程中用到的寄存器都使用PUSH Rn的指令进行保护,而采用POP Rn指令恢复。当用IRET指令自动恢复状态寄存器FLAGS时,可以从中断中返回。
3.2 对汇编语言函数的约定
对于一个可以被C语言函数调用的汇编程序来说,使用时必须满足以下3点:
1)符合C语言参数传递规则;
2)有PUBLIC函数入口标志;
3)在C语言函数中用extern声音为外部函数。
参加传递规则和C语言函数一样,所不同的是,要在汇编语言函数编写过程中具体体现出来。
4 应用实例
明确了以上调用规则,混合编程就比较容易了,归纳起来有以下几点:
1)在C语言源文件中用“extern”关键字导入被汇编语言源文件导出的标号;
2)在汇编语言源文件用“PUBLIC”关键字把标号导出到C语言源文件;
3)在汇编语言中用“EXTERN”关键字导入被C语言函数源文件导出的关键字;
4)用C语言把标号导出给汇编语言,这一步不需要关键字;
5)把编辑好的C语言和汇编语言源文件导入设计系统,并用各自调用函数的指令调用。
下面以笔者在校音器设计中用到的2个例子来具体说明。
4.1 C语言和汇编语言相互调用
在该例中,用C语言函数main()调用汇编语言函数get_rand()以得到一个随机数,接着,用汇编语言函数get_rand()调用C语言库函数rand()再得到一个整型机随机数,然后用调用C语言函数mult()的方法把这个随机值的高位乘以main()函数传递给自己的实参,同时把乘积值返回给main()参数。
![](../img/eec-mcu/mcu-172019hsivd4rhwgz.jpg)
4.2 汇编语言写中断服务程序
为了提高系统响应速度,设计时往往要求中断服务程序的执行时间较短,执行速度较快。因此,最好的方法就是用汇编语言编写中断服务程序。但要注意以下2点:
1)中断函数不传递参数和返回结果;
2)中断过程中用到的寄存器都要进行保护。
本例中用汇编语言编写看门狗定时器的中断服务程序,而用C语言编写主程序。
![](../img/eec-mcu/mcu-172020etrd5lrm14q.jpg)
5 结束语
以上方法已经应用于笔者参与设计的校音器设计中并取得良好的效果。但也要注意调试过程中编译器选项的设置对程序运行结果有一定的影响,因此,对SAM8系统中不同的核,一定要选用不同的内核版本号,否则,寄存器传递的参数可能会错位,从而导致参数传递错误,给调试带来不便。
单片机 CMOS C语言 LCD ADC AVR 仿真 连接器 编码器 看门狗 相关文章:
- 单片机智能频率信号装置(11-25)
- 单片机在医学信号检测仪中的应用(02-07)
- 单片机应用编程技巧(02-25)
- DSP与单片机通信的多种方案设计(03-08)
- 单片机与PC机串行通信的实现方法 (02-25)
- 单片机与PC通信的简化接口 (05-11)