单片机与嵌入式系统5_第1页
单片机与嵌入式系统5_第2页
单片机与嵌入式系统5_第3页
单片机与嵌入式系统5_第4页
单片机与嵌入式系统5_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第五章第五章 C51吸取了汇编语言的精华吸取了汇编语言的精华 提供了对位、字节及地址的操作,使程序可以直接对内提供了对位、字节及地址的操作,使程序可以直接对内存及指定寄存器进行控制;存及指定寄存器进行控制; 吸取了宏汇编技术中的某些灵活的处理方法,提供宏代吸取了宏汇编技术中的某些灵活的处理方法,提供宏代换换#define和文件蕴含和文件蕴含#include的预处理命令;的预处理命令; C51继承和发扬了高级语言的长处继承和发扬了高级语言的长处 C51 的可移植性好的可移植性好 生成的代码质量高生成的代码质量高目前使用目前使用C51开发系统最流行的是开发系统最流行的是Keil C51软件平台软件

2、平台 5.1 C51语言特点语言特点3/2/2022n5.2 标识符与关键字标识符与关键字 C51的标识符的标识符 C51的标识符基本同标准的的标识符基本同标准的C语言语言C51的关键字的关键字C51的关键字有的关键字有ANSI C标准的关键字,见表标准的关键字,见表5-1所示;所示;C51扩展的关键字,见表扩展的关键字,见表52所示(这里略)。所示(这里略)。3/2/2022n5.3 C51程序设计的基本规则程序设计的基本规则5.3.1 数据类型与存储模式数据类型与存储模式一、一、C51数据类型数据类型 数据类型 大小 数表示范围char/unsigned char8 bit-128127

3、/ 0255int/unsigned int16 bit-3276832767 / 065535long/unsigned long32 bit-21474836482147483647/04294967295float/double32 bit1.75494E-38 3.402823E+38 C51实际上不支持双精度浮点数实际上不支持双精度浮点数double,即便定义了即便定义了double,也是按照,也是按照float处理的。处理的。1、基本数据类型、基本数据类型3/2/20222、C51扩充数据类型扩充数据类型3/2/2022二、常量、变量与数据存储模式二、常量、变量与数据存储模式常量和

4、变量一样可以有不同的数据类型。常量和变量一样可以有不同的数据类型。可以用一个标识符可以用一个标识符const来声明一个量是常量。来声明一个量是常量。例:例:unsigned char system_status=0;unsigned int unit_id2;const char samp_string16;float outport_value; 常量常量在程序运行的过程中,其值始终不能改变的量。在程序运行的过程中,其值始终不能改变的量。 变量变量在程序运行的过程中其值可以改变的量。在程序运行的过程中其值可以改变的量。3/2/2022 还可以使用预编译语句还可以使用预编译语句#define定

5、义定义符号常量符号常量:#define CONST100#define NULL0#define TRUE1#define FALSE0 符号常量的值不能改变,它仅仅是代表某个固符号常量的值不能改变,它仅仅是代表某个固定常数的一个符号而已。定常数的一个符号而已。 习惯上符号常量通常用大写,而变量用小写,习惯上符号常量通常用大写,而变量用小写,注意养成良好的编程习惯。注意养成良好的编程习惯。3/2/2022C51变量定义格式:变量定义格式:存储种类存储种类 数据类型数据类型 存储器类型存储器类型 变量名变量名;存储种类存储种类 auto (自动自动) extern (外部外部) static (

6、静态静态) register (寄存器寄存器) 如果省略,则默认为如果省略,则默认为auto3/2/2022存储器类型存储器类型存储区描述data寻址片内低128字节,速度最快(MOV);bdata寻址片内20H-2FH的单元(bit 位); idata间接寻址片内256字节(MOV Ri ); pdata寻址外部存储区的256个字节(MOVX Ri ),一般是片外RAM第一页空间;xdata寻址外部64KRAM ( MOVX DPTR );code寻址程序区(MOVC A+DPTR 或MOVC A+PC);3/2/2022(1)data区区 对对data区的寻址是最快的,所以应该把使用频区的

7、寻址是最快的,所以应该把使用频率高的变量放在率高的变量放在data区。区。 注意使用注意使用data区不要超过区不要超过data区的范围,除了区的范围,除了包含程序变量外,还包含了包含程序变量外,还包含了堆栈堆栈和和寄存器组寄存器组。 当内部堆栈溢出时,程序会莫名其妙地复位,当内部堆栈溢出时,程序会莫名其妙地复位,实际原因是实际原因是8051系列微处理器没有硬件报错机制,系列微处理器没有硬件报错机制,堆栈溢出只能以这种方式表示出来堆栈溢出只能以这种方式表示出来unsigned int data k1,k2; char data inp_string16;3/2/2022(2)bdata区区 在

8、在bdata区定义变量,这个变量的每个位就可区定义变量,这个变量的每个位就可进行位寻址。进行位寻址。 unsigned char bdata s1;unsigned int bdata s2;sbit flag=s14;if(s215) flag=1;3/2/2022 idata区也可存放使用比较频繁的变量,区也可存放使用比较频繁的变量,使用寄使用寄存器作为指针进行寻址存器作为指针进行寻址。(3)idata区区int idata y110; float idata outp_value;3/2/2022 在这两个区声明变量和在其它段的语法是一样的。在这两个区声明变量和在其它段的语法是一样的。p

9、data区只有区只有256个字节,而个字节,而xdata区可达区可达65536个字个字节节。(4)pdata和和xdata区区 对对pdata区寻址比对区寻址比对xdata区寻址要快,因为对区寻址要快,因为对pdata区寻址只需要装入区寻址只需要装入8位地址,而对位地址,而对xdata段寻段寻址需装入址需装入16位地址,位地址,所以尽量把外部数据存储在所以尽量把外部数据存储在pdata段中。段中。3/2/2022(5)code区区 代码区的数据是不可改变的,一般代码段中可代码区的数据是不可改变的,一般代码段中可存放存放数据表数据表、跳转向量跳转向量和和状态表状态表,代码段中的变量代码段中的变量

10、在定义的时候需要初始化,在定义的时候需要初始化,否则就得不到想要的值。否则就得不到想要的值。unsigned int code unit_id2=1234;unsigned char code Num= 0 x00, 0 x01, 0 x02, 0 x03, 0 x04, 0 x05, 0 x06, 0 x07, 0 x08, 0 x09, 0 x10, 0 x11, 0 x12, 0 x13, 0 x14, 0 x15;3/2/2022如果在变量定义时略去存储类型,编译器会自动选择如果在变量定义时略去存储类型,编译器会自动选择默认的存储类型默认的存储类型,而默认的存储类型进一步由,而默认的存

11、储类型进一步由SMALL、COMPACT和和LARGE存储模式指令限制。存储模式指令限制。存储模式说明SMALL参数及局部变量放入data区,默认存储类型是data,栈空间位于片内idata(片内RAM)COMPACT参数及局部变量放入pdata区,默认存储类型是pdata(片外RAM);栈空间位于片内idata(片内RAM)LARGE参数及局部变量放入xdata区,默认存储类型是xdata,模拟堆栈位于片外xdata(片外RAM)存储模式可以在存储模式可以在Keil C51编译器中设置编译器中设置3/2/2022 Keil C编译器能产生高度优化的代码,但你编译器能产生高度优化的代码,但你可

12、以帮助编译器产生更好的代码。可以帮助编译器产生更好的代码。使用使用Keil C时应做的和应该避免的时应做的和应该避免的3/2/2022 一个提高代码效率的最基本的方式就是减小变量一个提高代码效率的最基本的方式就是减小变量的长度。使用的长度。使用C编程时,我们都习惯于对循环控制变编程时,我们都习惯于对循环控制变量使用量使用int类型,这对类型,这对8位的单片机来说是一种极大的位的单片机来说是一种极大的浪费。应该仔细考虑你所声明的变量值可能的范围,浪费。应该仔细考虑你所声明的变量值可能的范围,然后选择合适的变量类型。然后选择合适的变量类型。很明显,经常使用的变量应该是很明显,经常使用的变量应该是u

13、nsigned char,只占用一个字节只占用一个字节:(1)采用短变量)采用短变量unsigned char data n;3/2/2022 如果程序中可以不需要负数,那么把变量都定如果程序中可以不需要负数,那么把变量都定义成无符号类型的变量义成无符号类型的变量:(2)使用无符号类型)使用无符号类型 unsigned int data n1,n2;3/2/2022 在在8位操作系统上使用位操作系统上使用32位浮点数是得不偿位浮点数是得不偿失的。你可以这样做,但会浪费大量的时间。所失的。你可以这样做,但会浪费大量的时间。所以当你要使用浮点数的时候,你要问问自己是否以当你要使用浮点数的时候,你要

14、问问自己是否一定需要。一定需要。 可以通过提高数值数量级和使用整型运算来可以通过提高数值数量级和使用整型运算来消除浮点指针。处理消除浮点指针。处理int和和long比处理比处理double和和float要方便得多,代码执行起来会更快。要方便得多,代码执行起来会更快。 如果一定要采用浮点指针的话,应该采用已如果一定要采用浮点指针的话,应该采用已经对数处理进行过优化的单片机。经对数处理进行过优化的单片机。 (3)避免使用浮点数)避免使用浮点数3/2/2022(4)使用位变量)使用位变量 对某些标志位应使用位变量对某些标志位应使用位变量bit而不是而不是unsigned char,节省内存。不用多浪

15、费节省内存。不用多浪费7位存储区,而且位变量在位存储区,而且位变量在RAM中访中访问只需要一个处理周期。问只需要一个处理周期。 把变量定义成局部变量比全局变量更有效率,编译把变量定义成局部变量比全局变量更有效率,编译器为局部变量在器为局部变量在内部存储区中分配存储空间内部存储区中分配存储空间,而为,而为全局全局变量在外部存储区中分配存储空间变量在外部存储区中分配存储空间,这会降低访问速度。,这会降低访问速度。 (5)用局部变量代替全局变量)用局部变量代替全局变量 考虑到存储速度,按下面的顺序使用存储器:考虑到存储速度,按下面的顺序使用存储器:data、idata、pdata、xdata,但要记

16、得留出足够的堆栈空间。,但要记得留出足够的堆栈空间。(6)为变量分配内部存储区)为变量分配内部存储区3/2/2022sfr 特殊功能寄存器名特殊功能寄存器名 = 地址常数;地址常数;例如例如: sfr P0 = 0 x80;/定义了定义了I/O口口P0,其地址为,其地址为80Hsfr P1 = 0 x90;/定义了定义了I/O口口P1,其地址为,其地址为90H (可参考可参考Keil C51 中中reg51.h 各定义各定义)5.3.2 对硬件主要资源的定义对硬件主要资源的定义一、一、sfr定义方法定义方法3/2/2022编程时包含头文件即可编程时包含头文件即可 #include 或或 #in

17、clude 在在reg51中中,已经宏定义了所有已经宏定义了所有SFR寄存器。如:寄存器。如:/* BYTE Register */ sfr P0 = 0 x80; sfr P1 = 0 x90; sfr P2 = 0 xA0; sfr P3 = 0 xB0; sfr PSW = 0 xD0; sfr ACC = 0 xE0;sfr B = 0 xF0; sfr SP = 0 x81; sfr DPL = 0 x82; sfr DPH = 0 x83; sfr PCON = 0 x87; sfr TCON = 0 x88;sfr TMOD = 0 x89; sfr TL0 = 0 x8A; s

18、fr TL1 = 0 x8B; sfr TH0 = 0 x8C; sfr TH1 = 0 x8D; sfr IE = 0 xA8;sfr IP = 0 xB8; sfr SCON = 0 x98; sfr SBUF = 0 x99; sfr AUXR = 0 x8e; 3/2/2022sfr16 特殊功能寄存器名特殊功能寄存器名 = 地址常数地址常数 ;如:对于如:对于8052单片机的定时器单片机的定时器T2,可采用如下的方法来定义。,可采用如下的方法来定义。sfr16 T2 = 0 xCC;/定义定义timer2,其地址为,其地址为T2L=0 xCC,T2H=0 xCD二、二、sfr16定义

19、方法定义方法三、三、sbit 定义方法定义方法sbit 位变量名位变量名 = 位地址;位地址;sbit OV = 0 xD2 ;/ 定义了定义了PSW中的溢出标志中的溢出标志sbit CY = 0 xD7 ;/ 定义了定义了PSW中的进位标志中的进位标志sbit clk = 0 x91;/ 定义了定义了P1.1口信号线口信号线3/2/2022sbit 位变量名位变量名 = 特殊功能寄存器名特殊功能寄存器名位位置位位置sfr PSW = 0 xD0 ;sfr P1 = 0 x90 ;sbit OV = PSW2 ;/定义了定义了PSW的第的第2位为溢出标志位为溢出标志sbit CY = PSW7

20、 ;/定义了定义了PSW的第的第7位为进位标志位为进位标志sbit clk = P11 ; /定义了定义了P1的第的第1位为信号线位为信号线sbit 位变量名位变量名 = 字节地址字节地址位位置位位置sbit OV = 0 xD02 ;sbit CY = 0 xD07 ;sbit clk = 0 x901;3/2/2022sbit 位变量名位变量名 = 可位寻址对象可位寻址对象位位置位位置8051单片机内部单片机内部0 x200 x2F可位寻址区称之可位寻址区称之“可位寻址对象可位寻址对象”int bdata inumb ;/ 在位寻址区定义在位寻址区定义一个整型变量一个整型变量inumb c

21、har bdata bary4;/在位寻址区定义一个字符数组在位寻址区定义一个字符数组bary4sbit mybit0 = inumb0 ;/整型变量的第整型变量的第0位(共位(共16位)位)sbit mybit15 = inumb15;/整型变量的第整型变量的第15位位sbit ary07 = bary07; /第第1个字节中的第个字节中的第7位位sbit ary37 = bary37; /第第4个字节中的第个字节中的第7位位reg51.h和和reg52.h也包含有位定义,编程时包含头文件即可也包含有位定义,编程时包含头文件即可3/2/2022例如:例如:#include sbit P10=

22、P10;sbit P12=P12;main()P10=1;P12=0;PSW=0 x08;3/2/2022利用利用bit只能定义一个普通的位变量,取值只能定义一个普通的位变量,取值0或或1。 (定义的变量在(定义的变量在8051的的20H-2FH字节中)字节中)如,如,bit a,b,c; /定义了三个位变量定义了三个位变量a、b、c。这三个位变量应位于。这三个位变量应位于/8051内部内部00H7FH中的某三位。中的某三位。 四、四、bit 定义方法定义方法3/2/2022使用使用#define宏定义宏定义如,如, #include /XBYTE的头文件的头文件 #define PORTA

23、XBYTE0 x8000 /将将PORTA定义为外部定义为外部I/O口,地址为口,地址为0 x8000 main() PORTA=0 x3A; /将数据将数据3AH写入地址为写入地址为0 x8000的的I/O端口端口 使用地址定位使用地址定位 _at_ 定义定义如,如,unsigned char xdata x_data _at_ 0 x50; /这是以这是以0 x50开头的外部地址,无符号字符变量数组开头的外部地址,无符号字符变量数组x_data 的起址的起址 unsigned char xdata x_data0 x40 _at_ 0 x50; /这是以这是以0 x50开头的外部地址空间开

24、头的外部地址空间, 为为0 x40个个 unsigned char xdata Y0 _at_ 0 x1000; /这是以这是以0 x1000开头的外部地址,无符号字符变量开头的外部地址,无符号字符变量Y0的起址的起址 五、对片外扩展五、对片外扩展I/O或地址的定义方法或地址的定义方法3/2/2022使用指针变量操作外部地址使用指针变量操作外部地址 如如: unsigned char xdata * px; /定义了外部存储器的指针变量定义了外部存储器的指针变量 px=0 x1000; /给指针变量赋地址给指针变量赋地址 *px =0 x55; /给外部给外部1000h写入写入0 x553/2

25、/2022对片内具体地址的定义可以采用指针变量对片内具体地址的定义可以采用指针变量如:如: unsigned char idata * px; /定义了内部存储器的指针变量定义了内部存储器的指针变量 px=0 x90; /给指针变量赋地址给指针变量赋地址 *px =0 x66; /给内部给内部90h写入写入0 x66六、对片内地址的定义方法六、对片内地址的定义方法3/2/20225.3.3 C51的运算符与表达式的运算符与表达式略(参看略(参看131135)3/2/2022C51的位运算符的位运算符 能对运算对象进行能对运算对象进行按位操作是按位操作是C51的一大特点的一大特点,使使C51能对

26、硬件直接进行操作。能对硬件直接进行操作。C51提供了六种位运算提供了六种位运算如下表所示。如下表所示。3/2/2022n5.4 C51基本语句基本语句略(参看略(参看p135142)3/2/2022n5.5 函数函数略(参看略(参看p142148)3/2/2022C51中断函数中断函数void 函数名函数名 interrupt n using minterrupt后面的后面的n是中断号,是中断号,n取值取值031using后面的后面的m是选择的寄存器组,取值是选择的寄存器组,取值03编译器从编译器从8n+3处产生中断向量处产生中断向量常用中断号与中断向量常用中断号与中断向量中断号n中断源中断向

27、量8n+30外部中断00003H1定时/计数器0000BH2外部中断10013H3定时/计数器1001BH4串口0023H3/2/2022C51库函数库函数reg51.h 8051内部内部SFR定义定义reg52.h 8052内部内部SFR定义定义absacc.h 允许直接访问允许直接访问8051不同存储器的定义函数不同存储器的定义函数ctype.h 字符转换和分类程序字符转换和分类程序stdlib.h 存储器分配程序存储器分配程序stdio.h 常用输入输出库函数常用输入输出库函数string.h 字符串操作、缓冲区操作函数字符串操作、缓冲区操作函数math.h 常用数学函数常用数学函数3/

28、2/2022#include #define uint unsigned int#define uchar unsigned charsbit P14=P14; /LED0sbit P15=P15; /LED1void delay(uint); /延时函数声明延时函数声明void delay(uint x) /延时延时xms uchar i; while(x-0) for(i=0;i125;i+); void main() while(1) P14=0; /LED0亮亮 P15=1; /LED1灭灭 delay(1000); /延时延时1秒秒 P14=1; /LED0灭灭 P15=0; /LE

29、D1亮亮 delay(1000); /延时延时1秒秒 流水灯程序流水灯程序3/2/2022#include #define uint unsigned int#define uchar unsigned charsbit K1=P13; /按键按键K1uchar n=0; /数码管编码计数数码管编码计数 uchar code ss =0 x0C0,0 x0F9,0 x0A4,0 x0B0,0 x99,0 x92,0 x82,0 x0F8, /数码管编码数码管编码 0 x80,0 x90,0 x88,0 x83,0 x0C6,0 x0A1,0 x86,0 x08E; void delay(uin

30、t); /延时函数声明延时函数声明void delay(uint x) /延时延时xms uchar i; while(x-0) for(i=0;i125;i+); void main() P2=0 x0FE; P0=0 x0C0; /数码管初始显示数码管初始显示0 while(1) /自己编写程序自己编写程序 数码管增一程序数码管增一程序3/2/20223/2/20223/2/2022/*=读取键盘代码子程序读取键盘代码子程序=*/void read_key(void) unsigned char x; P3=0 xf0; /将键盘的列赋值将键盘的列赋值0 x=P3|0 x0f; /将键盘的

31、行值付给将键盘的行值付给x if(x!=0 xff) /软件的键盘防抖动软件的键盘防抖动,ff无键按下无键按下 !=ff有键按下有键按下 delay(200); P3=0 xf0; /延时去抖,再判断是否有键按下延时去抖,再判断是否有键按下 x=P3|0 x0f; if(x!=0 xff) /如果键盘的行有低电平,则有键按下如果键盘的行有低电平,则有键按下 P3=x; /将对应的行赋值将对应的行赋值0 key_code=P3; /此时根据行和列的值,即为按键代码此时根据行和列的值,即为按键代码 if(key_code=238) /如果按键为如果按键为0,蜂鸣器响,蜂鸣器响 P1=0 xbf;

32、else P1=0 xff; key_press=1; /将按键标志位置将按键标志位置1 3/2/2022附:keil C51 使用简介u(1)点击 Project 菜单,选择弹出的下拉式菜单中的 New Project,如图 12。 图 12 New Project 菜单 3/2/2022u(2)选择所要的单片机,这里选择常用的 Ateml 公司的 AT89c52。此时屏幕如图 14 所示。 图 14 选取芯片 3/2/2022u(3)、首先在项目中创建新的程序文件或加入旧程序文件。如果您没有现成的程序,那么就要新建一个程序文件。在 KEIL 中有一些程序的 Demo,在这里我们还是以一个 C 程序 为例介绍如何新建一个 C 程序和如何加到您的第一个项目中。点击图 15 中 1 的新建文件的快捷按钮,在 2 中出现一个新的文字编辑窗口。图 15 新建程序文件 这个操作也能通过菜单 F

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论