0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

8位单片机的程序优化

MCU开发加油站 来源:MCU开发加油站 2020-06-15 09:20 次阅读

1、采用短变量

一个提高代码效率的最基本的方式就是减小变量的长度。使用 C 编程时,我们都习惯于对循环控制变量使用 int 类型,这对 8 位的单片机来说是一种极大的浪费,你应该仔细考虑你所声明的变量值可能的范围,然后选择合适的变量类型,很明显,经常使用的变量应该是unsigned char,只占用一个字节。

2、使用无符号类型

为什么要使用无符号类型呢?原因是8051不支持符号运算,程序中也不要使用含有带符号变量的外部代码,除了根据变量长度来选择变量类型外,你还要考虑是否变量是否会用于负数的场合。如果你的程序中可以不需要负数那么把变量都定义成无符号类型的。

3、避免使用浮点指针

在 8 位操作系统上使用 32 位浮点数是得不偿失的。你可以这样做,但会浪费大量的时间,所以当你要在系统中使用浮点数的时候,你要问问自己这是否一定需要,可以通过提高数值数量级和使用整型运算来消除浮点指针,处理ints和longs比处理doubles和floats要方便得多,你的代码执行起来会更快,也不用连接处理浮点指针的模块。如果你一定要,采用浮点指针的话,你应该采用西门子 80517 和达拉斯半导体公司的 80320 这些已经对数,处理进行过优化的单片机。如果你不得不在你的代码中加入浮点指针,那么你的代码长度会增加程序执行速度也会比较慢。如果浮点指针运算能被中断的话,你必须确保要么中断中不会使用浮点指针运算,要么在中断程序前使用 fpsave 指令把中断指针推入堆栈,在中断程序执行后使用 fprestore 指令把指针恢复,还有一种方法是,当你要使用像 sin()这样的浮点运算程序时,禁止使用中断,在运算程序执行完之后再使能它。

4、使用位变量

对于某些标志位应使用位变量而不是 unsigned char,这将节省你的内存,你不用多浪费7位存储区,而且位变量在RAM中访问他们只需要一个处理周期。

5、用局部变量代替全局变量

把变量定义成局部变量比全局变量更有效率,编译器为局部变量在内部存储区中分配存储空间,而为全局变量在外部存储区中分配存储空间,这会降低你的访问速度,另一个避免使用全局变量的原因是你必须在你系统的处理过程中调节使用全局变量,因为在中断系统和多任务系统中,不止一个过程会使用全局变量。

6、为变量分配内部存储区

局部变量和全局变量可被定义在你想要的存储区中,根据先前的讨论,当你把经常使用的变量放在内部 RAM 中时,可使你的程序的速度得到提高,除此之外,你还缩短了你的代码,因为外部存储区寻址的指令相对要麻烦一些考虑到存储速度,按下面的顺序使用存储器DATA IDATA PDATA XDATA,当然你要记得留出足够的堆栈空间。

7、使用特定指针

当你在程序中使用指针时,你应指定指针的类型确定它们指向哪个区域如 XDATA 或CODE 区,这样你的代码会更加紧凑,因为编译器不必去确定指针所指向的存储区,因为你已经进行了说明。

8、使用调令

对于一些简单的操作,如变量循环位移,编译器提供了一些调令供用户使用,许多调令直接对应着汇编指令,而另外一些比较复杂并兼容 ANSI 所有这些调令都是再入函数,你可在任何地方安全的调用他们和单字节循环位移指令 RL A 和 RR A 相对应的调令是_crol_ 循环左移 和_cror_(循环右移)。如果你想对 int 或 long 类型的变量进行循环位移,调令将更加复杂而且执行的时间会更长 对于 int 类型调令为_irol_,_iror_ ,对于 long 类型调令为_lrol_,_lror_。在 C 中也提供了像汇编中 JBC 指令那样的调令_testbit_ ,如果参数位置位他将返回1,否则将返回 0 这条调令在检查标志位时十分有用,而且使 C 的代码更具有可读性调令将直接转换成 JBC 指令。

#include 《instrins.h》void serial_intr(void) interrupt 4 {if (!_testbit_(TI)) { // 是否是发送中断P0=1; // 翻转 P0.0_nop_(); // 等待一个指令周期P0=0;。..}if (!_testbit_(RI)) {test=_cror_(SBUF, 1); // 将SBUF中的数据循环// 右移一位。..}}

9、使用宏替代函数

对于小段代码,像使能某些电路或从锁存器中读取数据,你可通过使用宏来替代函数使得程序有更好的可读性你可把代码定义在宏中,这样看上去更像函数。编译器在碰到宏时,按照事先定义的代码去替代宏,宏的名字应能够描述宏的操作,当需要改变宏时,你只要修该宏定义处。

#define led_on() {led_state=LED_ON; XBYTE[LED_CNTRL] = 0x01;}#define led_off() {led_state=LED_OFF; XBYTE[LED_CNTRL] = 0x00;}#define checkvalue(val) ( (val 《 MINVAL || val 》 MAXVAL) ? 0 : 1 )

宏能够使得访问多层结构和数组更加容易,可以用宏来替代程序中经常使用的复杂语句以减少你打字的工作量且有更好的可读性和可维护性。

10、存储器模式

C51提供了 3 种存储器模式来存储变量、过程参数和分配再入函数堆栈。你应该尽量使用小存储器模式,很少应用系统需要使用其它两种模式,像有大的再入函数堆栈系统那样。一般来说如果系统所需要的内存数小于内部RAM 数时,都应以小存储模式进行编译。在这种模式下 DATA 段是所有内部变量和全局变量的默认存储段,所有参数传递都发生在DATA 段中,如果有函数被声明为再入函数,编译器会在内部 RAM 中为他们分配空间,这种模式的优势就是数据的存取速度很快,但只有120个字节的存储空间供你使用,总共有128个字节,但至少有8个字节被寄存器组使用,你还要为程序调用开辟足够的堆栈。如果你的系统有 256 字节或更少的外部 RAM 你可以使用压缩存储模式。这样一来,如果不加说明,变量将被分配在 PDATA 段中,这种模式将扩充你能够使用的 RAM 数量,对XDATA 段以外的数据存储仍然是很快的,变量的参数传递将在内部 RAM 中进行,这样存储速度会比较快,对 PDATA 段的数据的寻址是通过 R0 和R1进行间接寻址,比使用 DPTR 要快一些在大存储模式中,所有变量的默认存储区是 XDATA 段 Keil C 尽量使用内部寄存器组进行参数传递,在寄存器组中可以传递参数的数量和和压缩存储模式一样,再入函数的模拟栈将在 XDATA中 对 XDATA 段数据的访问是最慢的,所以要仔细考虑变量应存储的位置使数据的存储速度得到优化。

11、混合存储模式

Keil 允许使用混合的存储模式,这点在大存储模式中是非常有用的。在大存储器模式下,有些过程对数据传递的速度要求很高。我就把过程定义在小存储模式寄存器中,这使得编译器为该过程的局部变量在内部 RAM中分配存储空间,并保证所有参数都通过内部 RAM进行传递。尽管采用混合模式后编译的代码长度不会有很大的改变,但这种努力是值得的就像能在大模式下把过程声明为小模式一样,你像能在小模式下把过程声明为压缩模或大模式,这一般使用在需要大量存储空间的过程上,这样过程中的局部变量将被存储在外部存储区中,你也可以通过过程中的变量声明,把变量分配在 XDATA 段中。

12、运行库

运行库中提供了很多短小精悍的函数,你可以很方便的使用他们,你自己很难写出更好的代码了。值得注意的是库中有些函数不是再入函数,如果在执行这些函数的时候被中断,而在中断程序中又调用了该函数,将得到意想不到的结果。而且这种错误很难找出来,最好禁止使用这些函数的中断。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6025

    文章

    44418

    浏览量

    630468
  • 操作系统
    +关注

    关注

    37

    文章

    6597

    浏览量

    122984
  • 变量
    +关注

    关注

    0

    文章

    607

    浏览量

    28282

原文标题:8位单片机的程序优化

文章出处:【微信号:mcugeek,微信公众号:MCU开发加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    性价比高的8单片机有哪些?

    单片机作为电子产品的核心主控芯片,广泛应用于家用电器、智能仪表、工业控制、汽车电子、安防监控等多个领域。英锐恩科技小编将介绍几款在市场上表现突出的高性价比8单片机,帮助电子产品开发工
    发表于 09-27 14:27

    国产主流8单片机-RISC架构精简指令集单片机

    、仪器仪表、汽车电子、物联网等领域电子产品的应用 英锐恩科技的8单片机采用RISC架构设计,优化了指令执行流程,显著提升了处理效率。此外,结合高可靠性和低成本,EN
    发表于 09-27 10:15

    低功耗8单片机:技术特性与应用前景!

    不必要的能耗。 优化指令集:通过高效的指令集设计,减少执行任务所需的时钟周期,从而降低能耗。 2. 8数据总线 8
    发表于 09-26 14:09

    8单片机,32单片机编程和应用优势

    的微型计算机系统,英锐恩科技的电子工程师小编老唐将从灵活性、成本效益、开发效率、应用广泛性等方面进行详细阐述8单片机,32单片机编程和应
    发表于 09-26 11:45

    MCU前沿市场趋势:8单片机和32单片机

    的处理能力,所需的接口程度以及对于电池供电的设计的所有重要功耗曲线,仔细确定对MCU的要求。毫无疑问,32单片机8设备具有更高的性能,但是工程师面临传统的选择,即在市场上最好的设
    发表于 09-24 17:47

    8单片机为何不会被高端单片机取代?

    的控制器选择。 (1)架构:8单片机通常采用冯诺依曼架构,其中程序和数据存储器共享一条公共总线。它们还有一个哈佛架构,程序和数据存储器是
    发表于 09-24 16:51

    8单片机,32单片机就找英锐恩!

    深圳市英锐恩科技有限公司创立于 2008 年,是一家从事单片机及模拟器件电路芯片应用、设计研发、销售一体的国家高新技术半导体企业。 英锐恩科技公司凭着自身在半导体电子行业MCU(8单片机
    的头像 发表于 09-23 10:32 182次阅读

    单片机烧录程序的基本步骤是什么

    单片机烧录程序单片机开发过程中非常重要的一步,它涉及到将编写好的程序代码通过一定的方式传输到单片机内部的存储器中,使
    的头像 发表于 09-02 09:47 418次阅读

    8单片机为何不会过时?

    对于8单片机来说,由于其主要处理8数据,所以其“字”的长度可能也是8
    的头像 发表于 03-20 16:29 1456次阅读

    51单片机8数码管显示学号程序编写思路

    51单片机是一种非常经典的单片机型号,具有广泛的应用领域。我们可以利用51单片机的IO口来控制8数码管的显示,实现学号的显示功能。下面提供
    的头像 发表于 01-04 15:21 5764次阅读

    pic单片机汇编程序实例

    以下是一个简单的PIC单片机汇编程序示例,这个程序将实现一个LED闪烁的功能。 首先,我们需要了解PIC单片机的结构和指令集。PIC单片机
    的头像 发表于 12-14 11:01 1561次阅读

    8和32单片机的区别

    要搞懂这个问题,首先要搞明白8或32说的是单片机的哪一个部件。
    发表于 11-30 09:48 829次阅读
    <b class='flag-5'>8</b><b class='flag-5'>位</b>和32<b class='flag-5'>位</b><b class='flag-5'>单片机</b>的区别

    一颗8的51单片机是如何处理32数据的?

    一颗8的51单片机是如何处理32数据的? 首先,需要明确一点,即51单片机8
    的头像 发表于 11-06 11:05 2081次阅读

    一颗8的51单片机是如何处理32数据的?

    如果你曾经跟小编一样好奇过一颗8的51单片机是如何处理32数据的,那么你来对地方了。本文将揭开单片机这个神秘领域的面纱,具体探讨它们如何
    的头像 发表于 10-30 11:26 1924次阅读

    AVR单片机为何能成为8中的佼佼者?

    AVR单片机为何能成为8中的佼佼者? AVR单片机是一种高性能、低功耗、高可靠性、方便编程的微控制器。它可以广泛应用于消费电子、汽车电子
    的头像 发表于 10-29 17:29 636次阅读