1、第第4章章80C51的汇编与的汇编与C语言程序设语言程序设计计2023-1-252v 单片机应用系统由硬件系统和应用程序构成单片机应用系统由硬件系统和应用程序构成v 汇编语言汇编语言v 高级语言高级语言v 应用程序设计方法应用程序设计方法 汇编语言,生成的目标程序占内存空间少、运行速度快,具有效率高、实时性强。汇编语言,生成的目标程序占内存空间少、运行速度快,具有效率高、实时性强。高级语言,对系统的功能描述与实现简单,程序阅读、修改和移植方便,适合于编写复杂的程高级语言,对系统的功能描述与实现简单,程序阅读、修改和移植方便,适合于编写复杂的程序。如序。如C51C51 4.1 单片机汇编及单片机
2、汇编及C语言概述语言概述 2023-1-253汇编语言的语句格式汇编语言的语句格式v非数字字符开头,后跟字母、数字、非数字字符开头,后跟字母、数字、“-”、“?”等等v不能用已定义的保留字(指令助记符、伪指令等)不能用已定义的保留字(指令助记符、伪指令等)v后跟英文冒号后跟英文冒号“:”KeilKeil的汇编器的汇编器A51A51可以识别的语句形式为:可以识别的语句形式为:v 标号(即符号地址)标号(即符号地址)标号:指令助记符指令助记符 操作数1,操作数2,操作数3,;注释v 指令助记符指令助记符是指令功能的英文缩写。是指令功能的英文缩写。4.1 单片机汇编语言概述单片机汇编语言概述 80C
3、5180C51的汇编语言程序设计的汇编语言程序设计-自学自学2023-1-2544.1 单片机单片机C语言概述语言概述 4.1.1 C514.1.1 C51程序开发过程程序开发过程 v 编译器能自动完成变量的存储单元的分配编译器能自动完成变量的存储单元的分配v 对常用功能模块和算法编制相应的函数,方便移植对常用功能模块和算法编制相应的函数,方便移植v 采用采用C51C51的优点的优点 C C语言具有良好的可读性、可移植性和基本的硬件操作能力语言具有良好的可读性、可移植性和基本的硬件操作能力 。v C51C51程序开发过程程序开发过程 v 编写源程序编写源程序v 建立工程,加入源程序建立工程,加
4、入源程序v 编译生产目标程序编译生产目标程序v 仿真调试、写存储器仿真调试、写存储器2023-1-2552023-1-2564.1.2 C514.1.2 C51程序结构程序结构#include#include#include#include void delayms(unsigned)void delayms(unsigned);void main(void)void main(void)unsigned char i unsigned char i;P1=0 x01P1=0 x01;dodo for(i=0for(i=0;i=7i=7;i+)i+)delayms(5000)delayms(5
5、000);P1=P11P1=P11;if(P1=0 x0)P1=0 x01if(P1=0 x0)P1=0 x01;while(1)while(1);void delayms(unsigned x)void delayms(unsigned x)unsigned char j unsigned char j;while(x-)while(x-)for(j=0 for(j=0;j123j123;j+)j+);2023-1-2574.2.1 C514.2.1 C51的数据类型的数据类型4.2 C51的数据类型与运算的数据类型与运算 数据类型决定其取值范围、占用存储器的大小及可参与哪种运算。数据类型决
6、定其取值范围、占用存储器的大小及可参与哪种运算。数据类型数据类型长度长度(位位)取值范围取值范围字符型字符型signed char8-128127unsigned char80255整整 型型signed int16-3276832767unsigned int16065535长整型长整型signed long32-2147488364821474883647unsigned long3204294967295浮点型浮点型float321.75494E-383.402823E+38位位 型型bit10,1sbit10,1访问访问SFRsfr80255sfr16160655352023-1-25
7、8v尽可能采用无符号格式尽可能采用无符号格式vbitbit用于定义位变量的名字,编译器会对其分配地址(用于定义位变量的名字,编译器会对其分配地址(RAMRAM的的20H20H2FH 2FH 区域)区域)vsbitsbit用于定义位变量的名字和地址,地址是确定的且不用编译器分配(用于定义位变量的名字和地址,地址是确定的且不用编译器分配(SFRSFR及及RAMRAM的的20H20H2FH 2FH 区域)区域)vC51C51编译器在编译时会自动进行类型转换编译器在编译时会自动进行类型转换 几点说明:几点说明:2023-1-2594.2.2 C514.2.2 C51数据的存储类型数据的存储类型vC51
8、C51的存储器类型的存储器类型存储器类型存储器类型长度(位)长度(位)对应单片机存储器对应单片机存储器bdata1片内片内RAM位寻址区,共位寻址区,共128位。(亦能字节访问)位。(亦能字节访问)data8直接寻址,共直接寻址,共128字节。字节。idata8间接寻址,共间接寻址,共256字节。字节。pdata8片外片外 RAM分页间址,共分页间址,共256字节。(字节。(MOVX Ri)xdata16间接寻址,共间接寻址,共64k字节。(字节。(MOVX DPTR)code16ROM间接寻址,共间接寻址,共64k字节。(字节。(MOVC A,A+DPTR)2023-1-2510v经常使用的
9、变量应该置于片内经常使用的变量应该置于片内RAMRAM中,要用中,要用bdatabdata、datadata、idataidata来定义来定义v不经常使用的变量或规模较大的变量应该置于片外不经常使用的变量或规模较大的变量应该置于片外RAMRAM中,要用中,要用pdatapdata、xdataxdata来定义来定义v默认存储器类型由编译控制命令的存储模式指令限制默认存储器类型由编译控制命令的存储模式指令限制 存储模式存储模式默认默认存储类型存储类型特特 点点SMALL data小模式。小模式。变量默认在片内变量默认在片内RAM。空间小,速度块。空间小,速度块。COMPACTpdata紧凑模式。变
10、量默认在片外紧凑模式。变量默认在片外RAM的页(的页(256字节,页号由字节,页号由P2口决定)。口决定)。LARGExdata大模式。大模式。变量默认在片外变量默认在片外RAM的的64KB范围。空间大,速度慢。范围。空间大,速度慢。2023-1-25114.2.3 80C514.2.3 80C51硬件结构的硬件结构的C51C51定义定义v特殊功能寄存器的声明特殊功能寄存器的声明 sfr sfr 特殊功能寄存器名特殊功能寄存器名 =地址常数;地址常数;格式:格式:例如:例如:sfr SCON=0 x90sfr SCON=0 x90;sfr P0=0 x80sfr P0=0 x80;2023-1
11、-2512v特殊功能寄存器中特定位的声明特殊功能寄存器中特定位的声明 vsbit sbit 位变量名位变量名=特殊功能寄存器名特殊功能寄存器名 位的位置(位的位置(0 07 7)例如:例如:sfr PSW=0 xD0sfr PSW=0 xD0;sbit OV=PSW2 sbit OV=PSW2;vsbit sbit 位变量名位变量名 =字节地址字节地址 位的位置(位的位置(0 07 7)例如:例如:sbit OV=0 xD02sbit OV=0 xD02;sbit CY=0 xD07 sbit CY=0 xD07;vsbit sbit 位变量名位变量名 =位地址位地址 例如:例如:sbit O
12、V=0 xD2sbit OV=0 xD2;sbit CY=0 xD7 sbit CY=0 xD7;2023-1-2513v内部内部RAMRAM中可位寻址对象的定义中可位寻址对象的定义 v先定义变量的数据类型和存储类型先定义变量的数据类型和存储类型 例如:例如:int bdata ibaseint bdata ibase;char bdata array4 char bdata array4;v再利用再利用sbitsbit进行声明进行声明 例如:例如:sbit mybit0=ibase0sbit mybit0=ibase0;sbit mybit15=ibase15 sbit mybit15=ib
13、ase15;sbit ary07=array07sbit ary07=array07;访问示例:访问示例:ibase=-1ibase=-1;array2=array2=a a;2023-1-2514v算术运算符和算术表达式算术运算符和算术表达式 4.2.4 C514.2.4 C51的运算符和表达式的运算符和表达式 v基本算术运算符基本算术运算符 例如:例如:+加法运算符;加法运算符;-减法(取负)运算符;减法(取负)运算符;*乘法运算符;乘法运算符;/除法运算符;除法运算符;%取余数运算符取余数运算符。示例:示例:25.0/20.0=1.25 25.0/20.0=1.25 25/20=125/
14、20=125%20=5 25%20=5 取负运算优先级最高。取负运算优先级最高。2023-1-2515v自增、自减运算符(仅能用于变量)自增、自减运算符(仅能用于变量)例如:例如:+自增运算符;自增运算符;-自减运算符;自减运算符;v类型转换运算符类型转换运算符 自动转换,顺序:自动转换,顺序:bitcharintlongfloatbitcharintlongfloat 强制类型转换,如:(强制类型转换,如:(doubledouble)a a 2023-1-2516v关系运算符和关系表达式关系运算符和关系表达式 v关系运算符关系运算符 小于;小于;=大于;大于;=大于等于;大于等于;=等于;等
15、于;!=不等于。不等于。v关系表达式关系表达式关系表达式的值为逻辑值:真(关系表达式的值为逻辑值:真(1 1)和假()和假(0 0)2023-1-2517v逻辑运算符和逻辑表达式逻辑运算符和逻辑表达式 v逻辑运算符逻辑运算符&逻辑与;逻辑与;|逻辑或;逻辑或;!逻辑非。逻辑非。v逻辑表达式逻辑表达式逻辑表达式的值为逻辑值:真(逻辑表达式的值为逻辑值:真(1 1)和假()和假(0 0)例:例:5|05|0结果为结果为1 1,2&02&0结果为结果为0 0 2023-1-2518v位运算符位运算符&按位与;按位与;|按位或;按位或;按位异或;按位异或;按位取反;按位取反;右移。右移。例:例:P1=
16、P11P1=P11表示对表示对P1P1口的所有位左移口的所有位左移1 1位位 2023-1-2519v赋值和复合赋值运算符赋值和复合赋值运算符 v复合赋值运算符复合赋值运算符 +=+=加法赋值;加法赋值;-=-=减法赋值;减法赋值;*=乘法赋值;乘法赋值;/=/=除法赋值;除法赋值;%=%=取模赋值;取模赋值;v符号符号“=”称为赋值运算符称为赋值运算符 =右移位赋值;右移位赋值;&=&=逻辑与赋值;逻辑与赋值;|=|=逻辑或赋值;逻辑或赋值;=逻辑异或赋值;逻辑异或赋值;=逻辑非赋值逻辑非赋值 例:例:a a*=5=5相当于相当于a=aa=a*5 5;b&=0 x80b&=0 x80相当于相
17、当于b=b&0 x80b=b&0 x80。2023-1-25204.3 C51流程控制语句流程控制语句 4.3.1 C514.3.1 C51选择语句选择语句 v条件语句条件语句vifif(条件表达式)语句(条件表达式)语句 例如:例如:if if(p1p1!=0=0)c=20 c=20;vifif(条件表达式)语句(条件表达式)语句1 1 else else 语句语句2 2 例如:例如:if if(p1p1!=0=0)c=20 c=20;else c=0 else c=0;2023-1-2521vifif(条件表达式(条件表达式1 1)语句)语句1 1 else if else if(条件表达
18、式(条件表达式2 2)语句)语句2 2 else if else if(条件表达式(条件表达式3 3)语句)语句3 3 else if else if(条件表达式(条件表达式n n)语句)语句n n else else 语句语句n+1 n+1 2023-1-2522v开关语句开关语句switch switch(表达式)(表达式)case case 常量表达式常量表达式1 1:语句:语句1 1;breakbreak;case case 常量表达式常量表达式2 2:语句:语句2 2;breakbreak;case case 常量表达式常量表达式n n:语句:语句n n;breakbreak;def
19、ault default:语句:语句n+1n+1;2023-1-25234.3.2 C514.3.2 C51循环语句循环语句 vwhilewhile语句语句 v 一般形式为:一般形式为:while while(条件表达式)语句;(条件表达式)语句;如果条件表达式的结果一开始就为假,则后面的语句一次也不能执行。如果条件表达式的结果一开始就为假,则后面的语句一次也不能执行。vdo-whiledo-while语句语句 v 一般形式为:一般形式为:do do语句语句 whilewhile(条件表达式);(条件表达式);任何条件下,循环体语句至少会被执行一次。任何条件下,循环体语句至少会被执行一次。20
20、23-1-2524vforfor语句语句v 一般形式为:一般形式为:for for(初值表达式初值表达式;条件表达式条件表达式;更新表达式更新表达式)语句)语句vifif语句与语句与gotogoto语句结合语句结合 v 当型循环当型循环 形式为:形式为:loop loop:ifif(表达式)(表达式)语句语句 goto loopgoto loop;2023-1-2525v 直到型循环直到型循环 形式为:形式为:loop loop:语句语句 ifif(表达式)(表达式)goto loopgoto loop;vcontinuecontinue是一种循环中断语句,它并不跳出循环体;是一种循环中断语句
21、,它并不跳出循环体;vbreakbreak语句只能跳出它所处的那一层循环;语句只能跳出它所处的那一层循环;vgotogoto语句可以用于跳出多重循环(从内层到外层)。语句可以用于跳出多重循环(从内层到外层)。注意:注意:2023-1-25264.4 C51的指针类型的指针类型 v有一个变量有一个变量a a,利用,利用&a&a表示变量表示变量a a的地址的地址 。则语句。则语句 p=&a p=&a;把把a a的地址赋给了指针变量的地址赋给了指针变量p p,则,则“p p指向了变量指向了变量a a”。v*P P表示变量表示变量a a的内容的内容指针变量的定义指针变量的定义 char data ch
22、ar data*p/p/*定义指针变量定义指针变量 */p=30H /p=30H /*为指针变量赋值,为指针变量赋值,30H30H为片内为片内RAMRAM地址地址 */x=x=*p /p /*30H 30H单元的内容送给变量单元的内容送给变量x x*/2023-1-2527v定义时未指定它所指向的对象的存储器类型定义时未指定它所指向的对象的存储器类型 4.4.1 4.4.1 一般指针一般指针 v一般指针占一般指针占3 3个字节个字节第一字节存放该指针的默认存储器类型编码(见表)第一字节存放该指针的默认存储器类型编码(见表)第二字节存放该指针的高位地址偏移量第二字节存放该指针的高位地址偏移量第三
23、字节存放该指针的低位地址偏移量第三字节存放该指针的低位地址偏移量 v存储器类型编码存储器类型编码 存储器类型存储器类型bdata/data/idataxdatapdatacode编码编码0 x000 x010 xfe0 xff2023-1-2528一般指针定义示例:一般指针定义示例:char char*xdata strptrxdata strptr;/*指针本身存于指针本身存于xdata xdata 空间,它指向空间,它指向charchar型数据型数据 */int int *data numberdata number;/*指针本身存于指针本身存于data data 空间,它指向空间,它指向
24、intint型数据型数据 */由于指向对象的存储空间在编译时无法确定(运行时确定),因此必须生成一般代码以保证对任意空间由于指向对象的存储空间在编译时无法确定(运行时确定),因此必须生成一般代码以保证对任意空间的对象进行存取。所以一般指针所产生的代码速度较慢。的对象进行存取。所以一般指针所产生的代码速度较慢。2023-1-25294.4.2 4.4.2 基于存储器的指针基于存储器的指针v定义时就指定它所指向的对象的存储器类型定义时就指定它所指向的对象的存储器类型 v指针占指针占1 1个字节(个字节(idata idata*,data data*,pdata pdata*)或)或2 2个字节(个
25、字节(code code*,xdata xdata*)基于存储器指针定义示例:基于存储器指针定义示例:char data char data *strstr;/*指针指向的指针指向的charchar型数据存于型数据存于data data 空间空间 */int xdata int xdata*numnum;/*指针指向的指针指向的intint型数据存于型数据存于xdata xdata 空间空间 */基于存储器的指针长度比一般指针短,可以节省存储器空间,运行速度快,但它所指对象具有确定基于存储器的指针长度比一般指针短,可以节省存储器空间,运行速度快,但它所指对象具有确定的存储器空间,兼容性不好。的
26、存储器空间,兼容性不好。2023-1-25304.5 C51的函数的函数 4.5.1 C514.5.1 C51函数的定义函数的定义一般形式一般形式:返回值类型返回值类型 函数名(形式参数列表)函数名(形式参数列表)编译模式编译模式reentrantinterrupt nusing nreentrantinterrupt nusing n 函数体函数体 v编译模式为编译模式为SMALLSMALL、COPACTCOPACT或或LARGELARGEvreentrantreentrant用于定义可重入函数用于定义可重入函数vinterrupt n interrupt n 用于定义中断函数用于定义中断函
27、数,n,n为中断号为中断号,可以为可以为0 03131vusing n using n 确定工作寄存器组,取值为确定工作寄存器组,取值为0 03 3 2023-1-25314.5.2 C514.5.2 C51函数的调用与参数传递函数的调用与参数传递 v主调函数要向被调函数传递所需的参数主调函数要向被调函数传递所需的参数v传递给被调函数的数据称为实际参数,即实参传递给被调函数的数据称为实际参数,即实参v实参向形参的传递是单向的实参向形参的传递是单向的v参数传递可以采用寄存器、固定存储器位置方式参数传递可以采用寄存器、固定存储器位置方式 v参数传递参数传递v寄存器参数传递寄存器参数传递传递的参数传
28、递的参数char、1字节指针字节指针int、2字节指针字节指针long、float一般指针一般指针参数参数1R7R6、R7R4R7R1、R2、R3参数参数2R5R4、R5R4R7R1、R2、R3参数参数3R3R2、R3R1、R2、R32023-1-2532vSMALLSMALL模式下,在内部模式下,在内部RAMRAM中完成中完成 vCOMPACTCOMPACT模式下,在外部模式下,在外部RAMRAM中完成中完成vLARGERLARGER模式下,在外部模式下,在外部RAMRAM中完成中完成v固定存储器位置参数传递固定存储器位置参数传递 80C51单片机不采用堆栈传递参数。但C51提供一种模拟堆栈
29、,从而支持可重入函数的递归调用。4.5.3 C514.5.3 C51的库函数的库函数常用的C51库函数参见附录B.2 2023-1-25334.6 C51编程实例编程实例 4.6.1 80C514.6.1 80C51内部资源的编程内部资源的编程 v中断服务函数示例中断服务函数示例中断函数的定义形式中断函数的定义形式void void 函数名(函数名(voidvoid)interrupt n using minterrupt n using m 函数体函数体 中断源中断源外中断外中断0定时器定时器0外中断外中断1定时器定时器1串行口串行口中断号中断号012342023-1-2534【例例10-1
30、10-1】单片机应用系统中,外中断单片机应用系统中,外中断0 0引脚接一个开关,并行口线引脚接一个开关,并行口线P1.0P1.0接一个发光二级管。要求:开关闭合一次,接一个发光二级管。要求:开关闭合一次,发光二极管的状态改变一次。试编写程序发光二极管的状态改变一次。试编写程序#include“reg51.h”#include“intrins.h”sbit P10=P10;void delay(void)int a=5000;while(a-)_nop_();void int_srv(void)interrupt 0 delay();if(INT0=0)P10=!P10;while(INT0=0
31、);void mainvoid main()()P10=0 P10=0;EA=1EA=1;EX0=1EX0=1;whilewhile(1 1););2023-1-2535v定时计数器编程示例定时计数器编程示例【例例10-210-2】利用定时利用定时/计数器计数器T0T0的方式的方式1 1,产生,产生10ms10ms的定时,并使的定时,并使P1.0P1.0引脚上输出周期为引脚上输出周期为20ms20ms的方波,采用中断方的方波,采用中断方式,设系统时钟频率为式,设系统时钟频率为12 MHz12 MHz。1 1、计算计数初值、计算计数初值X X:N Nt/Tcy t/Tcy 101010-3/11
32、0-3/110-610-61000010000计数器初值应为计数器初值应为-10000-10000。即应将。即应将 -(10000/25610000/256)送入)送入TH0TH0中,中,-(10000%25610000%256)送入)送入TL0TL0中。中。2 2、求、求T0T0的方式控制字的方式控制字TMODTMOD:M1M0=01M1M0=01,GATE=0GATE=0,C/T=0C/T=0,可取方式控制字为,可取方式控制字为01H 01H 3 3、程序清单(见下页)、程序清单(见下页)2023-1-2536#include#include“reg51.hreg51.h”sbit P10
33、=P10sbit P10=P10;void timer0(void)interrupt 1void timer0(void)interrupt 1 P10=!P10 P10=!P10;TH0=-TH0=-(10000/25610000/256););TL0=-TL0=-(10000%25610000%256););void mainvoid main(voidvoid)TMOD=0 x01TMOD=0 x01;P10=0P10=0;TH0=-TH0=-(10000/25610000/256););TL0=-TL0=-(10000%25610000%256););EA=1EA=1;ET0=1ET
34、0=1;TR0=1TR0=1;whilewhile(1 1););2023-1-25374.6.2 80C514.6.2 80C51扩展资源的编程扩展资源的编程 v通用并行口编程示例通用并行口编程示例【例例10-310-3】用用81C5581C55作为微型打印机与单片机间的接口电路。作为微型打印机与单片机间的接口电路。2023-1-2538#include#include“reg51.hreg51.h”#include#include“absacc.habsacc.h”/*含有对含有对XBYTEXBYTE等绝对地址访问宏的定义等绝对地址访问宏的定义*/#define uchar unsigne
35、d char#define uchar unsigned char#define COMD8155 XBYTE0 x7f00#define COMD8155 XBYTE0 x7f00#define PA8155 XBYTE0 x7f01#define PA8155 XBYTE0 x7f01#define PB8155 XBYTE0 x7f02#define PB8155 XBYTE0 x7f02#define PC8155 XBYTE0 x7f03#define PC8155 XBYTE0 x7f03sbit BUSY=P33sbit BUSY=P33;2023-1-2539uchar cod
36、e tab17=0 xb80 xb8,0 xdf0 xdf,0 xbd0 xbd,0 xcc0 xcc,0 x200 x20,0 xb30 xb3,0 xf60 xf6,0 xb00 xb0,0 xe60 xe6,0 xc90 xc9,0 xe70 xe7,0 x200 x20,0 x320 x32,0 x300 x30,0 x300 x30,0 x380 x38,0 x0a0 x0a;/*高教高教 出版社出版社 20082008*/uchar t1=17;void ptrvoid ptr(uchar duchar d)/*打印字符函数打印字符函数*/PA8155=d PA8155=d;PC8
37、155=0 x00PC8155=0 x00;/*产生选通脉冲产生选通脉冲*/PC8155=0 x01 PC8155=0 x01;whilewhile(BUSYBUSY););2023-1-2540void mainvoid main(voidvoid)COMD8155=0 x0f COMD8155=0 x0f;/*送命令字送命令字*/prt prt(0 x1c0 x1c););/*送中文打印方式命令字高字节送中文打印方式命令字高字节*/prt prt(0 x260 x26););/*送中文打印方式命令字低字节送中文打印方式命令字低字节*/EA=1 EA=1;EX1=1 EX1=1;whilew
38、hile(1 1););2023-1-2541void int1void int1(voidvoid)interrupt 2 using 1interrupt 2 using 1 uchar i uchar i;EA=0EA=0;forfor(i=0i=0;i t1i t1;i+i+)prtprt(tabitabi););EA=1EA=1;2023-1-2542vA/DA/D转换接口编程示例转换接口编程示例【例例10-410-4】ADC0809 ADC0809与单片机的接口电路如图。与单片机的接口电路如图。2023-1-2543#include#include“reg51.hreg51.h”#
39、include#include“absacc.habsacc.h”#define uchar unsigned char#define uchar unsigned char#define IN0 XBYTE0 x7ff8#define IN0 XBYTE0 x7ff8sbit ad_busy=P33sbit ad_busy=P33;2023-1-2544void ad0809void ad0809(uchar idata uchar idata*x x)uchar i uchar i;uchar xdata uchar xdata*ad_adr ad_adr;ad_adr=&IN0ad_ad
40、r=&IN0;forfor(i=0i=0;i 8i 8;i+i+)*ad_adr=0 ad_adr=0;/*启动转换启动转换*/i=i i=i;/*延时等待延时等待*/i=i i=i;whilewhile(ad_busy!=0ad_busy!=0););xi=xi=*ad_adr ad_adr;/*存转换结果存转换结果*/ad_adr+ad_adr+;/*下一通道下一通道*/2023-1-2545void mainvoid main(voidvoid)static uchar idata ad10 static uchar idata ad10;ad0809ad0809(adad););谢谢!