您好,欢迎访问三七文档
原创翻译,转载注明作者:小楼听雨来源:编程教程:引言►引言用c语言为微控制器编程正在变的越来越普通,通常用汇编建立一个应用比用c语言要难的多,因此掌握嵌入式c编程是非常重要的。由于我们使用KeilC51编译器,也常常称之为KeilC。►关键字KeilC编译器添加的一些关键字:_at_farsbitalienidatasfrbdatainterruptsfr16bitlargesmallcodepdata_task_compact_priority_usingdatareentrantxdatadata/idata:描述:变量将被存储在控制器内部ram中。example:CODE:unsignedchardatax;//orunsignedcharidatay;bdata:描述:变量被存储在可位寻址的内部ram中。CODE:unsignedcharbdatax;//变量x的每一位可按以下的方式存取x^1=1;//设置x的第一位x^0=0;//清除x的第零位xdata:描述:变量将被存储在控制器外部ram中。example:CODE:unsignedcharxdatax;code:描述:这个关键字是用来将常量存储在rom中。假设你有一个大的字符串,而且这个字符串在程序中不会再被改变,为这个字符串浪费ram是很愚蠢的事,因此我们要像下面的例子一样运用code关键字。example:CODE:unsignedcharcodestr=thisisaconstantstring;pdata:描述:这个关键字将会使变量存储在分页寻址ram中,它运用不是很频繁。example:CODE:unsignedcharpdatax;_at_:描述:用来将变量存储在ram的指定位置。example:CODE:unsignedcharidatax_at_0x30;//变量x将会存储在内部ram的0x30处sbit:描述:这个关键字用来定义SFR(特殊功能寄存器)的某一位。example:CODE:sbitPort0_0=0x80;//地址0x80被定义为特殊位Port0_0sfr:描述:sfr被用来定义一个8位的特殊功能寄存器。example:CODE:sfrPort1=0x90;//地址0x90被定义为特殊功能寄存器Port1sfr16:描述:用来定义两个连续的8位特殊功能寄存器。example:CODE:sfr16DPTR=0x82;//开始于0x82的16位特殊功能寄存器using:描述:这个关键字位某个函数定义寄存器组,用户可以指定0-3的寄存器组。example:CODE:voidfunction()using2{//code}//名为function的函数在执行代码的时候使用寄存器组2interrupt:描述:这个关键字将会告诉编译器被描述的函数是一个终端服务程序。C51编译器支持最多32个中断源(0-31),使用下面的中断向量地址来决定中断号。example:CODE:voidExternal_Int0()interrupt0{//code}►存储器模式用户有三种类型的存储器模式变量:1.Small:所有变量都在内部ram中。2.Compact:参数及局部变量放入分页外内部存贮区(最大256bytes)。3.large:所有变量都在外部ram中,使用DPTR存取。根据我们硬件的配置我们能够向下面这样指定存储器模式:CODE://ForSmallMemorymodel#pragmasmall//ForCompactmemorymodel#pragmacompact//Forlargememorymodel#pragmalarge原文:keilCProgrammingTutorial:Introduction原创翻译,转载注明作者:小楼听雨来源:编程教程:指针►KeilC中的指针KeilC中的指针类似于标准C,可以完成标准C中指针的所有运算。另外,KeilC扩展了它的运算去满足8051微控制器架构,KeilC提供两种不同类型的指针:1.一般指针2.存储器指针►一般指针一般指针同标准C中的指针声明是一样的CODE:char*ptr;//字符型指针int*num;//整型指针一般指针用三个字节存储。第一个存储存储器类型,第二个第三个分别是高位偏移和低位偏移。一般指针能够存取任何变量,无论该变量在什么位置。►存储器指针存储器指针在指针说明时就指定了存储类型,例如:CODE:chardata*c;//指向一个存储在ram中的字符charxdata*c1;//指向一个存储在外部ram中的字符charcode*c2;//指向一个存储在rom中的字符由于存储器指针在编译时已经指定存储类型,存储器指针存放时需要一个(idata,data,bdata以及pdata指针)或两个字节(code和xdata指针)。KeilC为存储器指针生成的代码比为一般指针生成的代码执行速度要快,这是因为存储器指针指向的内容类型在编译的时候是已知的而不是在运行的时候,编译器使用这些信息优化存取过程,因此如果你追求的是速度至上,那么推荐你用存储器指针。一般指针和寄存器指针都可以在它们声明时指定存放区域。例如:CODE://一般指针char*idataptr;//字符型指针,该指针存储在内部ram中int*xdataptr1;//整型指针,该指针存储在外部ram中//存储器指针charidata*xdataptr2;//指向内部ram的字符型指针,该指针存储在外部ram中。intxdata*dataptr3;//指向外部ram的字符型指针,该指针存储在ram中。原文:keilCProgrammingTutorial:pointers原创翻译,转载注明作者:小楼听雨来源:编程教程:函数►KeilC中的函数KeilC编译器对标准c的函数声明进行的扩展如下:为中断过程指定函数选择要使用的寄存器组选择存储器模式►函数定义[Return_type]Fucntion_name([Arguments])[Memory_model][reentrant][interruptn][usingn]Return_type:函数返回值的类型,如果没有指定函数返回值类型,默认为int型。Function_name:函数名。Arguments:传递给函数的参数。可选项:这些选项你可以再函数定义的时候指定。Memory_model:为函数指明存储器模式(Large,Compact,Small),例如:CODE:intadd_number(inta,intb)Largereentrant:指明这个函数是可重入的还是递归的,关于这个选项稍后教程会进一步解释。interrupt:指明这个函数是一个中断服务程序,关于这个选项稍后教程会进一步解释。using:指定函数执行过程中使用的寄存器组,8051架构有三个寄存器组,使用usingn指定寄存器组n。CODE:voidfunction_name()using2{//函数使用寄存器组2//函数代码}►中断服务程序可以用关键字interrupt和中断号将一个函数指定为中断服务程序,中断号指明终端服务程序所要处理的中断。下面的表格描述了默认的中断:由于8051生产商创造了新的器件,加入了更多的中断。KeilC51支持32个中断(0-31),使用下表的中断向量入口地址去决定中断号。中断函数可以像下面这样定义:CODE:voidisr_name(void)interrupt2{//中断程序代码}注意中断服务程序没有参数,返回类型只能是空。►可重入函数在ANSIC中有递归函数,在嵌入式C中为了满足同样的需求,我们有可重入函数,这些函数可以被递归地调用,被两个或两个以上的进程同时调用。你现在可能在想,为什么要定义可重入函数?你必须知道这些函数在递归调用的时候是怎样工作的,当一个函数在执行的时候,会有一些和它相关的动态数据,比如局部变量,当函数被递归地调用或者两个以上的进程同时调用时,CPU必须保持局部变量的状态。可重入函数定义如下:CODEvoidfunction_name(intargument)reentrant{//函数代码}每一个可重入函数都有相应的栈,由startup.A51文件定义。存储器模式决定了可重入函数的堆栈存储的区域。Small模式可重入函数堆栈在内部ram中。Compant模式可重入函数堆栈在分页寻址ram中。Large模式可重入函数堆栈在外部ram中。►实时任务KeilC51支持实时系统(RTOS)RTX51Full和RTX51Tiny。实时任务函数使用_task_和_priority_关键字定义,_task_定义一个实时任务函数,_priority_指明任务的优先级。函数定义如下:CODE:voidfunc(void)_task_Number_priority_Priority{//code}Number:任务ID,RTX51Full是0到255,RTX51Tiny0到15。Priority:任务优先级。实时任务函数必须被定义为返回值为空且参数为空(没有参数传递给任务函数)。原文:keilCProgrammingTutorial:Functions原创翻译,转载注明作者:小楼听雨来源:编程教程:用Keil编写简单的C程序►C编程基础正如我们前面讨论的那样,KeilC与普通C语言编程并没有很大的区别。如果你了解汇编,写一个C程序更不会有问题,你唯一要记住的就是忘记控制器的通用寄存器和累加器,但是不要忘记端口和外围设备以及相关的寄存器。在标准C中,所有的程序至少有一个main函数作为应用程序的入口点。与此相似,KeilC中也有main函数,你所有的工作都在函数中完成,让我们进一步探究一下程序的工作流程。当你在PC上运行C程序时,对于操作系统你的程序可以看做是一个子程序或进程,因此当程序退出后,将返回到操作系统。然而,在嵌入式C中没有操作系统,你必须确保你的程序一直在运行,从不退出。用while(1)或者for(;;)进行无休止的循环即可实现。下面展示了一个基础C编程的轮廓:CODE:voidmain(){//初始化代码while(1){//while1循环//这个循环中加入你需要无休止循环的代码}}当你为特定的控制器编写程序时,首先需要为该控制器添加头文件。项目建立后,为你的项目添加C文件,你唯一要做的就是在编辑窗口点击鼠标右键,它将会显示正确的头文件。下图展示了添加头文件的窗口内容:►编写特定的硬件代码在编写硬件代码的时候,我们使用硬件设备如端口、定时器和串口等。不要忘记添加你使用的控制器的头文件,否则无法操作相关设备的寄存器。我们编写一段简单的代码让端口1的引脚1上的LED闪烁:CODE:#includeREGx51.h//89C51头文件voidmain(){//mainfunctionstartsunsignedinti;//InitializingPort1pin1P1_1=0;//MakePin1o/pwhile(1){//Infiniteloopmainapplication//comesherefor(i=0;i1000;i++);//delayloopP1_1=~P1_1;//complementPort1.1//t
本文标题:KeilC编程教程
链接地址:https://www.777doc.com/doc-2879885 .html