




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1全局变量和局部变量全局变量为整个程序而定义,在整个程序运行期间,它们占用固定的RAM资源。在C语言中,在所有函数外部声明的变量都认为具有全局作用域,这些声明通常置于源文件的顶部。“全局”实际上仅仅意味着标识符从声明点到文件末尾的范围内是可访问的,当程序包含多个源文件时,则在一个文件中定义的全局变量在其他文件引用时,需要使用extern关键字声明。在引用文件内部,标识符的作用域是由extern声明的位置确定的。如果该声明是全局的,那么该标识符对于文件是全局的;如果该声明是放在块内的,则它对于那个块就是局部的。局部变量为某个函数或子程序而定义,只在函数运行时,从堆栈空间中分配存储空间;函数运行结束,所占用堆栈空间释放。2变量修饰符变量定义有三个修饰符值得注意,虽然它们与标准C是相同的,但是在嵌入式C语言中又有不同的含义。(1) volatile大多数编译器对源程序编译时做优化操作,其中一种优化方法是基于这种假设:除非明确地把某值写到内存,否则内存中的值不会改变。所以如果源程序中频繁使用某个内存,编译器会把这个内存放到CPU寄存器或高速缓存中,提高代码运行速度。在嵌入式系统中,这种优化会影响程序的正确执行,典型的情况是:硬件外设寄存器的值随时都在变化,并且这种变化是不需要在写寄存器程序来改变。内存变量在主程序中没有显示改变,但在中断服务程序被改变,如果编译器在主程序中将内存以寄存器来取代,中断服务程序对变量的改变就不能传递到主程序中。对于这两种情况做变量声明时,需要加前缀volatile,告诉编译器不要对这些变量做优化操作。例如:volatile char device_status(2) static在子函数中用static声明的变量是局部变量,局部的范围可能是一个文件、函数、过程中,在局部的范围内,变量可以调用,变量值可以共享。下面给出了一个子函数中使用的局部变量的用法。void MyFunction (void)static char myVar = 0; /用 static声明的局部变量myVar = myVar + 1;void main (void)MyFunction(); /调用之前myVar = 0,调用之后myVar = 1MyFunction(); /调用之前myVar = 1,调用之后myVar = 2(3) const修饰符const可以用在任何变量之前,用于声明变量值不会被改变,即“只读的”。这提供了一种保护性编程,编译器会将任何想修改这种变量的行为看成是违犯语法的行为。const声明的变量必须包含一个初值,不允许在以后的使用中修改它的值。宏定义常量和const有一些相似之处,但const还声明了数据类型,编译器对它们的处理也有所不同,如:#define TYPEA 10 /*字符”TYPEA”在编译时用10来代替*/const unsigned int typeA=10; /*typeA 是一个无符号整型数值为10*/当在一个指针声明中使用const关键字时,其意义有所不同,如:const int *p; /*P是一个可修改的指针,指向一个只读的int值*/int *const p=&i; /*P是一个只读的指针,指向一个可修改的int值*/const int * const p=&i; /*P是一个只读的指针,指向一个只读的int值*/在嵌入式系统编程时,const修饰的变量应该把它看成一种常量,常量值存储在ROM中。5.4.2 变量存储空间分配嵌入式内部数据存储器RAM只有几百字节,如果通过扩展外部存储器RAM来提高数据存储量必将会增加了硬件成本,使系统更加的复杂,访问外部存储器比访问内部存储器所需的代码也要长得多。有效地使用片内存储器、提高存储器空间的利用率对开发者来说十分关键。内部处理器、内部堆栈、压缩栈、所有程序变量和所有包含进来的库函数都将使用数量有限的内部数据存储器RAM。因为C语言采用了存储器的覆盖技术,可以在程序进行连接时,它将那些已经被其它程序段释放了的存储器空间重新定义给另一个程序段的变量使用,当这个程序运行结束时再将这些存储器释放以供其它程序段使用。全局变量的作用范围是整个程序,因此不能被释放;静态变量由于在函数的调用中也不能被释放;只有局部变量中的动态变量可以被释放。因此在进行程序设计时应该尽量的使用局部变量,提高内部数据存储器的使用率。在C语言中程序中间结果及参数传递是通过内部的寄存器来完成的,要是内部的存储器不够,将会给你的程序带来许多莫名其妙的错误。例如在进行程序设计时语句不应太长,一条长语句可以分成多条语句,这样可以减少中间变量。若语句太长可能造成临时寄存器不够用,导致计算出错。下面的示例给出了08C中对于变量的一些详细的使用信息。例:08C中对于变量的存储空间的使用,在MT_IDE For Freescale HC08环境中输入如下程序:unsigned char pubVar0; /全局变量/*主函数*/void main()unsigned int tmpVar1; /局部变量static unsigned int staticVar2; /静态变量const static unsigned int constVar3=0x11; /静态常量tmpVar1=0x22;staticVar2=0x33;pubVar0=0x44;编译后的列表文件:_main:tmpVar1 - X+08037 A7 FE aiS #-28039 95 tSXFILE: main.c(0001) unsigned char pubVar0; /全局变量声明(0002) /*主函数*/(0003) void main()(0004) 803A 4F clrA803B F7 stA 0,X803C A6 22 ldA #34803E E7 01 stA 1,X(0005) unsigned int tmpVar1;(0006) static unsigned int staticVar2;(0007) const static unsigned int constVar3=0x11;(0008) tmpVar1=0x22;(0009) staticVar2=0x33;8040 4F clrA8041 C7 0041 stA _r0+18044 A6 33 ldA #518046 C7 0042 stA _r0+2(0010) pubVar0=0x44;FILE: 8049 A6 44 ldA #68804B C7 0043 stA _pubVar0804E A7 02 aiS #28050 81 rts说明:tmpVar1是一个无符号整型的局部变量,编译后的列表文件中,在main函数的开始处,将堆栈指针减2,预留了2个字节的空间用于存放tmpVar1的值,如果main函数有更多的局部变量,会开辟更多的堆栈空间。执行语句“tmpVar1=0x22”时,将十六进数22(十进制数34)放到堆栈空间,高字节0存放在堆栈指针处,低字节34存放在堆栈指针加1处。语句“const static unsigned int constVar3=0x11;”在执行时并不生成具体的执行代码,只是将常量0x11放到S19代码中,并且通常放在S19代码的最前面。本程序生成的S19代码的第一行S1238000001145024094CD805145004165004427066F00AF0120F54500429445800265803B其中加阴影的“0011”就是上述语句所产生的。staticVar2是一个静态局部变量,虽然是局部变量,但子程序结束后,其值仍然保留。所以也需要分配固定的存储空间。在08C中,这些变量存放在“Vreg”段变量空间的后面,所以语句“staticVar2=0x33”在执行时,高字节放在_r0+1的位置(r0位于Vreg段),低字节放在_r0+2处。staticVar2是一个字节型的局部变量,编译后分配了固定的存储空间。对于这些加了修饰符的变量的使用方法在不同编译器中存储空间的分配有所差别,使用者只需要像上面一样编写小的程序段进行编译,然后查看列表文件(.lst)、映象文件(.mp)及代码文件(.s19)等,就可以弄清楚使用方法,理解编译器这些问题对于软硬件编程是一件很重要的事情。基于嵌入式的08C语言和标准C语言虽然在语法上区别不大,但要结合嵌入式的系统资源,用C语言开发符合实际工程需要的嵌入式软件系统,对编程者来说是一件很难的事情。本节根据我们的开发经验讲述一些08C的编程技巧。5.4.3 数据类型的选用嵌入式C语言编程不同于一般C语言编程的一个显著特点,就是要和程序存储器资源结合起来,虽然其提供的数据类型十分丰富,但是只有bit和char等数据类型是机器语言直接支持的数据类型,用此类数据类型的语句所生成的代码较短;而其它的数据类型如整型、浮点型等数据要有一定的内部程序或内部函数的支持,相对来说用该类数据类型的语句生成的代码要长。有些C语言程序表面上看起来十分的简单,但在实际编译时,生成的代码却相当长。因此我们要按照实际需要,尽量选用占用存储空间少的数据类型,可以大大的减少所生成的代码长度。例如在08C中用不同的数据类型定义i时,语句:for(i=0;i10;i+);经编译后生成的代码长度如表5-4所示。通过表5-3我们知道,不同的数据类型所生成的机器代码长度相差很大,相同类型的数据类型有无符号对机器代码长度也有影响。在程序编译时生成机器代码长的数据类型的优先级越高,不同的数据类型在进行程序运算时要转化为高优先级的数据类型,相应的代码长度也会增长。因此我们应尽可能地使用bit, char等机器语言直接支持的数据类型,无符号数的变量应声明为无符号数,尽可能地减少程序中使用的数据类型的种类。5.4.4 位操作的其他实现方法1用共用体和位域实现位操作综合共用体和位域等多种数据类型,可以实现很直观的位操作方法。下面以A口的数据寄存器位操作方法来说明。(1) 定义/A口数据寄存器及位定义typedef union unsigned char Byte;struct int PTA_0 :1; /* Port A数据Bit 0 */int PTA_1 :1; /* Port A数据Bit 1 */int PTA_2 :1; /* Port A数据Bit 2 */int PTA_3 :1; /* Port A数据Bit 3 */int PTA_4 :1; /* Port A数据Bit 4 */int PTA_5 :1; /* Port A数据Bit 5 */int PTA_6 :1; /* Port A数据Bit 6 */int PTA_7 :1; /* Port A数据Bit 7 */ Bits;PTASTR;#define _PTA (*(volatile PTASTR *)0x00)#define PTA _PTA.Byte#define PTA0 _PTA.Bits.PTA_0#define PTA1 _PTA.Bits.PTA_1#define PTA2 _PTA.Bits.PTA_2#define PTA3 _PTA.Bits.PTA_3#define PTA4 _PTA.Bits.PTA_4#define PTA5 _PTA.Bits.PTA_5#define PTA6 _PTA.Bits.PTA_6#define PTA7 _PTA.Bits.PTA_7(2) 使用对A口整个口的使用,则直接对PTA赋值。如:PTA = 0xFF;对A口的某一位的使用,则直接对PTAx赋值。如:PTA4 = 1;很显然这样定义了以后,操作很方便,程序的可读性也很好。但这种方法08C编译器编译后的效率比第1种方法要差。如上面用到的PTA4 = 1编译后的代码为:8089 B6 00 ldA 0x00808B AA 10 orA #16808D B7 00 stA 0x00本来用1条位操作指令来实现的操作,现在用了3条指令,在执行效率和存储空间上都比较差,对于接口编程时对时序要求很高的时候要特别注意这个问题。2用宏定义+“按位与、按位或运算”的方法实现位操作在5.2.2节所讲述的位操作方法效率高,但程序的易读性不强。在有些情况下,将5.2.2节的位操作语句再来例如:串行模块(SCI)的控制寄存器2(SCC2)的第5位控制接收中断的开放(=1时)和禁止(=0时),此时可以定义两个宏:#define EnableSCIReInt() SCC2|= (15) /令SCC2.5=1,开放SCI接收中断#define DisableSCIReInt() SCC2&=(15) /令SCC2.5=0,禁止SCI接收中断这样在程序中开放串行接收中断就用如下语句:EnableSCIReInt();5.4.5 算法设计问题嵌入式C语言和标准C语言存在着很大差别,在计算机上进行C语言程序设计时可以不必考虑程序代码的长短,只需考虑程序功能实现,但是在嵌入式上进行C语言程序设计就必须考虑系统的硬件资源。有时并不是程序的算法越简单、长度越短越好,因为有一些算法要调用一些内部的子程序和函数,生成的机器代码可能非常长。不同的算法对程序代码长度影响十分大,因此在进行程序设计时,就尽量采用程序生成代码短的算法,在不影响程序功能实现的情况下可以采用一些优化算法。在嵌入式C语言编译成机器代码时,不同的运算生成的机器代码的长度相差很大,尽可能地减少程序中对某种数据类型的运算种类,越复杂的数据类型效果越明显。在进行数据计算时,在一定的精度范围内,可以用一些近似的计算来完成一些运算,既不损失精度又能减少大量的代码。比如:用逻辑AND/&取模比MOD/%操作更有效。在用热敏电阻测量温度时,可根据热敏电阻温度特性公式来求值。数学表达式表示为:RT=RT0e(B(1/T-1/T0)其中:RT-T时的阻值RT0-T0(基准温度)时的阻值B-热敏电阻特性参数如果直接按照公式计算RT时程序结构简单,算法复杂度不高,但是程序将调用文件中的对数函数,在编译成机器码时函数有1K多字节,对于一般只有几K字节的嵌入式系统来说,这是十分不合适的。考虑到系统资源问题可以用一种替代方法查表法来实现算法。只要给出一定温度范围内不同温度值对应热敏电阻的电阻值,然后建立表格,只要按照系统求出的阻值,进行查表、插值,就可以求出相应的温度
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030中国冶金辅料行业竞争动态及消费趋势预测报告
- 2025-2030中国亲子旅游行业经营态势与投资效益预测报告
- 2025-2030中国二手手机回收投资效益评估及未来前景展望报告
- 西南医科大学招聘笔试真题2024
- 2024年阳江市阳西县招聘笔试真题
- 2024年黔南州罗甸县特岗计划教师招聘笔试真题
- 垮部门工作会议管理制度
- 学校功能室制度管理制度
- 在制品生产车间管理制度
- 旅游质量工作管理制度
- 2025年全国普通高校招生全国统一考试数学试卷(新高考Ⅰ卷)含答案
- T/CSPSTC 75-2021微动探测技术规程
- 【KAWO科握】2025年中国社交媒体平台指南报告
- 【语文】第23课《“蛟龙”探海》课件 2024-2025学年统编版语文七年级下册
- 大部分分校:地域文化形考任务一-国开(CQ)-国开期末复习资料
- 2024年江苏省南通市中考地理试题(含答案)
- 2024年上海市中考数学真题试卷及答案解析
- 哈尔滨市道路交通安全管理办法
- 涉农贷款客户贷后管理操作规范
- ISO9001表单英文版
- PTT、PBT、T-400纤维织物染整生产实践
评论
0/150
提交评论