您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 单片机C51 C语言课件
补充:C51程序设计本讲重点:C51的数据类型和存储类型;指针和中断的使用;通过实例消化理解C51的编程方法;尝试将实验课中的ASM51程序转为C51程序.用C语言进行单片机程序设计是单片机开发与应用的必然趋势。单片机教学中的程序设计应以C语言为主,汇编语言为辅。对汇编语言掌握到只要可以读懂程序,在时间要求比较严格的模块中进行程序的优化即可。采用C语言不必对单片机和硬件接口结构有很深入的了解,编译器可以自动完成变量的存贮单元的分配,编程者可以专注于应用软件部分的设计,大大加快软件的开发速度。产品中的单片机重新选型后,C语言可以很容易地进行程序移植工作。从1985年开始就有了8051单片机的C语言编译器,简称C51。㈠C51简介目前比较流行的C51编译器是KeilC51其集成开发软件为KeiluVision2,它集编辑、编译、仿真于一体,界面友好,易学易用。C51与ASM51相比,有如下优点:1.对单片机的指令系统不要求了解,仅要求对8051的存贮器结构有初步了解;2.寄存器分配、不同存贮器的寻址及数据类型等细节可由编译器管理;3.程序有规范的结构,可分成不同的函数,这种方式可使程序结构化;4.提供的库包含许多标准子程序,具有较强的数据处理能力;6.由于具有方便的模块化编程技术,使已编好程序可容量地植入新程序;C51扩展关键字bit与sbit的使用对于可位寻址的SFR空间和RAM空间的字节型变量,可以定义特殊位变量标识该变量的某一位,这种位数据类型的标识符为sbit.在程序设计时,对于可位寻址对象,既可以按字节寻址也可以按位寻址的变量,其存储类型只能是bdata.intbdataa;charbdatab[4];然后可以使用sbit关键字定义其中可独立寻址访问的位变量:sbita0=a^0;sbita12=a^12;sbitb03=b[0]^3;sbitb36=b[3]^6;㈢C51的数据类型基本数据类型:㈡C51的程序结构与一般C语言的结构相同,以main()函数为程序人口,程序体中包含若干语句还可以包含若干函数。位型字符型整型长整型浮点型bitcharintlongintfloat1位1字节2字节4字节4字节构造类型:数组、结构体、共用体、枚举指针类型(精华)(1)字符型:char、unsignedchar;(2)整型:int、unsignedint、long、unsignedlong;(3)浮点与双精度型:float、double;(4)C51中扩展的类型:bit、sfr、sfr16、sbit(5)结构体、指针等bit:位类型如:bitrun_flag;sfr:特殊功能寄存器类型,如sfrP0=0x80;(0x80为地址)sfr16:16位特殊功能寄存器类型,如sfr16DPTR=0x82;(即DPTR)sbit:特殊功能寄存器位类型如sbitEINT=0xAF;(0xAF为位地址。即EA)㈢C51的数据类型㈣C51数据的存储类型存储类型说明data直接访问内部数据存储器(128字节)访问速度最快bdata可位寻址内部数据存储器(16字节),允许位与字节混合访问;idata间接访问内部数据存储器(256字节),允许访问全部内部数据区;pdata分页访问外部数据存储器(256字节),用MOVX@Ri指令访问;xdata外部数据存储器(64K),用MOVX@DPTR指令;code程序存储器(64K),用MOVC@A+DPTR指令;定义格式:[存储种类][存储类型]数据类型变量名;也可写为:[存储种类]数据类型[存储类型]变量名;存储种类有:静态变量(static)和动态变量(auto缺省)存储类型有:data、idata、bdata;xdata、pdata和code。(五)变量的定义方法#defineucharunsignedcharuchardataa1;/*字符变量a1定位在8051的片内数据存储区中*/bitbdataflag;/*位变量flag定位在8051的片内数据存储区中的可位寻址区*/floatidatax;/*浮点变量x定位在8051的片内数据存储区中并只能通过间接寻址来访问*/ucharxdatas[]={3,4,7,2,12,8};/*无符号字符数组s定位在片外数据存储区中*/ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};/*无符号字符数组table定位在ROM区中*/变量的绝对定位用关键字:_at_格式:[存储类型][存储种类]数据类型变量名_at_constant;Constant为定位的地址如:datacharmusich_at_0x29,musicl_at_0x2a;charbuf[8]_at_0x30;㈥C51的运算符与C语言基本相同:+-*/%++--(加减乘除取余增量运算符减量运算符)==(大于大于等于小于小于等于)==!=(等于不等于)&&||!(逻辑与逻辑或逻辑非)(位右移位左移)&|(按位与按位或)^~(按位异或按位取反)(七)C51包含的头文件通常有:reg51.hmath.hctype.hstdio.hstdlib.habsacc.h常用有:reg51.h(定义特殊功能寄存器和位寄存器);math.h数学函数库(定义常用数学运算);absacc.h绝对地址访问头文件(定义一些宏用来对存储器空间进行绝对地址访问)intrins.h内部函数库(包含变量循环移位、位操作等函数)(八)C51的基本语句与标准C语言基本相同:if选择语言switch/case多分支选择语言while循环语言do-while循环语言for循环语言(九)中断服务程序函数名()interruptnusingm{}Interrupt关键字是不可缺少的,由它告诉编译器该函数是中断服务函数,并由后面的n指明所使用的中断号。n的取值范围为0-31,但具体的中断号要取决于芯片的型号,at89c51实际上就使用0-4号中断。每个中断号都对应着一个中断向量,具体地址为8n+3,中断源响应后处理器会跳转到中断向量所处的地址执行程序,编译器会在这地址上产生一个无条件跳转语句,转到中断服务函数所在的地址执行程序。关键字using后跟一个0到3的数对应着4组工作寄存器。(十)I/O口定义#includeabsacc.h#defineprotxbyte[0x1000]或用指针定义★C51程序#includereg51.hmain(){inti;unsignedcharxdata*p=0x2000;/*指针指向2000H单元*/for(i=0;i256;i++)/*清零2000H-20FFH单元*/{*p=0;p++;}}例1.清零程序(将2000H—20FFH的内容清零)★汇编语言程序ORG0000HSE01:MOVR0,#00HMOVDPTR,#2000H;(0000H)送DPTRLOO1:CLRAMOVX@DPTR,A;0送(DPTR)INCDPTR;DPTR+1INCR0;字节数加1CJNER0,#00H,LOO1;不到FF个字节再清LOOP:SJMPLOOP例2.拆字程序(将2000H的内容拆开,高位送2001H低位,低位送2002H低位)★汇编语言程序ORG0000HSE02:MOVDPTR,#2000HMOVXA,@DPTRMOVB,A;(2000)→A→BSWAPA;交换ANLA,#0FH;屏敝高位INCDPTRMOVX@DPTR,A;送2001HINCDPTRMOVA,BANLA,#0FH;(2000)内容屏敝高位MOVX@DPTR,A;送2002HSJMP$★拆字C51程序#includereg51.hmain(){unsignedcharxdata*p=0x2000;/*指针指向2000H单元*//*2002H单元高4位清零,低4位装2000H单元低4位*/*(p+2)=(*p)&0x0f;/*2001H单元高4位清零,低4位装2000H单元高4位*/*(p+1)=(*p)4;}★汇编语言程序ORG0000HL00:MOVR0,#10H;查找16个字节MOVR1,#00HMOVDPTR,#2000HL11:MOVXA,@DPTRCJNEA,#00H,L16;取出内容与00H相等吗?INCR1;取出个数加1L16:INCDPTRDJNZR0,L11;未完继续MOVDPTR,#2100HMOVA,R1MOVX@DPTR,A;相同数个数送2100HL1E:SJMPL1E例3.查找零的个数(在2000H--200FH中查出有几个字节是零,把个数放在2100H单元中)★查找零的个数C51程序#includereg51.hmain(){unsignedcharxdata*p=0x2000;/*指针p指向2000H单元*/intn=0,i;for(i=0;i16;i++){if(*p==0)n++;/*若该单元内容为零,则n+1*/p++;/*指针指向下一单元*/}p=0x2100;/*指针p指向2100H单元*/*p=n;/*把个数放在2100H单元中*/}★汇编程序ORG0000HMOVA,R3MOVB,R7MULAB;R3*R7XCHA,R7;R7=(R3*R7)低字节MOVR5,B;R5=(R3*R7)高字节MOVB,R2MULAB;R2*R7ADDA,R5MOVR4,ACLRAADDCA,BMOVR5,A;R5=(R2*R7)高字节MOVA,R6MOVB,R3MULAB;R3*R6ADDA,R4XCHA,BADDCA,R5MOVR5,AMOVPSW.5,C;存CYMOVA,R2MULAB;R2*R6ADDA,R5MOVR5,ACLRAMOVACC.0,CMOVC,PSW.5;加上次加法的位ADDCA,BMOVR4,AJMP$例4.双字节无符号整数快速乘法★C51程序#includereg51.hmain(){unsignedintxdata*p1=0x2000;/*双字节被乘数在2000H单元*/unsignedintxdata*p2=0x2002;/*双字节乘数在2002H单元*/unsignedlongxdata*p3=0x2010;/*4字节乘积放在2010H单元*/*p3=(long)(*p1)*(long)(*p2);}例5.电脑时钟(用定时器产生0.1秒定时中断,对时钟计数器计数并送数码管显示)★C51程序#includereg51.h#includeabsacc.h#defineucharunsignedchar#defineLEDwpXBYTE[0xffdc]#defineLEDwbXBYTE[0xffdd]ucharcodetable[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};ucharhour=1,min=23,sec=45,m=0,n,i;/*给时钟赋初值*/ucharxdata*p;voidDelay(unsignedintvalue)/*延时子程序*/{while(value!=0)value--;}voidTrans(void)/*时间数据转换子程序*/{if(sec==60){min++;sec=0;}if(min==60){hour++;min=0;}if(hour==24){hour=0;}*(p+0)=hour/10;/*时的十分位*/*(p+1)=hour%10;/*时的个位*/*(p+2)=min/10;/*分的十分位*/*(p+3)=min%10;/*分的个位*/*(p+4)=sec/10;/*秒的十分位*/*(p+5)=sec%10;/*秒的个位*/}voidShow(void)/*循环显示子程序*/{for(;;){Trans();LEDwb=n=0x20;for(i=0;i6;i++){LEDwp=table[*(p+i)];LEDwb=n;
本文标题:单片机C51 C语言课件
链接地址:https://www.777doc.com/doc-3974979 .html