打印
[STM8]

STM8的C语言编程(1)--基本程序与启动代码分析

[复制链接]
2400|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
vigous1|  楼主 | 2015-2-26 16:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
现在几乎所有的单片机都能用C语言编程了,采用C语言编程确实能带来很多好处,至少可读性比汇编语言强多了。
在STM8的开发环境中,可以通过新建一个工程,自动地建立起一个C语言的框架,生成后开发环境会自动生成2个C语言的程序,一个是main.c,另一个是stm8_interrupt_vector.c。main.c中就是一个空的main()函数,如下所示:
/*MAIN.C file
*
*Copyright (c) 2002-2005 STMicroelectronics
*/
main()
{
      while (1);
}
而在stm8_interrupt_vector.c中,就是声明了对应该芯片的中断向量,如下所示:
/*   BASIC INTERRUPT VECTOR TABLE FOR STM8 devices
*  Copyright (c) 2007 STMicroelectronics
*/
typedefvoid @far (*interrupt_handler_t)(void);
structinterrupt_vector {
      unsigned char interrupt_instruction;
      interrupt_handler_t interrupt_handler;
};
@far@interrupt void NonHandledInterrupt (void)
{
      /* in order to detect unexpected events during development,
         it is recommended to set a breakpoint on the following instruction
      */
      return;
}
externvoid _stext();     /* startup routine */
structinterrupt_vector const _vectab[] = {
      {0x82, (interrupt_handler_t)_stext}, /* reset */
      {0x82, NonHandledInterrupt}, /* trap  */
      {0x82, NonHandledInterrupt}, /* irq0  */
      {0x82, NonHandledInterrupt}, /* irq1  */
      {0x82, NonHandledInterrupt}, /* irq2  */
      {0x82, NonHandledInterrupt}, /* irq3  */
      {0x82, NonHandledInterrupt}, /* irq4  */
      {0x82, NonHandledInterrupt}, /* irq5  */
      {0x82, NonHandledInterrupt}, /* irq6  */
      {0x82, NonHandledInterrupt}, /* irq7  */
      {0x82, NonHandledInterrupt}, /* irq8  */
      {0x82, NonHandledInterrupt}, /* irq9  */
      {0x82, NonHandledInterrupt}, /* irq10 */
      {0x82, NonHandledInterrupt}, /* irq11 */
      {0x82, NonHandledInterrupt}, /* irq12 */
      {0x82, NonHandledInterrupt}, /* irq13 */
      {0x82, NonHandledInterrupt}, /* irq14 */
      {0x82, NonHandledInterrupt}, /* irq15 */
      {0x82, NonHandledInterrupt}, /* irq16 */
      {0x82, NonHandledInterrupt}, /* irq17 */
      {0x82, NonHandledInterrupt}, /* irq18 */
      {0x82, NonHandledInterrupt}, /* irq19 */
      {0x82, NonHandledInterrupt}, /* irq20 */
      {0x82, NonHandledInterrupt}, /* irq21 */
      {0x82, NonHandledInterrupt}, /* irq22 */
      {0x82, NonHandledInterrupt}, /* irq23 */
      {0x82, NonHandledInterrupt}, /* irq24 */
      {0x82, NonHandledInterrupt}, /* irq25 */
      {0x82, NonHandledInterrupt}, /* irq26 */
      {0x82, NonHandledInterrupt}, /* irq27 */
      {0x82, NonHandledInterrupt}, /* irq28 */
      {0x82, NonHandledInterrupt}, /* irq29 */
};

沙发
vigous1|  楼主 | 2015-2-26 16:27 | 只看该作者
在stm8_interrupt_vector.c中,除了定义了中断向量表外,还定义了空的中断服务程序,用于那些不用的中断。当然在自动建立时,所有的中断服务都是空的,因此,除了第1个复位的向量外,其它都指向那个空的中断服务函数。
生成框架后,就可以用Build菜单下的RebuildAll对项目进行编译和连接,生成所需的目标文件,然后就可以加载到STM8的芯片中,这里由于main()函数是一个空函数,因此没有任何实际的功能。不过我们可以把这个框架对应的汇编代码反出来,看看C语言生成的代码,这样可以更深入地了解C语言编程的特点。
生成的代码包括4个部分,如图1、图2、图3、图4所示。
                          图1
                        图2

使用特权

评论回复
板凳
vigous1|  楼主 | 2015-2-26 16:31 | 只看该作者
图3



图4

使用特权

评论回复
地板
vigous1|  楼主 | 2015-2-26 16:31 | 只看该作者
图1显示的是从内存地址8000H开始的中断向量表,中断向量表中的第1行82008083H为复位后单片机运行的第1跳指令的地址。从表中可以看出,单片机复位后,将从8083H开始运行。其它行的中断向量都指向同一个位置的中断服务程序80D0H。
   图2显示的是3个字节,前2个字节8083H为复位后的第1条指令的地址,第3个字节是一个常量0,后面的启动代码要用到。
   图3显示的是启动代码,启动代码中除了初始化堆栈指针外,就是初始化RAM单元。由于目前是一个空的框架,因此在初始化完堆栈指针(设置成0FFFH)后,由于8082H单元的内容为0,因此程序就跳到了80B1H,此处是一个循环,将RAM单元从0到5初始化成0。然后由于寄存器X设置成0100H,就直接通过CALL main进入C的main()函数。
   图4显示的是main()函数和中断服务函数,main()函数对应的代码就是一个无限的循环,而中断服务函数就一条指令,即中断返回指令。

   通过分析,可以看出用C语言编程时,比汇编语言编程时,就是多出了一段启动代码。

使用特权

评论回复
5
mmuuss586| | 2015-2-26 20:35 | 只看该作者

STM8我用的不多,支持下;

使用特权

评论回复
6
x383709024x| | 2015-2-27 10:52 | 只看该作者
汇编看的有点迷糊

使用特权

评论回复
7
搞IT的| | 2015-2-28 18:28 | 只看该作者
图1 不是很懂,楼主可以说明白点吗

使用特权

评论回复
8
wxs732| | 2016-3-15 14:09 | 只看该作者
绝对经典啊,

使用特权

评论回复
9
鹏鹏车| | 2017-3-14 19:47 | 只看该作者
学习了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

427

帖子

15

粉丝