收藏 分销(赏)

第一章2 加 嵌入式C语言概述.ppt

上传人:xrp****65 文档编号:13738550 上传时间:2026-04-07 格式:PPT 页数:37 大小:728KB 下载积分:10 金币
下载 相关 举报
第一章2 加 嵌入式C语言概述.ppt_第1页
第1页 / 共37页
第一章2 加 嵌入式C语言概述.ppt_第2页
第2页 / 共37页


点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,嵌入式,C,语言概述,引入,变量定义的时机,for,(,loop=1,;,loop=limit,;,loop+,),for,(,loop=limit,;,loop!=0,;,loop-,),目录,任务和模块,中断服务程序,数据指针,数据指针,函数指针,动态内存申请,关键字,volatile,多任务还是单任务,(,1,)从,CPU,复位时的指定地址开始执行;(,2,)跳转至汇编代码,startup,处执行;(,3,)跳转至用户主程序,main,执行,在,main,中完成:,a.,初试化各硬件设备;,b.,初始化各软件模块;,c.,进入死循环(无限循环),调用各模块的处理函数,模块划分,(,1,)模块即是一个,.c,文件和一个,.h,文件的结合,头文件,(.h),中是对于该模块接口的声明;(,2,)某模块提供给其它模块调用的外部函数及数据需在,.h,中文件中冠以,extern,关键字声明;(,3,)模块内的函数和全局变量需在,.c,文件开头冠以,static,关键字声明;(,4,)永远不要在,.h,文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,一个嵌入式系统通常包括两类模块:(,1,)硬件驱动模块,一种特定硬件对应一个模块;(,2,)软件功能模块,其模块的划分应满足低偶合、高内聚的要求,/*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/*,在模块,3,中包含模块,1,的,.h,文件*,/,/*module1.h*/extern,int,a;/*,在模块,1,的,.h,文件中声明,int,a*/*module1.c*/#include module1.h/*,在模块,1,中包含模块,1,的,.h,文件*,/,int,a=5;/*,在模块,1,的,.c,文件中定义,int,a*/*module2.c*/#include module1.h/*,在模块,2,中包含模块,1,的,.h,文件*,/*module3.c*/#include module1.h/*,在模块,3,中包含模块,1,的,.h,文件*,/,中断服务程序,_interrupt,、,#program interrupt,等,中断服务程序需要满足如下要求:,(1),不能返回值;,(2),不能向,ISR,传递参数;,(3)ISR,应该尽可能的短小精悍;,(4),printf(char,*,lpFormatString,),函数会带来重入和性能问题,不能在,ISR,中采用。,一个硬件驱动模块通常应包括如下函数:(,1,)中断服务程序,ISR,(,2,)硬件初始化,a.,修改寄存器,设置硬件参数(如,UART,应设置其波特率,,AD/DA,设备应设置其采样速率等);,b.,将中断服务程序入口地址写入中断向量表:,/*,设置中断向量表*,/,m_myPtr,=make_far_pointer(0l);/*,返回,void far,型指针,void far*/,m_myPtr,+=ITYPE_UART;/*ITYPE_UART,:,uart,中断服务程序*,/*,相对于中断向量表首地址的偏移*,/*,m_myPtr,=&UART _,Isr,;/*UART _,Isr,:,UART,的中断服务程序*,/,(,3,)设置,CPU,针对该硬件的控制线,a.,如果控制线可作,PIO,(可编程,I/O,)和控制信号用,则设置,CPU,内部对应寄存器使其作为控制信号;,b.,设置,CPU,内部的针对该设备的中断屏蔽位,设置中断方式(电平触发还是边缘触发)。(,4,)提供一系列针对该设备的操作接口函数。例如,对于,LCD,,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于实时钟,其驱动模块则需提供获取时间、设置时间等函数。,unsigned char*p=(unsigned char*)0 xF000FF00;*p=11;,int,*p=(,int,*)0 xF000FF00;,long,int,*p=(long,int,*)0 xF000FF00;,数据指针,typedef,void(*,lpFunction,)();/*,定义一个无参数、无返回类型的*,/*,函数指针类型*,/,lpFunction,lpReset,=(lpFunction)0 xF000FFF0;/*,定义一个函数指针,指向*,/*CPU,启动后所执行第一条指令的位置*,/,lpReset,();/*,调用函数*,/,函数指针,数组,vs.,动态申请,在嵌入式系统中动态内存申请存在比一般系统编程时更严格的要求,这是因为嵌入式系统的内存空间往往是十分有限的,不经意的内存泄露会很快导致系统的崩溃。所以一定要保证你的,malloc,和,free,成对出现,,谁申请,就由谁释放,char*p=,malloc,();,if(p,=NULL);,function(p,);,free(p,);p=NULL;,而函数,function,则接收参数,p,,如下:,void,function(char,*p),/*,一系列针对,p,的操作*,/,关键字,volatile,int,a,b,c,;a=inWord(0 x100);/*,读取,I/O,空间,0 x100,端口的内容存入,a,变量*,/b=a;a=,inWord,(0 x100);/*,再次读取,I/O,空间,0 x100,端口的内容存入,a,变量*,/c=a;,int,a,b,c,;a=inWord(0 x100);/*,读取,I/O,空间,0 x100,端口的内容存入,a,变量*,/b=a;c=a;,volatile,int,a,;,volatile,变量可能用于如下几种情况:,(1),并行设备的硬件寄存器(如:状态寄存器,例中的代码属于此类);,(2),一个中断服务子程序中会访问到的非自动变量,(,也就是全局变量,),;,(3),多线程应用中被几个任务共享的变量。,1,使用宏定义,在,C,语言中,宏是产生内嵌代码的唯一方法。,#define MIN(A,B),(,A,),外部同步,RAM,外部异步,RAM,FLASH/ROM,5,活用位操作,/*,方法,1*/,int,i,j,;i=879/16;j=562%32;/*,方法,2*/,int,i,j;i=879 4;j=562-(562 5 5);,#define INT_I2_MASK 0 x0040,wTemp,=,inword(INT_MASK,);,outword(INT_MASK,wTemp,#define INT_I2_MASK 0 x0040,wTemp,=,inword(INT_MASK,);,outword(INT_MASK,wTemp,|INT_I2_MASK);,#define INT_I2_MASK 0 x0040,wTemp,=,inword(INT_MASK,);,if(wTemp,&INT_I2_MASK)/*,该位为,1*/,其它常见问题,汉字和图形的显示,菜单的处理,动画的处理,键盘的处理,时间的处理,II,ARM中C和汇编混合编程,1.,汇编举例,2.ARM,程序组织,3.,在,C,语言中内嵌汇编,5,在,C,中调用汇编的函数,4.,在汇编中使用,C,定义的全局变量,6.,在汇编中调用,C,的函数,AREA,init,CODE,READONLY,CODE32,Mode_USR,EQU 0 x10;CPSR,中各种处理器模式对应的控制位,I_Bit,EQU 0 x80;CPSR,中的中断禁止位,F_Bit,EQU 0 x40,USR_Stack,EQU 0 x00203000;,定义,RAM,的最高地址,无重映射,ENTRY,B,InitReset,;0 x00 Reset handler,undefvec,B,undefvec,;0 x04 Undefined Instruction,swivec,B,swivec,;0 x08 Software Interrupt,pabtvec,B,pabtvec,;0 x0C,Prefetch,Abort,dabtvec,B,dabtvec,;0 x10 Data Abort,rsvdvec,B,rsvdvec,;0 x14 reserved,irqvec,B,irqvec,;0 x18 IRQ,fiqvec,B,fiqvec,;0 x1c FIQ,InitReset,MSR,CPSR_c,#Mode_USR,|,I_Bit,|,F_Bit,;,改成用户模式且禁止,IRQ,和,FIQ,中断,LDR SP,=,USR_Stack,BLX _main ;,跳转到,_main,执行,它,例2,3.,在,C,语言中内嵌汇编,内嵌汇编使用的标记是,_,asm,或者,asm,关键字,用法如下:,_,asm,instruction;instruction,instruction,asm(“instruction,;instruction”);,内嵌汇编注意点,a.,不能直接向,PC,寄存器赋值,程序跳转要使用,B,或者,BL,指令,b.,在使用物理寄存器时,不要使用过于复杂的,C,表达式,避免物理寄存器冲突,c.R12,和,R13,可能被编译器用来存放中间编译结果,计算表达式值时可能将,R0,到,R3,、,R12,及,R14,用于子程序调用,因此要避免直接使用这些物理寄存器,d.,一般不要直接指定物理寄存器,而让编译器进行分配,#include,void,my_strcpy(const,char*,src,char*,dest,),char,ch,;,_,asm,loop:,ldrb,ch,src,#1,strb,ch,dest,#1,cmp,ch,#0,bne,loop,int,main(),char*a=forget it and move on!;,char b64;,my_strcpy(a,b);,printf(original,:%s,a);,printf(copyed,:%s,b);,return 0;,内嵌汇编举例,C,和汇编之间的值传递是用,C,的指针来实现的,,因为指针对应的是地址,所以汇编中也可以访问。,4,在汇编中使用,C,定义的全局变量,/*,cfile.c,*,定义全局变量,并作为主调程序,*,/,#include,int,gVar_1=12;,extern,asmDouble(void,);,int,main(),printf(original,value of gVar_1 is:%d,gVar_1);,asmDouble,();,printf,(modified value of gVar_1 is:%d,gVar_1);,return 0;,;called by,main(in,C),to,double an integer,a global,var,defined in C is used.,AREA,asmfile,CODE,READONLY,EXPORT,asmDouble,IMPORT gVar_1,asmDouble,ldr,r0,=gVar_1,ldr,r1,r0,mov,r2,#2,mul,r3,r1,r2,str,r3,r0,mov,pc,lr,END,5,在,C,中调用汇编的函数,一是在,C,中声明函数原型,并加,extern,关键字;,二是在汇编中用,EXPORT,导出函数名,并用该函数名作为汇编代码段的标识,最后用,mov,pc,lr,返回。然后,就可以在,C,中使用该函数了,例:在,C,中调用汇编的函数,/*,cfile.c,*in,C,call,an,asm,function,asm_strcpy,*Sep 9,2004,*/,#include,extern void,asm_strcpy(const,char*,src,char*,dest,);,int,main(),const char*s=seasons in the sun;,char d32;,asm_strcpy(s,d);,printf(source,:%s,s);,printf,(destination:%,s,d,);,return 0;,;,asm,function implementation,AREA,asmfile,CODE,READONLY,EXPORT,asm_strcpy,asm_strcpy,loop,ldrb,r4,r0,#1;address increment after read,cmp,r4,#0,beq,over,strb,r4,r1,#1,b loop,over,mov,pc,lr,END,ATPCS,(,ARM Thumb Procedure Call Standard,),C,和汇编之间的参数传递是通过,ATPCS,(,ARM Thumb Procedure Call Standard,)的规定来进行的。简单的说就是如果函数有不多于四个参数,对应的用,R0-R3,来进行传递,多于,4,个时借助栈,函数的返回值通过,R0,来返回。,ATPCS,是基于,arm,指令集和,thumb,指令集过程调用的规范。,ATPCS,寄存器的使用规则,寄存器的使用必须满足下面的规则:,1.,子程序间通过寄存器,R0 R3,来传递参数,这时,寄存器,R0R3,可以记作,A1-A4,。被调用的子程序在返回前无需恢复寄存器,R0-R3,的内容。,2.,在子程序中,使用寄存器,R4 R11,来保存局部变量这时,寄存器,R4-R11,可以记作,V1-V8,。如果在子程序中使用到了寄存器,V1-V8,中的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值;对于子程序中没有用到的寄存器则不必进行这些操作。在,Thumb,程序中,通常只能使用寄存器,R4-R7,来保存局部变量。,3.,寄存器,R12,用作子程序间,scratch,寄存器(用于保存,SP,,在函数返回时使用该寄存器出栈),记作,ip,。在子程序间的连接代码段中常有这种使用规则。,4.,寄存器,R13,用作数据栈指针,记作,sp,。在子程序中寄存器,R13,不能用作其他用途。寄存器,sp,在进入子程序时的值和退出子程序时的值必须相等。,5.,寄存器,R14,称为连接寄存器,记作,lr,。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器,R14,则可以用作其他用途。,6.,寄存器,R15,是程序计数器,记作,pc,。它不能用作其他用途,。,6,在汇编中调用,C,的函数,在汇编中调用,C,的函数,需要在汇编中,IMPORT,对应的,C,函数名,然后将,C,的代码放在一个独立的,C,文件中进行编译,剩下的工作由连接器来处理。,例:在汇编中调用,C,的函数,;the details of parameters transfer comes from ATPCS,;if there are more than 4,args,stack will be used,EXPORT,asmfile,AREA,asmfile,CODE,READONLY,IMPORT,cFun,ENTRY,mov,r0,#11,mov,r1,#22,mov,r2,#33,BL,cFun,END,/*C file,called by,asmfile,*/,int,cFun(int,a,int,b,int,c),return a+b+c;,在汇编中调用,C,的函数,参数的传递也是通过,ATPCS,来实现的。,需要指出的是当函数的参数个数大于,4,时,要借助,stack,,,天分决定速度,勤奋决定高度,关于实验二,
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 应用文书 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服