嵌入式C编程综述.pdf
《嵌入式C编程综述.pdf》由会员分享,可在线阅读,更多相关《嵌入式C编程综述.pdf(83页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、嵌入式系统程序设计嵌入式系统程序设计大连理工大学软件学院大连理工大学软件学院嵌入式教研室嵌入式教研室赖晓晨赖晓晨嵌入式嵌入式C编程综述编程综述?软件架构软件架构?屏幕操作屏幕操作?键盘操作键盘操作?内存操作内存操作?性能优化性能优化一、软件架构一、软件架构?模块划分模块划分?任务模式任务模式?中断服务程序中断服务程序?硬件驱动硬件驱动?C的面向对象化的面向对象化1、模块划分、模块划分?模块划分的模块划分的“划划”是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分,合作完成系统的需求。是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分,合作完成系统的需求。
2、?C语言作为一种结构化的程序设计语言,在模块的划分上主要依据语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能功能。模块划分的方法模块划分的方法?模块即模块即是一个是一个.c文件和一个文件和一个.h文件的结合文件的结合,头文件,头文件(.h)中是对于该模块接口的声明;中是对于该模块接口的声明;?某模块提供给其它模块调用的外部函数及数据需在某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以中文件中冠以extern关键字声明;关键字声明;?仅在模块内部使用的函数和全局变量需在仅在模块内部使用的函数和全局变量需在.c文件开头冠以文件开头冠以static关键字声明;关键字声明;?永
3、远不要在永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作。文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作。一个不好的例子一个不好的例子/*module1.h*/int a=5;/*在模块在模块1的的.h文件中定义文件中定义int a*/*module1.c*/#include module1.h/*在模块在模块1中包含模块中包含模块1的的.h文件文件*/*module2.c*/#include module1.h/*在模块在模块2中包含模块中包含模块1的的.h文件文件*/*module3.c*/#include module1.h/*在模
4、块在模块3中包含模块中包含模块1的的.h文件文件*/结果。结果。一个好的例子一个好的例子/*module1.h*/extern int a;/*在模块在模块1的的.h文件中声明文件中声明int a*/*module1.c*/int a=5;/*在模块在模块1的的.c文件中定义文件中定义int a*/*module2.c*/#include module1.h/*在模块在模块2中包含模块中包含模块1的的.h文件文件*/*module3.c*/#include module1.h/*在模块在模块3中包含模块中包含模块1的的.h文件文件*/两种类型模块两种类型模块?一个嵌入式系统通常包括两类模块:一
5、个嵌入式系统通常包括两类模块:?硬件驱动模块,一种特定硬件对应一个模块;硬件驱动模块,一种特定硬件对应一个模块;?软件功能模块,其模块的划分应满足低耦合、高内聚的要求。软件功能模块,其模块的划分应满足低耦合、高内聚的要求。2、任务模式、任务模式?单任务、多任务单任务、多任务?单任务:微观串行、宏观串行单任务:微观串行、宏观串行?多任务:微观串行、宏观并行多任务:微观串行、宏观并行单任务程序典型架构单任务程序典型架构1.从从CPU复位时的指定地址开始执行;复位时的指定地址开始执行;2.跳转至汇编代码跳转至汇编代码startup处执行;处执行;3.跳转至用户主程序跳转至用户主程序main执行,在执
6、行,在main中完成:中完成:?初试化部分硬件设备;初试化部分硬件设备;?初始化各软件模块;初始化各软件模块;?进入死循环(无限循环),调用各模块的处理函数进入死循环(无限循环),调用各模块的处理函数无限循环的两种方案无限循环的两种方案1.while(1)2.for(;)好:一目了然好:一目了然不好:含义不明确不好:含义不明确3、中断服务程序、中断服务程序?中断是嵌入式系统中重要的组成部分,但是在标准中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断。许多编译开发商在标准中不包含中断。许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标识中断服务程序上增加了对中断的支持,提
7、供新的关键字用于标识中断服务程序(ISR),类似于,类似于_interrupt?当一个函数被定义为当一个函数被定义为ISR的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。中断服务程序的特点中断服务程序的特点?中断服务程序需要满足如下要求:中断服务程序需要满足如下要求:?不能返回值;不能返回值;?不能向不能向ISR传递参数;传递参数;?ISR应该尽可能的短小精悍;应该尽可能的短小精悍;?printf(char*lpFormatString,)函数会带来性能问题,不能在函数会带来性能问题,不能在
8、ISR中采用。中采用。备选专题备选专题中断服务程序模型中断服务程序模型?在项目的开发中,设计一个队列,在中断服务程序中,只是将中断类型添加入该队列中,在主程序的无限循环中不断扫描中断队列是否有中断,有则取出队列中的第一个中断类型,进行相应处理。在项目的开发中,设计一个队列,在中断服务程序中,只是将中断类型添加入该队列中,在主程序的无限循环中不断扫描中断队列是否有中断,有则取出队列中的第一个中断类型,进行相应处理。中断服务程序模型中断服务程序模型typedef struct tagIntQueue/*存放中断的队列存放中断的队列*/int intType;/*中断类型中断类型*/struct t
9、agIntQueue*next;IntQueue;IntQueue*lpIntQueueHead;_interrupt ISRexample()int intType;intType=GetSystemType();/*得到中断类型得到中断类型*/QueueAddTail(lpIntQueueHead,intType);/*在队列尾加入新的中断在队列尾加入新的中断*/主程序模型主程序模型While(1)if(!IsIntQueueEmpty()intType=GetFirstInt();switch(intType)case xxx:/*中断处理部分代码中断处理部分代码*/break;case
10、 xxx:break;4、硬件驱动模块、硬件驱动模块?一个硬件驱动模块通常应包括如下函数:一个硬件驱动模块通常应包括如下函数:?中断服务程序中断服务程序ISR?硬件初始化硬件初始化?修改寄存器,设置硬件参数(如修改寄存器,设置硬件参数(如UART应设置其波特率,应设置其波特率,AD/DA设备应设置其采样速率等);设备应设置其采样速率等);?将中断服务程序入口地址写入中断向量表:将中断服务程序入口地址写入中断向量表:硬件驱动模块(续)硬件驱动模块(续)/*设置中断向量表设置中断向量表*/m_myPtr=make_far_pointer(0l);/*返回返回void far型指针型指针void f
11、ar*/m_myPtr+=ITYPE_UART;/*ITYPE_UART:uart中断服务程序中断号,相对于中断向量表首地址的偏移中断服务程序中断号,相对于中断向量表首地址的偏移*/m_myPtr/*UART _Isr:UART的中断服务程序首地址的中断服务程序首地址*/硬件驱动模块(续)硬件驱动模块(续)?一个硬件驱动模块通常应包括如下函数:一个硬件驱动模块通常应包括如下函数:?设置设置CPU针对该硬件的控制线针对该硬件的控制线?如果控制线可作如果控制线可作PIO(可编程(可编程I/O)和控制信号用,则设置)和控制信号用,则设置CPU内部对应寄存器使其作为控制信号;内部对应寄存器使其作为控制
12、信号;?设置设置CPU内部的针对该设备的中断屏蔽位,设置中断方式(电平触发还是边缘触发)。内部的针对该设备的中断屏蔽位,设置中断方式(电平触发还是边缘触发)。硬件驱动模块(续)硬件驱动模块(续)?一个硬件驱动模块通常应包括如下函数:一个硬件驱动模块通常应包括如下函数:?提供一系列针对该设备的操作接口函数。例如,对于提供一系列针对该设备的操作接口函数。例如,对于LCD,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于时钟,其驱动模块则需提供获取时间、设置时间等函数。,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于时钟,其驱动模块则需提供获取时间、设置时间
13、等函数。5、C的面向对象化的面向对象化?在面向对象的语言里面,出现了类的概念。类是对特定数据的特定操作的集合体。类包含了两个范畴:数据和操作。而在面向对象的语言里面,出现了类的概念。类是对特定数据的特定操作的集合体。类包含了两个范畴:数据和操作。而C语言中的语言中的struct仅仅是数据的集合,我们可以利用函数指针将仅仅是数据的集合,我们可以利用函数指针将struct模拟为一个包含数据和操作的模拟为一个包含数据和操作的类类。用用C程序模拟一个最简单的程序模拟一个最简单的类类:#define C_Class structC_Class A C_Class A*A_this;/*this指针指针*
14、/void(*foo)(C_Class A*A_this);int(*parea)(int length,int width);/*行为:函数指针行为:函数指针*/int a;/*数据数据*/int b;二、屏幕操作二、屏幕操作?汉字处理汉字处理?系统时间显示系统时间显示?定时器定时器?菜单操作菜单操作?模拟模拟MessageBox1、汉字处理、汉字处理?嵌入式系统汉字库的特点嵌入式系统汉字库的特点嵌入式系统中经常使用的并非是完整的汉字库,往往只是需要提供数量有限的汉字供必要的显示功能。例如,一个微波炉的嵌入式系统中经常使用的并非是完整的汉字库,往往只是需要提供数量有限的汉字供必要的显示功能。
15、例如,一个微波炉的LCD上没有必要提供显示上没有必要提供显示“电子邮件电子邮件”的功能;一个提供汉字显示功能的空调的的功能;一个提供汉字显示功能的空调的LCD上不需要显示一条上不需要显示一条“短消息短消息”,诸如此类。,诸如此类。但是一部手机则通常需要包括较完整的汉字库。但是一部手机则通常需要包括较完整的汉字库。完整字库完整字库如果包括的汉字库较完整,那么,由内码计算出汉字字模在库中的偏移是十分简单的:汉字库是按照区位的顺序排列的,前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录如果包括的汉字库较完整,那么,由内码计算出汉字字模在库中的偏移是十分简单的:汉字库是按照区位的顺序排列
16、的,前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录94个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:94*(区号区号-1)+位号位号-1然后乘上一个汉字字模占用的字节数即可,以然后乘上一个汉字字模占用的字节数即可,以16*16点阵字库为例,即:点阵字库为例,即:(94*(区号区号-1)+(位号位号-1)*32汉字库中从该位置起的汉字库中从该位置起的32字节信息记录了该字的字模信息。字节信息记录了该字的字模信息。仅使用少量汉字仅使用少量汉字#define EX_FONT_
17、WORD(value)(value)#define EX_FONT_UNICODE_VAL(value)(value)typedef struct _wide_unicode_font16x16 unsigned char word3;int value;/内码内码unsigned char data32;/*字模点阵字模点阵*/Unicode;#define CHINESE_CHAR_NUM4/*汉字数量汉字数量*/仅使用少量汉字(续)仅使用少量汉字(续)Unicode chineseCHINESE_CHAR_NUM=EX_FONT_WORD(业业),EX_FONT_UNICODE_VAL(
18、0 x4e1a),0 x04,0 x40,0 x04,0 x40,0 x04,0 x40,0 x04,0 x44,0 x44,0 x46,0 x24,0 x4c,0 x24,0 x48,0 x14,0 x50,0 x1c,0 x50,0 x14,0 x60,0 x04,0 x40,0 x04,0 x40,0 x04,0 x44,0 xff,0 xfe,0 x00,0 x00,0 x00,0 x00,.,.,.仅使用少量汉字(续)仅使用少量汉字(续)?要显示特定汉字的时候,只需要从数组中查找内码与要求汉字内码相同的即可获得字模。如果前面的汉字在数组中以内码大小顺序排列,那么可以以二分查找法更高效
19、的查找到汉字的字模。要显示特定汉字的时候,只需要从数组中查找内码与要求汉字内码相同的即可获得字模。如果前面的汉字在数组中以内码大小顺序排列,那么可以以二分查找法更高效的查找到汉字的字模。?这是一种很有效的组织小汉字库的方法,它可以保证程序有很好的结构。这是一种很有效的组织小汉字库的方法,它可以保证程序有很好的结构。2、系统时间显示、系统时间显示?在时间显示函数中以静态变量分别存储小时、分钟、秒,只有在其内容发生变化的时候才更新其显示。在时间显示函数中以静态变量分别存储小时、分钟、秒,只有在其内容发生变化的时候才更新其显示。系统时间显示(续)系统时间显示(续)#define BYTE unsig
20、ned charextern void DisplayTime()static BYTE byHour,byMinute,bySecond;BYTE byNewHour,byNewMinute,byNewSecond;byNewHour=GetSysHour();byNewMinute=GetSysMinute();byNewSecond=GetSysSecond();if(byNewHour!=byHour)/*显示小时显示小时*/byHour=byNewHour;if(byNewMinute!=byMinute)/*显示分钟显示分钟*/byMinute=byNewMinute;if(byN
21、ewSecond!=bySecond)/*显示秒钟显示秒钟*/bySecond=byNewSecond;3、定时器、定时器?希望显示会闪烁的希望显示会闪烁的“:”,用来分隔时间,用来分隔时间单位。随着时间的变更,在屏幕上显示单位。随着时间的变更,在屏幕上显示不同的静止画面,即是动画之本质。所不同的静止画面,即是动画之本质。所以,在一个嵌入式系统的以,在一个嵌入式系统的LCD上欲显上欲显示动画,必须借助定时器。没有硬件或示动画,必须借助定时器。没有硬件或软件定时器的世界是无法想像的软件定时器的世界是无法想像的思考:定时器的用途思考:定时器的用途?请举例说明定时器都在哪些场合得到应用请举例说明定时
22、器都在哪些场合得到应用思考:定时器的用途思考:定时器的用途?没有定时器,一个操作系统将无法进行时间片的轮转,于是无法进行多任务的调度,于是便不再成其为一个多任务操作系统;没有定时器,一个操作系统将无法进行时间片的轮转,于是无法进行多任务的调度,于是便不再成其为一个多任务操作系统;?没有定时器,一个多媒体播放软件将无法运作,因为它不知道何时应该切换到下一帧画面;没有定时器,一个多媒体播放软件将无法运作,因为它不知道何时应该切换到下一帧画面;?没有定时器,一个网络协议将无法运转,因为其无法获知何时包传输超时并重传之,无法在特定的时间完成特定的任务。没有定时器,一个网络协议将无法运转,因为其无法获知
23、何时包传输超时并重传之,无法在特定的时间完成特定的任务。思考:定时器的用途思考:定时器的用途void ShowDot()static BOOL bShowDot=TRUE;if(bShowDot)showChar(:,xPos,yPos);elseshowChar(,xPos,yPos);bShowDot=!bShowDot;4、菜单操作、菜单操作?要求以键盘上的要求以键盘上的 键切换菜单焦键切换菜单焦点,当用户在焦点处于某菜单时,若敲点,当用户在焦点处于某菜单时,若敲击键盘上的击键盘上的OK、CANCEL键则调用该键则调用该焦点菜单对应之处理函数。焦点菜单对应之处理函数。菜单菜单1菜单菜单2
24、菜单菜单3菜单菜单4菜单实现方法菜单实现方法1/*按下按下OK键键*/void onOkKey()/*判断在什么焦点菜单上按下判断在什么焦点菜单上按下Ok键,调用相应处理函数键,调用相应处理函数*/Switch(currentFocus)case MENU1:menu1OnOk();break;case MENU2:menu2OnOk();break;菜单实现方法菜单实现方法1(续)(续)/*按下按下Cancel键键*/void onCancelKey()/*判断在什么焦点菜单上按下判断在什么焦点菜单上按下Cancel键,调用相应处理函数键,调用相应处理函数*/Switch(currentFo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 编程 综述
限制150内