嵌入式系统的C语言

上传人:豆浆 文档编号:19482666 上传时间:2017-09-08 格式:PDF 页数:62 大小:2.73MB
返回 下载 相关 举报
嵌入式系统的C语言_第1页
第1页 / 共62页
嵌入式系统的C语言_第2页
第2页 / 共62页
嵌入式系统的C语言_第3页
第3页 / 共62页
嵌入式系统的C语言_第4页
第4页 / 共62页
嵌入式系统的C语言_第5页
第5页 / 共62页
点击查看更多>>
资源描述

《嵌入式系统的C语言》由会员分享,可在线阅读,更多相关《嵌入式系统的C语言(62页珍藏版)》请在金锄头文库上搜索。

1、 1 嵌入式系统的 C 语言 一、 C语言基础 1、什么是 C? C程序语言最初是由 Dennis Ritchie在 1971年为 UNIX系统开发并实现的。 C的一个最大优点是与任何特定的硬件或系统无关。这使得一个用户写的程序不作任何修改就能运行在几乎所有的机器上。 C通常被称为中级计算机语言,因为它将高级语言的要素与汇编语言的功能结合了在一起。 2、为什么用 C? C非常灵活,而且可随心所欲。这种自由赋予 C非常强大的功能,有经验的用户可以掌握;C是一个相对小的语言,但是它经久耐用; C有时被认为是“高级汇编语言”;低级(位操 作)编程也容易实现;松类型(不象其它高级语言); C是结构化编

2、程语言; C允许你创建你脑海中已有的任何任务。 C保留了程序员知道正在做的事情的基本体系;它只需要他们明白地表达其意图。 3、为什么不用 C?文化的问题 当考虑转到 C语言时,我们会遇到一些共同的问题: 产生大而低效的代码;标准 IO程序的雍余代码( printf, scanf, strcpy等);存贮器定位的使用: malloc(),alloc();堆栈的使用,在 C中不很直接;在 RAM和 ROM中数据的声明;难于写中断服务程序。 4、 8位微控制器的 ANSI C 对于嵌入式系统,纯粹的 ANSI C并不方便,因为: 嵌入式系统与硬件打交道。 ANSI C 提供的在固定存贮空间用寄存器寻

3、址的工具非常拙劣;几乎所有的嵌入式系统使用中断; ANSI C有各种类型的促进规则,对 8位机来说绝对是性能杀手;一些微控制器结构没有硬件支持 C堆栈;很多微控制器有多个存贮空间。 5、打破一些 C范例 当在低端的 8位微控制器上用 C语言,应想法使代码变小。这意味着打破一些编程规则: 开 /关全局中断;使用 GOTO语句;全局标号;全局寄存器段;指针支持。 6、嵌入式与桌面编程 嵌入式编程环境的主要特 点: 有限的 RAM;有限的 ROM;有限的栈空间;面向硬件编程;严格的定时( ISR,任务,);很多不同种类的指针( far/near/rom/uni/paged/);特殊关键字 /标识符(

4、, interrupt, tiny,)。 7、汇编与 C 编译器只是一个能干的优秀汇编程序员。 写能够转换为高效率汇编代码的好的 C代码,比手工写高效率的汇编代码容易得多。 C是终极解决办法,但其本身并未终结。 8、为什么改用 C? 有很多原因用 C语言而不用汇编: C使我们提高效益;用 C写的代码更可靠; C代码更容易升级和扩展;不同 平台之间更容易迁移;代码容易维护;文档、书籍、第三方库和程序都可得到。 9、 C代码结构 如下图所示, 一个 C程序基本由以下部分组成: 2 预处理命令、类型定义、函数原型(声明传给函数的函数类型和变量)、变量和函数。 一个程序必须有一个 main()函数,每

5、个命令行必须用分号(;)结束。 10、 C函数 一个函数的结 构如下: 类型 函数名(参数) 本地变量 C 语句 3 11、 C关键字 1)数据类型 char short signed unsigned int float long double 2) 修饰符 const static volatile restrict 3)标识符 struct union void enum 4) 选择体 if else switch case default 5) 存贮指定 register typedef auto extern 6)循环体 do while for 7)跳转 goto continue

6、 break return 8)功能指定 inline 9) 预处理指示 #include #define #undef #line #error #pragma 10)条件编译 # if # ifdef # ifndef # elif # else # endif 12、 C操作符 1)基本表达式和后缀操作符 ( ) 子表达式和函数调用 数组下标 - 结构指针 结构成员 + 增加 (后缀 ) - 减少 (后缀 ) 2) 一元操作符 ! 逻辑非 取补 + 增加 (前缀 ) - 减少 (后缀 ) - 一元减 + 一元加 (类型 ) 类型 强制 * 间接指针 & 取地址 sizeof 大小 3)

7、赋值符 = 相等赋值 += 加等于 -= 减等于 *= 乘等于 /= 除等于 %= 求余等于 =右移位等于 &=按位与等于 = 按位异或等于 |= 按位或等于 4) 位操作 & 位与 位异或 | 位或 位右移 5) 数学运算 * 乘 / 除 %求余 + 加 - 减 6) 关系运算 大于 =大于或等于 =相等测试 !=不等测试 7) 逻辑运算 & 逻辑与 | 逻辑或 8) 条件运算 ?: 条件测试 9) 序列 , 逗号 4 二、嵌入式编程 1、变量 变量的类型决定其可带值的类型。也就是说,为变量选择一个类型与我们使用这个变量的方法直接相关。我们将学习 C的基本类型、怎样写常量和声明这些变量。 1

8、 1 选择一个类型 “值集合”是有限的。 C的整数类型不能代表所有整数;它的浮点类型也不能代表所有浮点数。当声明一个变量并为它选择一个类型, 你应紧记你需要的值和操作。 1 2 C的基本数据类型 ANSI标准并没为本地类型规定尺寸大小,但 CodeWarrior规定了。 C只有一些基本数据类型: 所有数量类型(除了 char)缺省都是有符号的,例如: int = signed int。 注意: INT型的大小依赖于不同的机器。 1 3 CodeWarrior数据类型 例如 ,按 ALT+F7打开工程的通用设置 ,选择 “Compiler for HC08”面板并点击类型尺寸。这个窗口向你显示

9、CodeWarrior 编译器使用的标准类型设置。 所有基本类 型可以改变,尽管这可能不是个好主意。 5 1 4 数据类型的事实 代码大小和执行时间的最大节约可通过为变量选择最合适的数据类型得到。 8位微控制器内部的数据的长度是 8位(一字节),然而 C首选的数据类型是 int。 8位机处理 8位数据类型比 16位类型效率更高。 “int“和大数据类型只有当所描述的数据的大小需要时才使用。 当效率非常重要时,双精度和浮点操作效率低,应当避免。 1 5 选择数据类型 8位微控制器选择数据类型有 3个规则: 1)用最可能小的类型来完成工作,大小越小占用存贮空间越少; 2)若可能 ,用无符号类型;

10、3)在表达式内声明以将数据类型减到最少需要。 使用类型定义得到固定大小: 1)根据编译器和系统而改变; 2)移植到不同的机器代码不变; 3)当值需要固定位时使用。 6 打开文件: Lab1-Variables.mcp Main 函数内定义了三种不同类型的变量 定义了一个数据类型的完整集合 7 只写了意义最少的位 ;寄存器用于此目的。 每个变量剩余位用: clr ,x 清除。 变量在堆栈中有一个地址。 主函数外定义了三个不同类型的变量。 主函数外定义了三个不同类型的变量。 8 编译器为作用的变量保留了内存。本例中 VarA 是唯一使用的变量。 所有声明的全局变量均被使用。 9 在这种情况下,编译

11、器为所有变量保留了内存。 10 2、存贮类修饰符 以下关键字用于声明变量,以指定特定需要或内存中变量存贮的相关条件。 static volatile const 这三个关键字,一起让我 们不仅可写出好的代码,而且可写出紧凑的代码。 2 1 静态变量 使用静态有二个主要功能: 第一个最常用的用法是定义一个变量,在函数连续调用期间,变量不会消失。 第二个使用静态的用法是限制变量的范围。在模块级定义时,能被整个模块中所有函数访问,不能被其它函数访问。这非常重要,因为当严格限制全局变量众所周知的问题时,它让我们获得所有全局变量执行性能的好处。因此,如果我们有必须被一些函数频繁访问的数据结构,就应当将函

12、数放入同一模块中,并将结构声明为静态。这样所有函数能够访问而不必通过一个访问函数的上层,同时与数据 结构无关的代码禁止访问它。这一技术是一种变通方法,立即可访问变量在小的机器上实质上取得了足够的性能。 声明模块级静态变量(与将其设为全局相反)能取得一些其他潜在的益处。静态变量由于定义,只能被一组特定的函数访问。因此,编译器和连接器能够明智地选择变量在存贮空间的放置。例如,对于静态变量,编译器 /连接器也许选择将一个模块中所有静态变量放在连续的区域,这样增加了各种优化机会,例如用简单的增加或减少代替重载。相反,全局变量在存贮空间的位置通常计划于优化编译器的哈稀算法,这排除了可能的优化。 须着重指

13、出 , 这些变量 不会存贮在堆栈中,因为它们必须保存其值。 下面给出一个静态变量怎样工作的例子: FILE1.c 根据变量大小的不同,每个加操作用不同的方法完成。 变量声明的内存区,每个变量有不同的大小 ( 1、 2 和 4 字节) 11 #include /包含文件 FILE2.c /中的函数 void main (void) /第一次进入 MyFunction之前, myVar=0。 MyFunction(); /在 FILE2.c中 /第二次进入 MyFunction之前, myVar=1。 MyFunction(); /在 FILE2.c中 FILE2.c void MyFunctio

14、n (void) /FILE2.C中定义 /MyFunction函数 static char myVar = 0; /本地变量 /声明为 static myVar = myVar + 1; /尽管 myVar是本地变量,但它保持了自己的值。 2 2 静态函数 一个静态函数只能被其所在模块中的其它函数调用。使用静态函数是结构化编程的好习惯。你也许惊讶地知道静态函数能产生小 /快的代码。这是可能的,因为编译器在编译时确切地知道什么函数能调用一个给定的静态函数。因此,函数的相关内存区域能被调整, 以致使用调用的一个短版本或跳转指令。潜在的改进甚至更好,编译器足够聪明地用跳转代替调用。 2 3 关键字

15、 “static”的使用 在函数体声明静态的变量,在函数调用期间保持其质; 在模块内声明静态的变量,(但在函数体之外)能被模块内所有函数访问; 在模块内声明静态的函数,只能被模块内其它函数调用。 对于嵌入式系统:封装持续生存的数据(包装);模块化编码(数据隐藏);在每个模块中隐藏内部处理。 2 4 可变( volatile)变量 可变变量是其值在正常程序流程以外可能改变的变量。在嵌入式系统中,这种情况通过两种 主要途径发生: 通过一个中断服务程序,或作为硬件动作的结果。例如,通过一个串口接收到一个字符,结果串口状态寄存器更新,这完全在程序流程之外发生。很多程序员知道编译器不会试图优化一个 vo

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号