现在几乎所有的单片机都能用 C 语言编程了,采用 C 语言编程确实能带来很多好处,至少可读性比汇编语言强多了。在 STM8 的开发环境中,可以通过新建一个工程,自动地建立起一个 C 语言的框架,生成后开发环境会自动生成 2 个 C 语言的程序,一个是 main.c ,另一个是 stm8_interrupt_vector.c 。main.c 中就是一个空的 main() 函数,如下所示:
在 stm8_interrupt_vector.c 中,除了定义了中断向量表外, 还定义了空的中断服务程序, 用于那些不用的中断。当然在自动建立时,所有的中断服务都是空的,因此,除了第 1 个复位的向量外,其它都指向那个空的中断服务函数。生成框架后,就可以用 Build 菜单下的 Rebuild All 对项目进行编译和连接,生成所需的目标文件,然后就可以加载到 STM8 的芯片中,这里由于 main() 函数是一个空函数,因此没有任何实际的功能。不过我们可以把这个框架对应的汇编代码反出来,看看 C 语言生成的代码,这样可以更深入地了解 C 语言编程的特点。
图 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 设置成 01 00H ,就直接通过 CALL main 进入 C 的 main() 函数。图 4 显示的是 main() 函数和中断服务函数, main() 函数对应的代码就是一个无限的循环, 而中断服务函数就一条指令,即中断返回指令。通过分析,可以看出用 C 语言编程时,比汇编语言编程时,就是多出了一段启动代码。
STM8 单片机的时钟源非常丰富,芯片内部既有 16MHZ 的高速 RC 振荡器,也有 128KHZ 的低速 RC 振荡器,外部还可以接一个高速的晶体振荡器。在系统运行过程中,可以根据需要,自由地切换。单片机复位后,首先采用的是内部的高速 RC 振荡器,且分频系数为 8,因此 CPU 的上电运行的时钟频率为 2MHZ 。切换时钟源,主要涉及到的寄存器有:主时钟切换寄存器 CLK_SWR 和切换控制寄存器 CLK_SWCR 。主时钟切换寄存器的复位值为 0xe1 ,表示切换到内部的高速 RC 振荡器上。当往该寄存器写入 0xb4 时,表示切换到外部的高速晶体振荡器上。在实际切换过程中,应该先将切换控制寄存器中的 SWEN (第 1 位)设置成 1,然后设置 CLK_SWC R 的值,最后要判断切换控制寄存器中的 SWIF 标志是否切换成功。下面的实验程序首先将主时钟源切换到外部的晶体振荡器上, 振荡频率为 8MHZ ,然后, 然后快速闪烁 LED 指示灯。接着,将主时钟源又切换到内部的振荡器上,振荡频率为 2MHZ ,然后再慢速闪烁 LED 指示灯。通过观察 LED 指示灯的闪烁频率,可以看到,同样的循环代码,由于主时钟源的改变的改变,闪烁频率和时间长短都发生了变化。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !