《嵌入式C语言程序设计基础.pdf》由会员分享,可在线阅读,更多相关《嵌入式C语言程序设计基础.pdf(6页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、 1嵌入式 C 语言程序设计基础嵌入式 C 语言程序设计基础 对于 C 语言大家应该都比较熟悉,它是一种结构化的程序设计语言,它的优点优点是运行速度快、编译效率高、移植性好和可读性强。因此在嵌入式程序设计中经常会用到 C 语言程序设计。嵌入式 C 语言程序设计是利用基本的 C 语言知识,面向嵌入式工程实际应用进行程序设计。也就是说呢它首先是 C 语言程序设计,因此必须符合 C 语言基本语法,只是它是面向嵌入式的应用而设计的程序。本节课我们讲述的嵌入式 C 语言程序设计基础,一方面是对 C 语言基础知识的回顾,同时也是对面向嵌入式应用进行 C 语言程序设计的讲述。主要介绍 C 语言的一些基本语法
2、及各个知识点在本教程例程中的应用。一、C 语言的“预处理伪指令”在嵌入式程序设计中的应用 如:A#include B#define ULONG unsigned long C#if _B0SIZE=B0SIZE_BYTE typedef unsigned char pB0SIZE;#elif _B0SIZE=B0SIZE_SHORT typedef unsigned short pB0SIZE;#elif _B0SIZE=B0SIZE_WORD typedef unsigned long pB0SIZE;#endif 对于第 1 个例子,是文件包含伪指令,其作用是将头文件包含到程序中。1、文件
3、包含伪指令 格式 格式#include ;标准头文件#include“头文件名.h”;自定义头文件 由此可见,头文件可分为标准头文件与自定义头标准头文件与自定义头文件。尖括号对内的头文件为标准头文件。标准头文件标准头文件就是按按 dos 系统的环境变量系统的环境变量 include 所指定的目录顺序搜索头文件所指定的目录顺序搜索头文件。也就是我们通常说的到系统指定的目录去搜索头文件到系统指定的目录去搜索头文件。双引号对“”内的头文件名为用户自定义头文件用户自定义头文件。搜索时,首先在当前目录(通常为源文件所在目录)中搜索,其次按环境变量 include指定的目录顺序搜索。搜索到头文件后,就将该
4、伪指令直接用头文件内容替换。头文件中的内容一般是什么呢?内容一般是定义一些本程序要用到的符号常量、复合变量原型、用户定义的变量类型原型和函数的原型说明等等。比如说在 S3CEV40 开发板模块程序的设计过程中,程序员就把一些常量及地址宏定义及函数声明等设计成了头文件中,这样当程序中用到这些定义及说明时只需将这些头文件包含进来即可。如*File:main.c*Desc:c main entry*/*-include files-*/#include 44blib.h#include 44b.h#include rtc.h#include./LCD_Test/bmp.h.其中 Generated
5、by Foxit PDF Creator Foxit Softwarehttp:/ For evaluation only.244blib.h对程序开发中的函数进行了声明,并用宏定义对一些常用的表达式或常量进行了预定义;“44blib.c”中对开发中用到的一些库函数作了函数原型定义 44b.h主要是用宏的方式定义了各模块中寄存器的地址。rtc.h对实时时钟模块程序中用到的常量做了宏定义。对于我们这里介绍的“预处理伪指令”它本身不是 C 语言的组成部分,因此不能直接进行编译,而必须在编译前由预处理器将这些“预处理伪指令”用实际的内容代替。因此也称为“编译预处理命令”或“编译预处理伪指令”。注意:
6、注意:伪指令行都以#号打头 2、宏定义伪指令、宏定义伪指令 对于第 2 个例子,它是一个宏定义伪指令。其格式如下:格式:格式:#define 宏标识符 宏体 如同前面介绍的,宏定义伪指令必须在编译前由预处理器将程序中的宏标识符用相应的宏体替换。如#define ULONG unsigned long 将所有的 ULONG 用 unsigned long替换 伪指令:伪指令:简单宏、参数宏、条件宏,宏释放 参数宏:参数宏:例子说明#define SQR(x,y)sqrt(x)*(x)(y)*(y)源文件中有:z=SQR(ab,ab);*替换为 sqrt(ab)*(ab)(ab)*(ab);*由上
7、面可见,参数宏类似于函数的调用。事实上,许多库函数是用参数宏写的。参数宏和函数的区别:一是形式参数表中没有类型说明符;二是参数宏在时空的开销上比函数都要小。条件宏:条件宏:先测试是否定义过某宏标识符,然后决定如何处理。这样做是为了避免重复定义。u 格式#ifdef 宏标识符#ifndef 宏标识符#undef 宏标识符#define 宏标识符 宏体#define 宏标识符 宏体#else#else#undef 宏标识符#define 宏标识符 宏体#define 宏标识符 宏体#endif#endif#ifdef 宏标识符#undef 宏标识符#define 宏标识符 宏体#else#defi
8、ne 宏标识符 宏体#endif#ifndef 宏标识符#define 宏标识符 宏体#else#undef 宏标识符#define 宏标识符 宏体#endif Generated by Foxit PDF Creator Foxit Softwarehttp:/ For evaluation only.3 其中:u 左边格式是测试存在,右边是测试不存在。宏释放:宏释放:用于释放原先定义的宏标识符。格式#u n d e f 宏标识符 3、条件编译伪指令 3、条件编译伪指令 条件编译伪指令是写给编译器的,指示编译器只有在满足某一条件时才编译源文件中与之相应的部分。u 格式#if(条件表达式 1)
9、#elif(条件表达式 2)#elif(条件表达式 n)#else#endif 这样,编译时,编译器仅对#i f()#e n d i f 之间满足某一条件表达式的源文件部分进行编译。二、嵌入式程序设计中的函数及函数库 函数是 C 语言程序设计的核心。一个较大的 C 语言程序一般是由一个主函数和若干个子函数组成,每个函数完成一个特定的功能。主函数可以调用其他函数,其他函数之间也可以相互调用。通过函数间的相互调用可以大大减少编程的工作量。函数定义的格式:e x t e r n i n t s t a r g(c h a r a,i n t b,i n t *p)e x t e r ne x t e
10、 r n i n t s t a r g(c h a r a,i n t b,i n t *p)e x t e r n static 是存储类型说明,externC 语言的函数都是全程序存在的,在不加任何存储类说明的情况下都是全程序可见的。但是,如果程序为多源文件时,非定义函数的文件要调用该函数时,需加原型说明。另外,即使在定义函数的源文件中,如果在函数定义之前超前调用,也需要加原型说明,而且原型说明中必须加存储类说明符 extern。在进行函数的定义性说明时,加上 static,表示在本文件定义前和非本函数定义文件中,该函数将不能被调用。这是为了提高函数的安全性。函数声明的格式:e x t
11、e r n i n t s t a r g(c h a r a,i n t b,i n t *p)e x t e r n i n t s t a r g(c h a r a,i n t b,i n t *p)C 语言的函数在不加任何存储类说明的情况下都是全程序可见的。但是,如果程序为多源文件时,非定义函数的文件要调用该函数时,需加原型说明。三、嵌入式程序设计中常用的 C 语言语句 C 语言语句格式为:标号:语句;其中:标号部分可有可无,由有效标志符后跟冒号组成。C 语言的语句有 1 0 种:表达式语句、复合语句、条件语句、循环语句、s w i t h 语句、b r e a k语句、c o n
12、t i n u e语句、返回语句等,其中用的最多地是条件语句、s w i t h语句和循环语句,Generated by Foxit PDF Creator Foxit Softwarehttp:/ For evaluation only.4这里我们重点介绍这些。1、条件语句 格式:两重选择 i f(条件表达式)语句 1;e l s e 语句 2;多重选择 i f(条件表达式 1)语句 2;e l s e i f(条件表达式 2)语句 3;e l s e i f(条件表达式 n)语句 n;例例例例一一一一:控制 LED 亮灭的条件语句 2、s w i t c h 语句 格式 s w i t c
13、 h(开关表达式)c a s e 常量表达式 1:语句 1;c a s e 常量表达式 2:语句 2;c a s e 常量表达式 n:语句 n;d e f a u l t:语句 n+1;注意:开关表达式的值必须是 i n t整数。语句可以是复合语句,也可以是空(即没有语句)。在 s w i t c h 语句中,可以通过 b r e a k 语句和 g o t o 语句跳出。void user_input_action(int value)if(!(value 0 x39)Uart_Printf(%x,value-0 x30);switch(value)case 0:TS_Test();/*如果
14、用户输入 0,则进行触摸屏的测试*/break;case 1:Digit_Led_Test();/*如果用户输入“1”,则进行 8 段数码管的测试*/break;case 2:Uart_Printf(nLook at LCD.n);Lcd_Test();/*如果用户输入“2”,则进行 LCD 的测试*/break;case 3:Uart_Printf(nKeyboard function testing,please press Key and Look at 8LED.n);Generated by Foxit PDF Creator Foxit Softwarehttp:/ For eva
15、luation only.5 Test_Keyboard();/*如果用户输入“3”,则进行键盘的测试*/break;case 4:Test_Iis();/*如果用户输入“4”,则进行 IIS 的声音测试*/break;case 5:Test_Timer();/*如果用户输入“5”,则进行定时器的测试*/break;case 6:Dhcp_Test();/*如果用户输入“6”,则进行以太网的 DHCP 测试*/break;case 7:Test_Flash();/*如果用户输入“7”,则进行 Flash 的测试*/break;case 8:Test_Iic();/*如果用户输入“8”,则进行
16、IIC 的测试*/break;case 9:Tftp_Test();/*如果用户输入“9”,则进行以太网的 TFTP 的测试*/break;default:break;3、循环语句 在 C 语言中有 3 种循环语句:f o r 循环语句、w h i l e 循环语句、d o w h i l e 循环语句。(1)f o r 循环语句(1)f o r 循环语句 格式:f o r(表达式 1;表达式 2;表达式 3)语句;其中:表达式 1 是对循环量赋初值,表达式 2是对循环进行控制的条件语句,表达式 3 是对循环量进行增减变化。例例例例二二二二:本例使用 for 循环语句控制在 8 段数码管中循环
17、显示 0F(2)(2)while 循环语句循环语句 格式 while(条件表达式)语句;(3)do while 循环语句 do 语句;while(条件表达式);四、嵌入式程序设计中 C 语言的变量、数组、结构、联合 1、变量 定义格式:int *count Generated by Foxit PDF Creator Foxit Softwarehttp:/ For evaluation only.62、数组 定义格式:int Symbol5=DIGIT_0,DIGIT_1,DIGIT_2,DIGIT_3,DIGIT_4;分类:一维数组 int a5 二维数组 in a510 其元素类型均为数
18、组类型。定义未赋初值,则其括号内必须有常量表达式,表示为数组分配内存的大小。初值缺省时数组各元素为随机值;需赋初值时,使用等号,后面跟花括号,花括号内是用逗号分隔的初值表。3、指针数组 定义格式:i n t *p 5=地址,地址,;指针数组 本质上是一个数组,只是它的元素是指针,就是说数组中存放的是其变量的地址,它在字符串排序中特别有用;4、数组指针 定义格式:int(*p)5=a;本质上是一个指针,只是该指针指向的是一个数组。指针指向数组的首地址。5、结构体 struct sockaddr unsigned short sa_family;char sa_data14;5.4 嵌入式嵌入式
19、C 语言程序设计实例语言程序设计实例 前面我们对 C 语言的语法及嵌入式中用到的 C 语言知识作了一个简单的介绍。这一节我们以 S3CEV40 开发板上的各个功能模块的整个测试程序为例,介绍如何运用 C 语言进行基于 ARM 的嵌入式程序设计。我们先运行一下这个程序,由程序的执行来分析一下程序各个组成部分的功能及设计。由程序的执行我们可以看出,该测试程序运行之后,数码管八段全亮;LED1、LED2 轮流闪烁;会在 LCD 和串口终端输出主界面信息。这时我们从 PC 键盘操作就可以交互式地进行系统各模块的测试。分析源代码 由程序的全部代码来看,编写一个成功的主文件代码主要需要以下几部分:1.需要用#include 指令将本文件所用到的头文件包含到该程序中;2.需要将本文件中定义的函数进行函数声明;3.定义本文件中用到的各种类型的外部变量及数组;4.编写各个函数代码,其中包括一个主函数 main(),由 main()提供主线,通过调用各子函数来实现各种功能。Generated by Foxit PDF Creator Foxit Softwarehttp:/ For evaluation only.
限制150内