讲稿《嵌入式系统应用技术》“二”.ppt
嵌入式系统应用技术,二、51单片机编程语言(C51)赵玉昆,3.3 C51语言,3.3.1 标识符、关键字和运算符3.3.2 数据类型3.3.3 常量及变量3.3.4 C51语言中的特殊数据类型3.3.5 数组和指针3.3.6 程序设计的3种基本结构3.3.7 函数3.3.8 预处理功能3.3.9 C与汇编的混合编程(略)3.3.10 使用C51编译器时的注意事项习题、补充习题,3.3.1 标识符、关键字和运算符,1。标识符2。关键字3。运算符,1。标识符,用于变量名、函数名、数组名、类型名字母、下划线开头,后跟字母、下划线、数字大小写敏感例如:var、VAR,2。关键字,又叫保留字,已由系统占用例如:char、for、if等注释:在C51中,使用“/*/”和“/”进行注释“/*/”中所有字符均为注释,包括回车换行“/*/”不能嵌套“/”到本行结束均为注释例如:var1=a+b;/*这里是注释*/var2=a*b;/这里是注释,3。运算符,(1)算术运算符(2)关系运算符和逻辑运算符(3)操作运算符,(1)算术运算符,+加-减*乘/除%取模(求余)+自加1-自减1,自加(+)、自减(-),先取值,再自加(自减):例如:设x的初值为4y=x+;结果:y=4,x=5y=x-;结果:y=4,x=3先自加(自减),再取值:例如:设x的初值为4y=+x;结果:y=5,x=5y=-x;结果:y=3,x=3注意:+、-只能用于变量,不能用于常量和表达式,(2)关系运算符和逻辑运算符,运算结果是逻辑量(真=非0、假=0)大于=大于等于小于=小于等于=等于!=不等于&与|或!非注意:=是等于运算符,=是赋值操作,(3)操作运算符,位运算符:举例(设x=0 x55,y=0 x37)z=0 x2a,赋值运算符=,是二元运算符,左边是变量(左值),右边是表达式例如:x=y+3;复合赋值运算符:+=、-=、*=、/=、%=、=、,逗号运算符,,作用是将几个表达式串在一起,成为逗号表达式运算顺序是从左到右,最右边表达式的值是逗号表达式的值例如:x=(y=5,z=y+3);结果为y=5,z=8,x=8,条件运算符(?:),代替简单的if-else语句是三元运算符,格式为:表达式1?表达式2:表达式3当表达式1为真,则采用表达式2,否则采用表达式3例如:z=(ab?3:5);/由于ab为假,所以z=5if(ab)z=3;/简单的if语句elsez=5;,强制类型转换符(),格式为:(类型名)(表达式)例如char x;x=7.2/2;/警告,类型不匹配x=(int)(7.2/2);/结果x=3例如(C51中,整型的低地址存放高字节)int x=0 x1234,*p2;char y1,y2,*p1;p1=(char*),Sizeof运算符,计算某数据类型、变量、表达式的字节数例如:int x;y=sizeof(x);/相当于 y=2注意:sizeof不是函数,字节数的计算是在编译时完成。,其他几种运算符,“/p是指针,*p是p指向单元的值。y=10,其他几种运算符,“*”指针运算符。取指针指向单元的值“/a3是数组中第3个单元的值,3.3.2 数据类型,1。基本数据类型2。指针3。特殊数据类型4。结构、联合、枚举和位域5。用typedef定义数据类型,1。基本数据类型,整型有符号char字符型1字节-128+127int整型2字节-32768+32767long长整型4字节-231+231-1无符号unsigned char字符型1字节0255unsigned int整型2字节065535unsigned long长整型4字节0-232-1浮点型float浮点型4字节注意:C51中,整型的低地址存放高字节。(大端模式),2。指针,*指针型13字节指针本身是个变量,存放指向另一个数据的地址。在3.3.5中详细介绍,3。特殊数据类型,8051相关数据类型,在3.3.4中详细介绍bit1位sbit1位sfr1字节sfr162字节,4。结构、联合、枚举和位域,构造类数据类型略。,5。用typedef定义数据类型,给已有数据类型起个新名字格式为:typedef原类型名新类型名例如:typedef unsigned char uchar;/定义uchar为无符号字符型uchar i;/等价于unsigned char i;通常使用以下预定义,使其简洁:typedef unsigned charuchar;typedef unsigned intuint;typedef unsigned longulong;,3.3.3 常量及变量,1。常量2。变量及变量的属性,1。常量,又称标量,其值在运行时不能改变(1)整型常量10,-20,0 x10(2)浮点型常量1.2,2e3(3)字符型常量A,%(4)字符串型常量“Hello”,(1)整型常量,十进制,如345,-23等八进制,以0开头,如034表示十进制的28十六进制,以0 x开头,如0 x12表示十进制的18在数字后面加“L”,构成长整型常量,如2048L等,(2)浮点型常量,小数形式如:0.12、-.3、0.指数形式如:12.3e8、-1.9E-2等,(3)字符型常量,用单引号括起一个字符表示,如:A、$等其值等于该字符的ASCII码不可显示的控制字符,用“”加字符组成转义符表示常用转义符:0空字符(NULL)0 x00r回车0 x0dn换行0 x0a单引号0 x27”双引号0 x22反斜杠0 x5c,(4)字符串型常量,用双号括起一个字符串表示,如:“Hello”,“I am”等字符串中的双引号要用转义符“表示字符串以0结尾字符串保存在字符型数组中例如:char arr4=“ABC”;等价于 char arr4=A,B,C,0;等价于 char arr4=0 x41,0 x42,0 x43,0;,注意:字符常量与字符串常量是不同的。字符常量A,是字符类型,占1字节字符串常量“A”,是字符型数组,占2字节,(4)字符串型常量,辨析:char x,arr=“ABC”;x=A;x=“A”;arr1=x;arr=x;arr=A;arr1=A;arr=ABC;arr=ABC;arr1=ABC;,数组名是指针类型的常量arr,字符串常量是指针类型的常量abc,数组单元是普通变量arr1,没有字符串变量,可保存在字符数组,2。变量及变量的属性,其值在运行时可以改变。必须先定义后使用。变量定义的格式:存储种类 存储器类型 数据类型 变量名例如:static data char x1(1)局部变量和全局变量(2)存储种类(3)存储区域(4)存储器类型(5)存储模式,(1)局部变量和全局变量,局部变量在函数内部定义、只有本函数可以使用。退出函数时释放。全局变量在函数外部定义、各函数都可使用。始终不释放。例如:char quanju;/定义全局变量void func1(void)char jubu;/定义局部变量quanju=34;/使用全局变量jubu=12;/使用局部变量,(1)局部变量和全局变量,局部变量在函数内部定义、只有本函数可以使用。退出函数时释放。例如:void func1(void)char x1=12;/定义局部变量,在进入函数时赋初值x1+;/使用局部变量void func2(void)char x2;/定义局部变量,初值未知x2=x1;/x1不可见,(1)局部变量和全局变量,局部变量在函数内部定义、只有本函数可以使用。退出函数时释放。例如:void main(void)func1();func1();/再次调用,局部变量的初值仍旧未知void func1(void)char x1;/定义局部变量,初值未知x1+;/退出时x1释放,(1)局部变量和全局变量,全局变量在函数外部定义、各函数都可使用。始终不释放。例如:char y1=0 x22;/定义全局变量void main(void)func1();func2();void func1(void)char x1=0 x11;/定义局部变量y1+=x1;/y1可见/退出时y1不释放,(2)存储种类,有4种:auto自动默认(可省略)extern外部在多个源程序时使用static静态退出函数时不释放register寄存器建议编译器使用CPU寄存器,(1)局部变量和全局变量,static修饰局部变量,退出函数时不释放例如:void main(void)func1();func1();/再次调用,局部变量的初值仍旧未知void func1(void)static char x1=3;/定义静态局部变量,在main前时赋初值=3x1+;/退出时x1不释放,(3)存储区域,程序区,内部RAM区,外部RAM区,code程序区,存放代码、常数、表格等,data内部RAM区bdata位寻址区,存放位变量idata内部RAM区,用R0寻址,xdata外部RAM区,用DPTR寻址pdata外部RAM区,用R0寻址,(4)存储器类型,code、data、bdata、idata、xdata、pdata例如:data char var1;/内部RAM区的字符型变量code char text=“ENTER”/程序区的字符型数组xdata unsigned long array100;/外部RAM区的长整型数组idata float x,y,z;/内部RAM区间址访问的浮点变量 pdata int dim;/外部RAM区分页访问的整型变量xdata unsgned char v843;/外部RAM区无符号字符三维数组bdata char flags;/位寻址区的字符变量,可位操作说明:数据类型与存储区修饰符的位置可互换。data char var1;等效与char data var1;,(5)存储模式,用于指定默认的存储器类型存储模式所有变量默认为small小模式datacompact紧凑模式pdatalager大模式xdata注意:通常,small存储模式可以生成最快及最有效的代码。,3.3.4 C51语言中的特殊数据类型,1。位变量2。可位寻址的对象3。特殊功能寄存器4。绝对变量地址,1。位变量,位变量类型可用于声明变量、函数参数、函数返回值。例3.15 位变量使用bit done_flag=0;/位变量bit testfunc(bit flag1,bit flag2)/函数返回为位类型./函数参数为位类型return(0);/返回位类型值位变量存储在内部RAM位寻址区,最多128个。不能将指针指向位变量(位变量不能间接寻址)没有位变量数组,2。可位寻址的对象,是指既可以同时用字节寻址和位寻址访问的对象。存放在内部RAM位寻址区,最多16字节用bdata存储器类型声明bdata char ibase;/可位寻址的字符型变量sbit mb0=ibase0;/ibase的第0位sbit mb7=ibase7;/ibase的第7位ibase=0 x55;/字节操作,mb0=1,mb7=0mb0=0;/位操作,ibase=0 x54注意:bdata只能修饰全局变量,不能用于局部变量。,3。特殊功能寄存器,(1)sfr定义8位SFR例如:sfr P1=0 x90;/P1端口,地址为0 x90(2)sfr16定义16位SFR例如:sfr16 T2=0 xCC;/定时器2,T2L 0 xCC,T2H 0 xCD(3)sbit定义可位寻址单元(包含SFR)的位例如:定义P1.7(位地址为0 x97),可用3种方式sbit P17=P17;/用已定义SFR名第几位sbit P17=0 x907;/用SFR地址第几位sbit P17=0 x97;/用位地址SFR通常在包含文件中预定义,3.3.5 数组和指针,1。数组2。指针,1。数组,数组定义:数据类型 数组名常量1 常量2.常量n数组定义例子char a2;/定义一维字符数组,有2个元素char b4=1,2,3;/定义数组,并赋初值char c=1,2,3;/定义数组,并赋初值,用初值决定尺寸3char d5=“ABC”;/定义数组,指定尺寸,并赋初值char e=“ABC”;/定义数组,并赋初值,用初值决定尺寸4注意:C语言数组下标总是从0开始数组只能在定义时初始化多维数组的第n维变化最快,第1维变化最慢char f23=1,2,3,4,5,6;,2。指针,(1)指针与地址的概念(2)指针变量的引用(3)数组的指针(4)函数的指针,(1)指针与地址的概念,变量经过编译连接后,确定在存储器中的地址。指向某个变量首地址的量称作“指针”。存放指针的变量称为指针变量。指针变量的定义:数据类型*指针变量名data int a,b;/整型变量data char c,d;/字符型变量data int data*e;/指向整型变量的指针data char data*f;/指向字符型变量的指针e=/e指向的单元赋值,e=,*e=0 x1234;,(1)指针与地址的概念,C51有2种类型指针:通用指针,(灵活,效率低,尽量不用)具体指针,(严格,效率高,尽量使用),通用指针,声明时不指定指向的存储器类型。数据类型*变量名占3字节使用时可以指向任何存储区域内的变量。char*s;/指向字符类型的通用指针data char dx;/data区的变量xdata char xx;/xdata区的变量code char cx=9;/code区的常量s=/指针s指向code区,可以,具体指针,声明时指定指向的存储器类型。数据类型 存储器类型*变量名例如:char xdata*b;占1字节(指向idata、data、bdata、pdata),或占2字节(指向xdata、code)。使用时只能指向指定存储区域内的变量。char data*a;/指向data区字符的具体指针char xdata*b;/指向xdata区字符的具体指针data char dx;/data区的变量xdata char xx;/xdata区的变量a=/指向xdata区字符的指针,存放在data中,也可以:char xdata*data b;,(2)指针变量的引用,指针使用时,必须先赋值,再引用。char data*a;/指向data区字符的指针data char b;/data区字符a=/向a赋值非地址量,错误2个与指针相关的运算符“*”:指针运算符,作用是通过指针变量间接访问它所指向的变量。“&”:取地址运算符,作用是取得变量的首地址,即指针。,(3)数组的指针,一个数组包含多个元素。数组元素的地址是连续的。C语言规定,数组名是个指针常量,等于数组首地址数组首地址=数组 0的地址int data*a;/指向data区整型的指针data int b2;/data区整型数组a=b;/指向数组a=/指向b1/由于整型占2字节,实际上指针的值+2,效果一样,a的值=0 x50,a的值=0 x52,(3)数组的指针,辨析:(指针+1)int x2=0 x1234,0 x5678,x1,x2,*px;char y3=0 x23,0 x45,0 x67,0 x89,y1,y2,*py;px=x;py=(char*)x;x1=*(px+1);x2=*(py+1);y1=*(px+1);y2=*(py+1);px=(int*)y;py=y;x1=*(px+1);x2=*(py+1);y1=*(px+1);y2=*(py+1);,/px指向x0/py指向x0的高位/x1=0 x5678:x1/x2=0 x0034:x0的低位,自动转换/y1=0 x78:x1的低位,自动转换/y2=0 x34:x0的低位/px指向y0,包含y1/py指向y0/x1=0 x6789:y2、y3/x2=0 x0045:y1,自动转换/y1=0 x89:y2、y3,自动转换去低位/y2=0 x45:y1,(4)函数的指针,C语言规定,函数名是个指针,等于函数的入口地址指向函数指针变量的定义函数返回类型(*指针变量名)(函数参数列表)例如:int add(int a,int b);/声明函数addint x;int(*pfun)(int a,int b);/定义函数指针pfun=add;/pfun指向add函数x=(*pfun)(3,4);/即x=add(3,4);,此括号表示是指针变量,必须,此括号表示指向函数,必须,3.3.6 程序设计的3种基本结构,1。语句2。顺序结构3。选择结构4。循环结构,1。语句,以分号为结束标志(1)常用控制语句:if.else.、for()、while()、do.while()、continue、break、switch.case、goto、return。(2)空语句:只有一个分号,不做任何操作。(3)表达式语句:表达式加上分号,结果丢弃。(4)复合语句:多个语句用 括起来,语法上等于一个语句。(5)注释语句:/*/括起来、或/之后的内容为注释语句。增加程序的可读性和维护性。,2。顺序结构,最简单、基本的结构例如:data int a,b;void main(void)char c;a=0 x11;b=0 x22;c=a+b*0 x33;.,3。选择结构,即分支结构。根据条件,执行某个分支。C语言有if语句和switch语句构成选择结构。(1)if语句(2)switch语句,(1)if语句,有3种基本格式:格式1例:if(ab)c=0 x11;格式2例:if(ab)c=0 x11;elsed=0 x22;格式3例:if(a60)c=0;bjg+;elseif(a70)c=1;elseif(a80)c=2;elseif(a90)c=3;elsec=4;you+;,(2)switch语句,switch例:switch(a)case 0:c=0 x11;break;case 3:c=0 x22;case 8:c=0 x33;break;default:c=0 xff;break;注意:case仅相当于一个标号。break相当于一个goto语句,跳出switch语句。没有break将继续执行下一语句。,必须为整形、字符型量,这里没有break当a=3时,将执行c=0 x22;c=0 x33;再跳出switch,4。循环结构,C语言可用for、while、do.while语句构成循环结构。(1)for循环(2)while循环(3)do.while循环(4)goto语句(5)break语句(6)continue语句,(1)for循环,一般格式:for(表达式1;表达式2;表达式3)循环体语句求解表达式1(循环初值)。求解表达式2,若为真,则执行循环体;否则结束循环(终点控制)。求解表达式3(每轮循环后处理)。例如:for(i=0;i10;i+)szi+;count+=10;注意:若第一次求解表达式2就为假,则循环体一次都不执行。如果循环体是多个语句,要用括起来,使其语法上为一个语句。,(2)while循环,一般格式:while(表达式)循环体语句求解表达式,若为真,则执行循环体;否则结束循环。例如:i=0;while(i10)szi+;i+;/会使循环结束注意:在循环体内要有使循环结束的语句,否则是个死循环。若第一次求解表达式就为假,则循环体一次都不执行。如果循环体是多个语句,要用括起来,使其语法上为一个语句。,这里没有分号,(3)d0.while循环,一般格式:do 循环体语句while(表达式);执行循环体。求解表达式,若其值为真,则执行循环体;否则结束循环。例如:i=0;doszi+;i+;/会使循环结束while(i10);注意:在循环体内要有使循环结束的语句,否则是个死循环。循环体至少执行一次。如果循环体是多个语句,要用括起来,使其语法上为一个语句。,这里有个分号,(4)goto语句,一般格式:goto 语句标号;例如:.goto label1;.label1:.注意:滥用goto语句是C语言的大忌。,(5)break语句,break语句用在循环中,可以立即退出循环。例如:for(i=0;i100;i+).;if(abc=1)break;/当abc=1时,立即结束循环.;说明:break语句可用for、while、do.while循环中,也可用于switch语句中。在嵌套结构中,break只能退出当前层。,(6)continue语句,continue语句只能用在循环中,可以结束本轮循环,开始下一轮循环。例如:for(i=0;i100;i+).;if(abc=1)countinue;/当abc=1时,开始下一轮循环.;/这些语句被跳过,3.3.7 函数,C程序由一个主函数main()和若干个其他函数组成。单片机运行时,经过系统初始化后,进入main(),C51的main()不会退出。1。函数的基本格式2。内部函数和外部函数(略)3。可重入函数(略)4。规定函数使用的寄存器组(略)5。中断函数,1。函数的基本格式,(1)函数定义(2)函数返回值(3)形式参数和实际参数(4)调用函数的方式,(1)函数定义,一般格式:返回类型 函数名(形式参数列表)局部变量声明语句(有返回值的要有return语句)例如:int func1(char a,int b)char c;c=(int)a*100+b;return c;int func2(void)/没有参数,用void明确指出.,(2)函数返回值,返回值是通过return语句返回的。返回值的类型要和函数定义的类型一致。没有返回值,应该用void定义函数,用不带返回值的return语句,或不用return语句。例如:void func2(int*a)/没有返回值,用void定义(*a)+;return;/也可无return语句,(3)形式参数和实际参数,函数应该先声明(或定义)后使用。例如:char func3(char d);/func3的声明,比定义多个分号int func1(char a,int b)/func1先定义.void func2(char c).x=func1(3,4);/func1已经定义过,可以使用y=func3(5);/func3已经声明过,可以使用char func3(char d)/func3后定义.,形式参数,实际参数,(3)形式参数和实际参数,形式参数相当于函数的局部变量。基本类型的参数为传值调用。指针类型的参数为传址调用。例如:void func1(char a)/a是传值,传入的是实参的值a+;/仅修改形参a的值void func2(char data*b)/b是传址,传入的是实参的地址(*b)+;/将修改实参的值char func3(char c)char x,y;func1(x);/将x的值传给a,调用函数后,x的值不变func2(/将y的地址传给b,调用函数后,y的值改变,(3)形式参数和实际参数,数组元素作为参数是传值调用。数组名作为参数是传址调用。例如:void func1(char a)/a是传值a+;/仅修改形参a的值void func2(char data*b)/b是传址,传入的是实参的地址(*b)+;/将修改实参的值char func3(char c)char x3;func1(x0);/将x0的值传给a,调用函数后,x0的值不变func2(x);/将x的地址传给b,调用函数后,x0的值改变,(4)调用函数的方式,函数应该先声明(或定义)后使用。函数作为语句func1(char a);/完成函数定义的操作,不使用返回值函数作为表达式y=x+func1(char a);/使用函数返回值参与运算函数作为参数func1(func2();/使用函数返回值作为参数函数递归调用(高级运用)func1(void).func1();/函数内部调用自身,递归,5。中断函数,定义格式为:void 中断函数名(void)interrupt nn=031,表示中断号n=0,入口地址=0 x0003,即INT0中断n=1,入口地址=0 x000B,即T0中断.中断函数由系统自动调用,用户不能在程序中显式调用。中断函数入口参数和返回值都必须是void。中断函数名并不重要。编译处理会生成必要的现场保护、恢复。例如:void T0_int(void)interrupt 1/定时器T0中断服务程序.,3.3.8 预处理功能,预处理在编译前处理,C语句在编译中处理。预处理命令以#号开头,不加分号,行尾结束1。简单宏定义和带参数的宏定义2。包含文件3。条件编译命令,1。简单宏定义和带参数的宏定义,(1)简单宏定义#define uchar unsigned char/用uchar代替unsigned char#define buflen 100/用buflen代替100(2)带参数的宏定义#define ADD1(x,y)(x+y)/定义ADD1宏v=ADD1(3,4);/使用ADD1宏,等效于v=(3+4);,这里不能有空格。不能写成#define ADD(x,y)(x+y),1。简单宏定义和带参数的宏定义(续1),注意:宏和函数不同#define ADD1(x,y)(x+y)/定义ADD1宏char ADD(char x,char y)/定义函数return(x+y);void main(void)char v;v=ADD1(3,4);/使用ADD1宏,结果v=7;v=ADD2(3,4);/使用ADD2函数,结果v=7;宏在编译前完成替换。运行速度更快。函数在运行中完成运算。调试时可以跟踪,更方便。,编译时实际语句是:v=7;,2。包含文件,在当前文件中插入其他文件例如:#include/在此处插入reg51.h文件。文件在包含目录中#include“reg51.h”/在此处插入reg51.h文件。文件在当前目录中,3。条件编译命令,对源程序代码有选择地编译例如:#define VER0/定义VER#if(VER=1)/如果VER=1b=3;/编译此语句,否则目标代码中不出现此语句。#endif与if语句不同char VER=0;/定义VERif(VER=1)/如果VER=1b=3;/执行此语句,目标代码中有此语句。,3.3.9 C与汇编的混合编程,略,3.3.10 使用C51编译器时的注意事项,(1)使用短变量,能用char就不用int。(2)避免使用浮点运算。用整型代替浮点。(3)逻辑运算能用bit就不用char。(4)用常量宏定义代替数字常量。(5)多用局部变量,少用全局变量。(6)尽量使用内部RAM。(7)使用具体指针。(8)尽量使用small存储模式。(9)变量取名有意义,见名知意。(10)有清晰详尽的注释。(11)合理使用缩进格式,体现层次结构。优美的行文风格。,书中习题 1(123页),1。片外RAM从1000H10FFH有一数据块,编写程序将其传送到片外RAM的2500H单元开始的区域中。char xdata*rp,xdata*wp;/指向xdata中字符型的指针int i;rp=(char xdata*)0 x0000;/读指针,指向源wp=(char xdata*)0 x2500;/写指针,指向目标for(i=0;i0 x100;i+)*wp=*rp;rp+;wp+;说明:C语言中通常不建议绝对地址访问。此为借用汇编语言习题。,附加习题 1b,1b。在片外RAM中有一字符数组buf1,长度为100字节,编写程序将其内容传送到片外RAM的另一数组buf2。char xdata buf1100,xdata buf2100;/xdata中的字符型数组char i;for(i=0;i100;i+)buf2i=buf1i;,书中习题 2,2。将无符号整型变量i求补码后送回原处。unsigned int i;if(i0)i=-i;/求补码,书中习题 3,3。编写函数,将十六进制数0F转换为ASCII码。/*-十六进制数0F转换为ASCII码的函数-*/uchar hextoasc(uchar h)uchar asc;if(h10)asc=h+0;elseasc=h-10+A;return asc;/*-函数调用例-*/x=hextoasc(0 x05);/结果x=5x=hextoasc(0 x0a);/结果x=A,书中习题 4,1,x04。编写函数,计算y=0,x=0-1,x0)y=1;else if(x=0)y=0;elsey=-1;return y;,书中习题 5,5。x=05,根据x的值,分别执行fun0、func1.func5。switch(x)case 0:func0();break;case 1:func1();break;case 2:func2();break;case 3:func3();break;case 4:func4();break;case 5:func5();break;,使用函数指针数组:void(*fp5)()=func0,func1,func2,func3,func4,func5;/定义函数指针数组/并赋初值。(*fpx)();/根据x的值,调用相应函数,书中习题 6,6。根据x中的8位二进制,用ASCII码填充到buf数组。例如:x=01010011B,buf=0,1,0,1,0,0,1,1uchar i,x,buf8;x=0 x53;/送个试验的值for(i=0;i8;i+)if(x/左移1位,书中习题 7,7。将x中的十六进制数0F转换为7段码送P1口。uchar code tab_7dm16=/*7段码表*/0 x3F,0 x06,0 x5B,0 x4F,0 x66,0 x6D,0 x7D,0 x07,/*0,1,2,3,4,5,6,7*/0 x7F,0 x6F,0 x77,0 x7C,0 x39,0 x5E,0 x79,0 x71/*8,9,A,B,C,D,E,F*/;P1=tab_7dmx;,书中习题 8,8。有一个5行*8列的二维数组,将第i行、第j列元素送y。uchar sz58;y=szij;,书中习题 9,9。实现图示功能。P1.1P2.2IE0IE1P1.3b25b26#include/在reg51.h中有P13、IE0等定义bit b25,b26;P13=(P22|E0),1,1,&,1,&,A,B,C,A,B,C,书中习题 10,10。有2个不同大小的数组buf1、buf2,首单元是数组长度。编程找出数组中最大值,相乘后送y。uchar getmax(uchar data*p)/找到最大值的函数uchar i,max=0;for(i=1;imax)max=pi;return max;void main(void)uchar buf1=4,1,200,2,4;/试验数据uchar buf2=5,1,3,7,4,100;uint x1,x2,y;x1=getmax(buf1);/调用找最大值的函数x2=getmax(buf2);/调用找最大值的函数y=x1*x2;,书中习题 11,11。编写多字节相加函数。入口:p1、p2指向加数低位,n为字节数;出口:p1指向和。void mb_add(uchar data*p1,uchar data*p2,uchar n)/多字节相加的函数uchar i,c=0;uint s;/c是进位,s是字节和for(i=0;i0 xff?1:0);/得到进位p1i=(uchar)s;/保存字节和void main(void)uchar buf1=0 x11,0 x22,0 xaa,0 x44;/试验数据uchar buf2=0 x55,0 x66,0 xbb,0 x88;mb_add(buf1,buf2,sizeof(buf1);/调用多字节相加的函数,补充习题,1、将xdata区20个字节单元的无符号数按从小到大的顺序排序。2、编制一个字符串转数字的函数。入口:指向10进制数字字符串的指针。返回:对应10进制数字字符串的整型数。例如:3600-3600(0 x0e10)。3、编制一个数字转10进制字符串的函数。入口:1、待转换的整型数,2、保存结果的字符串的指针。返回:无。例如:3600-3600。4、编制一个在字符串中寻找指定字符的函数,入口:1、字符串,2、字符。返回:字符在字符串中的位置,0表示未找到。例如:字符串=ABCDEFG,字符=C,返回3。,大纲,3.3 C51语言3.3.1 标识符、关键字和运算符1。标识符2。关键字3。运算符(1)算术运算符(2)关系运算符和逻辑运算符(3)操作运算符3.3.2 数据类型1。基本数据类型2。指针3。特殊数据类型4。结构、联合、枚举和位域5。用typedef定义数据类型3.3.3 常量及变量1。常量2。变量及变量的属性3.3.4 C51语言中的特殊数据类型1。位变量2。可位寻址的对象3。特殊功能寄存器4。绝对变量地址3.3.5 数组和指针1。数组2。指针(1)指针与地址的概念(2)指针变量的引用(3)数组的指针(4)函数的指针3.3.6 程序设计的3种基本结构1。语句2。顺序结构3。寻则结构4。循环结构3.3.7 函数1。函数的基本格式2。内部函数和外部函数3。可重入函数4。规定函数使用的寄存器组5。中断函数3.3.8 预处理功能1。简单宏定义和带参数的宏定义2。包含文件3。条件编译命令3.3.9 C与汇编的混合编程3.3.10 使用C51编译器时的注意事项,