您好, 访客   登录/注册

单片机C语言编程的多位乘法运算分析

来源:用户上传      作者:

  摘要:C语言作为一种结构化的程序设计语言,其不但具有高级语言的相关特点,还具有汇编语言的相关功能,其能够直接对计算机的硬件进行很好的操作。C语言不但具备丰富的库函数,还具有较强的功能性、较好的移植性、较快的运算速度和较高的编译效率,所以成了单片机系统最为常用的编程语言。在单片机性能不断提高的情况下,C语言编程方法的应用,成为开发出优秀单片机系统的关键,同时对于编程者而言,C语言编程方法也具有十分重要的作用。对于单片机而言,在使用[C51]进行多字节乘法运算时,常常会忽略相应的问题。本作者对该问题出现的原因进行了分析,并提出了相应的解决办法。同时本文对单片机C语言的概念和特点进行了概述,并对单片机C语言编程的优点进行了分析,探讨了单片机C语言编程的多位乘法运算编程方法。
  关键词:单片机;C语言;编程;多位乘法运算
  中图分类号:TP3      文献标识码:A
  文章编号:1009-3044(2019)24-0242-02
  开放科学(资源服务)标识码(OSID):
  单片机作为一种典型的嵌入式微控制器,具有多种构成组件,其整体相当于一个微型的计算机,目前单片机已经普遍应用到我们生活的各个领域,尤其是在工业领域中,单片机的应用更为广泛。在教育领域中,单片机也是相关专业必学的课程,其中就涉及较多的编程语言,在众多的编程语言中,C语言成为单片机最重要的编程语言,在单片机系统中,常常会应用到多种算法,而本文的研究主要在于单片机多位乘法的算法分析和编程方法。C语言作为一种重要的结构化的程序设计语言,具有较强的功能性、结构性和较好移植性等特点,这也使得其成为单片机系统的编程语言。本文的研究中利用到了[C51]进行单片机系统的开发,其继承了C语言强大的表达数据的能力,并且具有丰富的运算符、强大的数据处理能力和数学运算库函数,能够方便解决复杂的数学运算。
  1 单片机C语言及特点概述
  单片机C语言也具有高级语言的功能以及完善的模块化程序结构,能够为单片机软件系统的开发提供有力的保障,对于C语言存在的编译资源有限的情况,单片机C语言能够很好地解决这类问题。单片机C语言能够提供较为复杂的数据类型,能够极大增强相关程序的处理能力和灵活性,同时能够有效利用单片机上有限的RAM资源空间,对相应的数据进行专业性的处理,从而有效避免单片机系统在运行期间出现非异步的破坏[1]。
  单片机C语言能够提供常用的标准函数库,用户可以进行直接使用,相关程序员在进行编程的时候,不需要仔细了解单片机的相关指令集,就可以编写出完美并符合硬件实际需求的单片机程序。使用单片机C语言进行程序的编写,要比使用汇编语言方便得多,编程人员不需要与硬件进行相应的接触,只需要考虑相应的功能和算法,这就极大地减少了系统开发和调试的时间。单片机C语言具有良好的程序结构,非常适合于模块化程序的设计,在进行单片机应用系统程序设计时,相关编程设计人员应该尽可能地使用结构化的程序设计方法,将单片机系统功能模块化,通过使用不同的模块来完成不同的功能,这样能够使得单片机系统具有十分清晰的程序结构,也方便后期的调试和维护。对于不同功能的模块而言,其具有相对应的入口参数和出口参数,对于需要重复调用的程序可以将其编写成相应的函数,这样不但能够减少程序代码的长度,同时也便于管理整个程序,增强程序的可读性和移植性。
  2 单片机C语言编程的优点分析
  2.1 单片机C语言的数据类型
  单片机C语言编译器能够支持多种类型的数据,其相关的数据类型一般包括char类型、long长整型、sft特殊功能寄存器、float浮点型以及int整型等等。使用sft特殊功能寄存器,能够对单片机内部的所有特殊功能寄存器进行相应的访问。单片机C语言编程一般与程序存储器进行结合,而程序的存储器一般体现出单片机系统资源的有限性[2]。对于浮点型数据而言,一般需要具有相应的内部程序或者函数进行支持,但在一定程度上会生成较长的代码,因此在进行单片机系统程序的编写时,相关编程人员要尽可能多地使用char和int等数据类型,并且减少程序中使用到的数据类型,通过合理选择应用的数据类型,可以有效减少程序中生成的代码长度。
  2.2 单片机C语言的算法描述
  一般控制结构和原操作构成一个算法,两者的综合效果决定着该算法的执行时间,对于同一个算法而言,如果相关编程语言的级别越高,那么其执行的效率就越低。由于单片机资源存在的限制,单片机C语言不仅要考虑程序的相关具体功能,还要考虑程序代码的长度。程序的算法的长度不是越短越好,这需要根据其调用的子程序和函数来决定,在进行程序设计的时候,一般采取一些优化算法以减少代码的生成长度。
  2.3 数据存储器的分配
  对于单片机的数据存储器而言,其是由读写存储器RAM组成,该存储器可以进行相应的扩容,能够对实时输入的数据进行储存。在存储器的实际应用中,应该首先使用内部的存储器,单片机C语言采用的是存储器的覆盖技术,所以在进行程序连接的时候,可以对存储器空间的一些程序段进行释放,重新定义给另一个程序段使用。对于在程序开始处就定义的全局变量,其作用域是整个程序,所以不能够被释放,同样的对于静态存储变量,在程序运行期间其存储空间固定不变,其在函数的调用中具有专用性,所以也不能够被释放,能够被释放的只有局部变量中的动态变量,所以在进行程序设计的时候,要尽可能地使用局部变量。
  2.4 單片机C语言的代码优化
  存储期一般包含三种不同的模式,其中SMALL是小模式,所有的变量都存储在一定额地址范围内,该模式能够将所有的变量定义为data类型的内存。不同的模式会对程序代码的长度和执行的速度产生直接的影响,当程序中需要应用到较多的变量时,可以在存储器空间中存放部分变量,使用编译器对相关变量进行定位后,可能会增加代码的长度,影响到程序的执行效率,这时候就可以将很少访问的变量定义为xdata类型,并将其存放在外部的RAM中。   3 单片机C语言编程中多位乘法运算分析
  3.1 单片机C语言编程中多位乘法运算问题的提出
  在[C51]编译器中,其能够直接支持不同数据类型的变量,比如bit类型、char类型等,而两个unsigned char类型的数据进行相乘,也正好符合汇编指令中的“MUL AB”。使用[C51]进行多位乘法运算编程,在这个过程中只需要使用相应的乘法表达式进行编译就行,只要通过相应的编译,[C51]就可以自动寻找相应的存储器并且把运行的结果存放在存储器空间中[3]。所以在使用[C51]进行乘法运算的时候,编程人员只需要编写一个乘法表达式并且将乘积的结果赋值给一个存储单元就可以,但是如果乘法运算中的乘数不是unsigned char类型的变量,及时乘法表达式再简单,也需要调用[C51]中的库函数;而如果乘法运算中的乘数是大于255的常量,[C51]就会将这个乘数以对应的类型自动存储起来。对于大于255的常量而言,因为unsigned char类型的变量是8位的,所以其和其他类型的变量一样需要调用[C51]的库函数,所以在这种情况下,如果还是用乘法表达式进行相应的编译,那么得到的运算结果就有可能和实际的结果存在一定的差异。例如下面一段程序,其运行之后的结果gg的值不等于[9?10000]所得的值。
  #include <AT89X52.H>
  main()
  {
  Unsigned char aa;
  Unsigned long gg;
  aa=9;
  gg=([aa?10000]);   }
  3.2 关于问题的分析
  在使用[C51]编译器进行相应的优化处理时,往往希望用工作寄存器来存储相应的局部变量,按照[C51]的相关存储规则,程序在执行aa=9语句时,可以得到的结果为[R7=9],在执行[aa?10000]时,根据[C51]的要求,进行算数运算的数据类型需要相同时,该语句中的10000的存储方式是以两个字节的unsigned char方式存储的,这就需要将aa的储存进行扩展为两个字节的unsigned char方式。所以[C51]在使用两个寄存器对[aa=9]进行储存时,需要先存储低字节,然后再存储高字节,这就使得在执行[aa?10000]时,乘法运算就变成了两个双字节数相乘,按照[C51]的运算规则,改程序的代码会少一次运算,其中有数据没有进行相应的乘法运算,而且在执行的过程中,没有把经过第三次运算得到的结果的高8位进行储存,而运算结果的低8位存放在[R7],而次低8位存放在[R6],所有得到的运算结果就会不正确。
  3.3 相应的优化方案
  针对上述提到的关于乘法运算的问题,本文提出了几种进行优化的算法,其包括引入中间变量法、分布运算法以及强制类型转换法。
  3.3.1 引入中间变量法
  在进行乘法运算的过程中,可以通过增加一个中间变量来对算法进行优化,但对于这个中间变量而言,其数据类型必须要能够存储相乘之后的得到的结果,上述中的程序就可以改写为:
  #include <AT89X52.H>
  Main()
  {
  Unsigned char aa;
  Unsigned long gg,bb;
  aa=9;
  bb=10000;
  gg=(aa*bb);   }
  从该程序中就可以发现,程序中的aa是char类型,而bb是long类型,按照[C51]的相关运算规则,aa的数据类型先改变为与long一样的,那运行的结果也是long类型的,而且[C51]能够对[9?10000]这个数据进行自动存储,运行结果就不会出错。
  3.3.2 分布运算法
  除了上述算法外,编程人员也可以使用分布运算法进行优化,可以将一个16位的数据分成两个数据的乘积,而对于这两个数据来说,其都是8位数,结果储存在能够进行存储相乘之后得到的结果的储存单元中,最上面的程序就可以改为:
  #include <AT89X52.H>
  Main()
  {
  Unsigned char aa;
  Unsigned long gg;
  aa=9;
  gg=(aa*100);
  gg=100;   }
  通过对该程序进行分析可以发现,进行修正后的程序运算的得到的结果为long类型,并且可以对[9?10000]这个数进行存储,所以最后的运算结果也是正确的。
  3.3.3 强制类型转换法
  在[C51]编译器中,强制类型转换运算符可以使用“()”表示,其作用就是将相关表达式或者标量的类型进行强制转换为所需要的类型,在[C51]中一般存在隐式转换和显式转换两种转换方式。在使用隐式转换式对程序进行编译时,编译器能够进行自动处理,但在本文的研究中运用的是显示类型转换方式,使用该方法将aa强制转换成可以进行存储运算结果的类型,那么最上面的程序就可以改为:
  #include <AT89X52.H>
  Main()
  {
  Unsigned char aa;
  Unsigned long gg;
  aa=9;
  gg=((unsigned long)aa)*10000;   }
  在该程序中,aa转换成了可以存储[9?10000]的数据类型,所以得到的结果也是正确的。
  4 结语
  综上所述,C语言作为一种结构化的程序设计语言,成为单片机最重要的编程语言,单片机C语言也具有高级语言的功能以及完善的模块化程序结构,能够为单片机软件系统的开发提供有力的保障。在单片机系统中,常常会涉及多种算法,而本文研究主要是单片机程序设计中的多位乘法的相关算法,并對多位乘法运算中存在的问题以及解决方法进行了相应的研究。
  参考文献:
  [1] 严克剑,张淼,黄先伟.单片机C语言编程中多位乘法运算问题探讨[J].广东工业大学学报,2006(4):23-26.
  [2] 谭炳菊,富钰.单片机C语言编程方法探讨[J].辽宁高职学报,2010,12(4):43-44.
  [3] 黄皎,刘建国,高敏.单片机C语言编程应注意的若干问题[J].微计算机信息,2003(7):58-59.
  【通联编辑:张薇】
转载注明来源:https://www.xzbu.com/8/view-15031125.htm