如何编写高效率稳定的单片机代码

发布者:温柔心绪最新更新时间:2016-03-09 来源: eefocus关键字:编写  高效率稳定  单片机代码 手机看文章 扫描二维码
随时随地手机看文章
由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是以KB 来衡量的,可想而知,单片机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须 遵循以下几点进行优化:
  1. 使用尽量小的数据类型 
    能用unsiged就不用signed; 
    能用char就不用int; 
    能不用floating就不用。 
    能用位操作不用算数。

  2. 使用自加、自减指令 
    通常使用自加、自减指令和复合赋值表达式(如a-=1 及a+=1 等)都能够生成高质量的 
    程序代码,编译器通常都能够生成inc 和dec 之类的指令,而使用a=a+1 或a=a-1 之类 
    的指令,有很多C 编译器都会生成二到三个字节的指令。

  3. 减少运算的强度 
    可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。 
    (1) 求余运算 
    N= N %8 可以改为N = N &7 
    说明:位操作只需一个指令周期即可完成,而大部分的C 编译器的“%”运算均是调用子程序来 
    完成,代码长、执行速度慢。通常,只要求是求2n 方的余数,均可使用位操作的方法来代替。 
    (2) 平方运算 
    N=Pow(3,2) 可以改为N=3*3 
    说明:在有内置硬件乘法器的单片机中(如51 系列),乘法运算比求平方运算快得多, 因为浮点数 
    的求平方是通过调用子程序来实现的,乘法运算的子程序比平方运算的子程序代码短,执行速度快。 
    (3) 用位移代替乘法除法 
    N=M*8 可以改为N=M<<3 
    N=M/8 可以改为N=M>>3 
    说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移 
    的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子 
    程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果。 
    如N=M*9可以改为N=(M<<3)+M; 
    (4) 自加自减的区别 
    例如我们平时使用的延时函数都是通过采用自加的方式来实现。 
    void DelayNms(UINT16 t) 

    UINT16 i,j; 
    for(i=0;i

define MAX(A,B) {(A)>(B)?(A):(B)}

说明:函数和宏函数的区别就在于,宏函数占用了大量的空间,而函数占用了时间。大家要知道的是,函 
数调用是要使用系统的栈来保存数据的,如果编译器里有栈检查选项,一般在函数的头会嵌入一些汇编语 
句对当前栈进行检查;同时,cpu 也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所以, 
函数调用需要一些cpu 时间。而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序, 
不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函数的时候,该现象尤其突出。

  1. 适当地使用算法 
    假如有一道算术题,求1~100 的和。 
    作为程序员的我们会毫不犹豫地点击键盘写出以下的计算方法: 
    UINT16 Sum(void) 

    UINT8 i,s; 
    for(i=1;i<=100;i++) 

    s+=i; 

    return s; 

    很明显大家都会想到这种方法,但是效率方面并不如意,我们需要动脑筋,就是采用数学算法解决问题, 
    使计算效率提升一个级别。 
    UINT16 Sum(void) 

    UINT16 s; 
    s=(100 *(100+1))>>1; 
    return s; 

    结果很明显,同样的结果不同的计算方法,运行效率会有大大不同,所以我们需要最大限度地通过数 
    学的方法提高程序的执行效率。

  2. 用指针代替数组 
    在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相 
    比,指针一般能使代码速度更快,占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的, 
    但是效率不一样。 
    UINT8 szArrayA[64]; 
    UINT8 szArrayB[64]; 
    UINT8 i; 
    UINT8 *p=szArray; 
    for(i=0;i<64;i++)szArrayB[i]=szArrayA[i]; 
    for(i=0;i<64;i++)szArrayB[i]=*p++; 
    指针方法的优点是,szArrayA 的地址装入指针p 后,在每次循环中只需对p 增量操作。在数组索引 
    方法中,每次循环中都必须进行基于i 值求数组下标的复杂运算。

  3. 强制转换 
    C 语言精髓第一精髓就是指针的使用,第二精髓就是强制转换的使用,恰当地利用指针和强制转换不但 
    可以提供程序效率,而且使程序更加之简洁,由于强制转换在C 语言编程中占有重要的地位,下面将已五 
    个比较典型的例子作为讲解。 
    例子1:将带符号字节整型转换为无符号字节整型 
    UINT8 a=0; 
    INT8 b=-3; 
    a=(UINT8)b; 
    例子2:在大端模式下(8051 系列单片机是大端模式),将数组a[2]转化为无符号16 位整型值。 
    方法1:采用位移方法。 
    UINT8 a[2]={0x12,0x34}; 
    UINT16 b=0; 
    b=(a[0]<<8)|a[1]; 
    结果:b=0x1234 
    方法2:强制类型转换。 
    UINT8 a[2]={0x12,0x34}; 
    UINT16 b=0; 
    b= (UINT16 )a; //强制转换 
    结果:b=0x1234 
    例子3:保存结构体数据内容。 
    方法1:逐个保存。 
    typedef struct _ST 

    UINT8 a; 
    UINT8 b; 
    UINT8 c; 
    UINT8 d; 
    UINT8 e; 
    }ST; 
    ST s; 
    UINT8 a[5]={0}; 
    s.a=1; 
    s.b=2; 
    s.c=3; 
    s.d=4; 
    s.e=5; 
    a[0]=s.a; 
    a[1]=s.b; 
    a[2]=s.c; 
    a[3]=s.d; 
    a[4]=s.e; 
    结果:数组a 存储的内容是1、2、3、4、5。 
    方法2:强制类型转换。 
    typedef struct _ST 

    UINT8 a; 
    UINT8 b; 
    UINT8 c; 
    UINT8 d; 
    UINT8 e; 
    }ST; 
    ST s; 
    UINT8 a[5]={0}; 
    UINT8 p=(UINT8 )&s;//强制转换 
    UINT8 i=0; 
    s.a=1; 
    s.b=2; 
    s.c=3; 
    s.d=4; 
    s.e=5; 
    for(i=0;i

define Perror(FUN) printf(“Err:%s %s %d: %s\n”, FILE, func,LINE,FUN) 类linux的perror函数实现,这里加了出错的文件位置,所在函数,引发出错调用的函数FUN。

宏中#和##的用法

define STR(s) #s

define CONS(a, b) int(a##e##b)

printf(STR(vck));//输出vck 
printf(“%d\n”, CONS(2,3));//2e3 输出2000

关键字:编写  高效率稳定  单片机代码 引用地址:如何编写高效率稳定的单片机代码

上一篇:找回失去的青春,单片机是玩出来的
下一篇:浅析单片机与嵌入式的区别

推荐阅读最新更新时间:2024-03-16 14:46

STM8L超低功耗程序编写教学,简单易懂
之所以写这篇博客,是因为最近做一个项目,需要用到单片机的低功耗模式。第一次用stm8,我在网上看了很多资料,虽然有些写的还是挺详细的,但是我自己实际调试的时候还是出了不少意外,花了不少时间,因此想写一篇文章让你们少走一些弯路。语文水平有限,写的不好勿怪。 在讲程序之前先说明几点: 1.STM8低功耗的几种模式我不多说了,这方面的资料很多,自己可以先去了解一下。 2. 我测试用的主控芯片是STM8L151G6。(其他L系列程序上没有什么区别,至于功耗是不是一样我就不知道了) 3. 程序用的是库函数的写法。 4. 低功耗模式用的是Halt模式,也就是停机模式,功耗是最低的,其他模式的功耗我没有测过,这里不说。 5. 为了更加直观,
[单片机]
如何编写高效率稳定单片机代码
由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是以KB 来衡量的,可想而知,单片机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须 遵循以下几点进行优化: 使用尽量小的数据类型 能用unsiged就不用signed; 能用char就不用int; 能不用floating就不用。 能用位操作不用算数。 使用自加、自减指令 通常使用自加、自减指令和复合赋值表达式(如a-=
[单片机]
基于RS485主从结构通信单片机代码
RS485主从结构通信代码,用于组网内部通信 单片机源程序如下: #ifndef _485MON_H // 防止485Mon.h被重复引用 #define _485MON_H #include reg52.h // 引用标准库的头文件 #include stdio.h #include string.h #define uchar unsigned char #define uint unsigned int #define ACTIVE 0x11 #define GETDATA 0x22 #define READY
[单片机]
基于RS485主从结构通信<font color='red'>单片机</font><font color='red'>代码</font>
基于at89c51单片机的最基础流水灯Proteus仿真图含代码
#include reg51.h #include stdio.h void delay(void) { unsigned int i,j; for(i=500;i 0;i--) for(j=115;j 0;j--); } void main(void) { // Write your code here unsigned char led ,a ,b ;//定义三个变量 led=0xfe; //led=1111 1110,P0。0亮 while (1) { P0=led; //将led的状态赋给P0寄存器 a=led 7; //将led最高位赋给a最低位,其
[单片机]
基于at89c51<font color='red'>单片机</font>的最基础流水灯Proteus仿真图含<font color='red'>代码</font>
STM8单片机关于rtc部分代码分享
STM8 rtc 时钟可以使用内部低频时钟源,或者外部低速 32768Hz 时钟源,关于 rtc 部分代码如下: #include #include voidinit_rtc(void) { RTC_InitTypeDefRTC_InitStr; RTC_TimeTypeDefRTC_TImeStr; RTC_DateTypeDefRTC_DateStr; #if0 /*LSI*/ CLK_RTCClockConfig(CLK_RTCCLKSource_LSI,CLK_RTCCLKDiv_1); CLK_PeripheralClockConfig(CLK_Peripheral_RTC,ENABLE); RTC_I
[单片机]
STM8<font color='red'>单片机</font>关于rtc部分<font color='red'>代码</font>分享
STM32入门开发:编写XPT2046电阻触摸屏驱动(模拟SPI)
一、环境介绍 单片机采用: STM32F103ZET6 编程软件: keil5 编程语言: C语言 编程风格: 寄存器开发. 目标芯片: XPT2046---标准SPI接口时序 二、XPT2046芯片介绍 2.1 功能 XPT2046是一颗12位的ADC芯片,可以当做普通的ADC芯片使用,但是一般都是用在电阻触摸屏上,方便定位触摸屏坐标。 图1: XPT2046内部原理图 图2:电阻触摸屏---引出的4条线就接在XPT2046的YNXNYPXP上 (XPT2046支持笔中断输出--低电平有效,这个引脚可以配置到单片机的中断脚上,或者轮询判断这个引脚状态,判断触摸屏是否已经按下) 可以单独买一个触
[单片机]
STM32入门开发:<font color='red'>编写</font>XPT2046电阻触摸屏驱动(模拟SPI)
如何写出高效的单片机C语言程序代码
由于单片机的性能同电脑的性能是天渊之别的,无论从空间资源上、内存资源、工作频率,都是无法 与之比较的。PC 机编程基本上不用考虑空间的占用、内存的占用的问题,最终目的就是实现功能就可以了。 对于单片机来说就截然不同了,一般的单片机的Flash 和Ram 的资源是以KB 来衡量的,可想而知,单片 机的资源是少得可怜,为此我们必须想法设法榨尽其所有资源,将它的性能发挥到最佳,程序设计时必须 遵循以下几点进行优化: 1. 使用尽量小的数据类型 能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变 量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然
[单片机]
LCD驱动HT1621的PIC单片机代码
STATUS EQU 3H FSR EQU 4H RB EQU 6H RC EQU 7H OPTIONA EQU 81H TRISB EQU 86H TRISC EQU 87H GENR0 EQU 053H GENR1 EQU 054H WD_RG EQU 055H DA_AG0 EQU 056H ;SEG0 SEG1 DA_AG8 EQU 05EH ;SEG16 SEG17 ;............................. C EQU 0 Z EQU 2 RP0 EQU 5 RP1 EQU 6 CS
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved