资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第二章,MCS51,单片机,C,语言程序设计,C,语言具有很强的表达能力,并具有较高的可移植性,提供了种类丰富的运算符和数据类型,可以直接实现对系统硬件的控制。,相对于汇编语言,使用,C,语言进行系统开发可以大大缩短开发周期,明显增强程序的可读性,便于改进和扩充。,本章就介绍使用,C,语言开发,8051,系列单片机程序的方法。,;,双字节无符号数加法程序,(R3R4+R6R7)=(R3R4);,入口,:R3,R4,R6,R7NADD :MOV A,R4 ADD A,R7 MOV R4,A MOV A,R3 ADDC A,R6 MOV R3,A RET,unsigned int val_1, val_2,;,unsigned int val_add;,val_add = val_1 + val_2;,第二章 MCS51单片机C语言程序设计C语言具有很强的表达,1,本章主要内容,C51,变量声明,C51,的,IO,口操作,C51,的中断响应方法,C51,的定时器操作,C51,的串行口操作,C51,的外部总线扩展操作,本章主要内容C51变量声明,2,2.1 C51,语言变量声明,但在,C,语言编程中,对数据类型与变量的定义必须要与单片机的存储结构相关联,否则编译器就不能正确的映射。,所以用,C,语言编写单片机应用程序是要根据单片机的结构及内部资源定义相应的,C,语言中的数据类型和变量。,用,C,语言编写的应用程序必须经单片机的,C,语言编译器,将源代码转换成单片机的可执行程序。,支持,MCS-51,系列单片机的编译器有很多,比较著名也是实际应用最多的是,KEIL/Franklin,编译器。这也是这门课使用的编译器。,2.1 C51语言变量声明但在C语言编程中,对数据类型与变量,3,一、,C51,数据类型,数据类型,长度(,bit,),长度(,byte,),值域,bit,1,1,0,1,unsigned char,8,1,0,255,signed char,8,1,-128,127,unsigned int,16,2,0,65535,signed int,16,2,-32768, 32767,unsigned long,32,4,0, 4294967295,signed long,32,4,-2147483648, 2147483647,float,32,4,1.176E-383.40E+38,(,6,位有效数字),double,64,8,1.176E-383.40E+38,(,10,位有效数字),指针,24,3,065535,(存储空间),表,2.1 C51,支持的数据类型,一、C51数据类型数据类型长度(bit)长度(byte)值域,4,二、,C51,数据类型修饰符,存储类型,与存储空间的对应关系,data,直接寻址,片内数据存储区,访问速度快(,128,字节),值域,0127,bdata,可位寻址,片内数据存储区,允许位与字节混合访问(,16,字节,值域,0127,idata,间接寻址片内数据存储区,可访问片内全部,RAM,地址空间(,256,字节,值域,0255,pdata,分页寻址片外数据存储区,,由,MOVX Ri,访问(,i=0,1,),值域,0255,xdata,片外数据存储区(,64KB,)由,MOVX DPTR,访问,值域,065535,code,程序存储器,64KB,空间,由,MOVC DPTR,访问,值域,065535,表,2.2 C51,存储类型修饰符,二、C51数据类型修饰符存储类型与存储空间的对应关系data,5,二、,C51,数据修饰符,修饰符名称,功能,const,指示被修饰的变量或者指针是常量,volatile,指示被修饰的变量或者指针可由多种原因被修改,禁止优化。常用于修饰多个函数公用的变量。,表,2.3,其他修饰符,二、C51数据修饰符修饰符名称功能const指示被修饰的变量,6,三、,C51,变量声明举例,C51,变量声明格式:,存储类型,+,类型说明,+,修饰符,+,标示符,=,初值,auto,register,static,extern,char,unsigned char,int,unsigned int,long,unsigned long,float,double,bit,sfr,sfr16,sbit,data,bdata,idata,pdata,xdata,code,const,volatile,value=,初值,unsigned char xdata val;,signed char data string;,bit bdata val_bit;,unsigned char xdata,*,pval;,unsigned char code,*,pcode;,三、C51变量声明举例C51变量声明格式:autochard,7,code,应用举例,unsigned char code tab4=0x00,0x01,0x02,0x03;,void main(void),unsigned char i,j=0;,for(i=0; i4; i+),j = j+tabi;,9: for(i=0; i4; i+),MOV R6,A,10: j = j+tabi;,MOV A,R6,MOV DPTR,#tab(0x001E),MOVC A,A+DPTR,ADD A,R7,MOV R7,A,11: ,code应用举例unsigned char code ta,8,三、,C51,存储模式,存储模式,说明,SMALL,参数及局部变量放入可直接寻址的片内存储区(最大,128,个字节),默认存储类型是,data,,访问方便。所有对象都嵌入片内,RAM,中。,COMPACT,参数及局部变量放入分页片外存储区(最大,256,个字节),默认存储类型是,pdata,,通过寄存器,R0,和,R1,间接寻址,栈空间位于,8051,系统内部数据区。,LARGE,参数及局部变量都放入片外数据存储器(最大,64K,),默认存储类型为,xdata,,使用,DPTR,访问。访问效率较低。,表,2.4,存储模式说明,三、C51存储模式存储模式说明SMALL参数及局部变量放入可,9,四、,C51,特殊功能寄存器,(SFR),的,C51,定义,MCS-51,单片机中除了,PC,和,4,组工作寄存器外,其他的所有寄存器均为特殊功能寄存器(,SFR,),分散在片内,RAM,区的高,128,字节中,地址范围为,80H0FFH,。,为能直接访问,SFR,,,Franklin C51,提供了自动定义方法,与标准,C,语言不兼容,只适用于,MSC-51,单片机进行编程。一般将特殊功能寄存器定义放在头文件中,一般为,reg51.h,。,特殊功能寄存器的定义语法为:,sfr sfr_name = int constant,例如:,sfr SCON=0x98; /,*串行口控制寄存器地址,98H,*,/,SCON = 0x01;,四、C51特殊功能寄存器(SFR)的C51定义MCS-51单,10,四、,C51,特殊功能寄存器,(SFR),的,C51,定义,sbit,定义位寻址单元,第一种定义格式:,sbit bit_name = sfr_nameint constant;,sbit,是定义语句的关键字,bit_name,为位寻址符号名,sfr_name,为已经定义过的特殊功能寄存器名,int constant,为欲寻址的特殊功能寄存器在,sfr_name,中的位号,sfr PSW=0xD0;/,*定义,PSW,寄存器地址为,D0H,*,/,sbit OV=PSW2;/,*定义,OV,位为,PSW.2,,地址为,D2H,*,/,Sbit CY=PSW7;/,*定义,CY,位为,PSW.7,,地址为,D7H,*,/,四、C51特殊功能寄存器(SFR)的C51定义sbit定义位,11,四、,C51,特殊功能寄存器,(SFR),的,C51,定义,第二种定义格式:,sbit bit_name=constant_1constant_2;,sbit,是定义语句的关键字,bit_name,为位寻址符号名,constant_1,为特殊功能寄存器的字节地址,constant_2,为欲寻址位在特殊功能寄存器中的位号,sbit OV=0xD02;/,*定义,OV,位为,PSW.2,,地址为,D2H,*,/,Sbit CY=0xD07;/,*定义,CY,位为,PSW.7,,地址为,D7H,*,/,sbit,定义位寻址单元,四、C51特殊功能寄存器(SFR)的C51定义第二种定义格式,12,第三种定义格式:,sbit bit_name=int_constant;,sbit,是定义语句的关键字,bit_name,为位寻址符号名,int_constant,为绝对位地址,sbit OV=0xD2;/,*定义,OV,位为,PSW.2,,地址为,D2H,*,/,Sbit CY=0xD7;/,*定义,CY,位为,PSW.7,,地址为,D7H,*,/,sbit,定义位寻址单元,四、,C51,特殊功能寄存器,(SFR),的,C51,定义,第三种定义格式:sbit bit_name=int_cons,13,2.2 51,单片机,IO,口操作的,C,语言编程方法,#include ,sbit DIPCK = P26;,unsigned char DIP_state;,void main(),unsigned char temp;,P0 = 0xff;,DIPCK = 0,; /,*打开,273,*,/,temp = P0,; /,*读取,DIP,开关状态*,/,DIPCK = 1,; /,*关闭,273,*,/,2.2 51单片机IO口操作的C语言编程方法#include,14,2.2 51,单片机,IO,口操作的,C,语言编程方法,6: unsigned char temp;,7: P0 = 0xff;,MOV P0(0x80), #0xFF,8: DIPCK = 0;,CLR DIPCK(0xA0.6),9: temp = P0;,MOV 0x09, P0(0x80),10: DIPCK = 1;,SETB DIPCK(0xA0.6),#include ,sbit DIPCK = P26;,unsigned char DIP_state;,void main(),unsigned char temp;,P0 = 0xff;,DIPCK = 0,; /,*打开,273,*,/,temp = P0,; /,*读取,DIP,开关状态*,/,DIPCK = 1,; /,*关闭,273,*,/,2.2 51单片机IO口操作的C语言编程方法 6:,15,2.2 51,单片机,IO,口操作的,C,语言编程方法,读,IO,口:,value = P0;,写,IO,口:,P0 = value;,读,IO,端脚:,value_pin = P00;,写,IO,端脚:,P00 = value_pin;,C51,语言操作,IO,端口方法:,2.2 51单片机IO口操作的C语言编程方法读IO口:val,16,2.3 51,单片机中断的,C,语言编程方法,C51,编译器支持在,C,源程序中直接开发中断程序。中断程序是通过按照编译器规定的语法格式定义的一个函数。,C51,中断服务程序的函数定义的语法格式如下:,void,函数名,() interrupt m using n,/,*函数体*,/,中断服务函数没有返回值也没有参数,m,为服务的中断源编号,与中断入口对应,n,为中断服务程序选用的寄存器组编号,2.3 51单片机中断的C语言编程方法C51编译器支持在C源,17,编号,中断源,入口地址,0,外部中断,0,0003H,1,定时器,/,计数器,0,000BH,2,外部中断,1,0013H,3,定时器,/,计数器,1,001BH,4,串行口中断,0023H,表,2.5 51,单片机中断源编号,一、,C51,中断系统编程,编号中断源入口地址0外部中断00003H1定时器/计数器00,18,一、,C51,中断系统编程,汇编语言中断服务程序的,般格式如下:,CLR EA,;,关中断,PUSH PSW ;,保护现场,PUSH A,SETB EA,;,开中断, ;服务程序,CLR EA,;,关中断,POP A,;恢复现场,POP PSW,SETB EA,;,开中断,RETI,;,中断返回,C,语言中断服务程序的,一般格式如下:,void interrupt_server() interrupt m using n,/,*中断服务程序*,/,外部中断,0,的,C,语言中断服务程序:,void int0_interrupt_server() interrupt 0 using 0,/,*中断服务程序*,/,一、C51中断系统编程汇编语言中断服务程序的C语言中断服务程,19,二、外部中断的服务程序编写方法,#include ,sbit P1_1=P11; sbit P1_0 = P10;,void main(),IT0 = 1;,IT1 = 1;,IE0 = 1; IE1 = 1;,EA = 1;,while(1) ,void int0_server() interrupt 0 using 0,P1_1 = 0;,P1_0 = 1;,void int0_server() interrupt 2 using 1,P1_1 = 1;,P1_0 = 0;,二、外部中断的服务程序编写方法#include reg51,20,2.4 51,单片机定时器,C,语言编程,一、定时器,查询方式,程序编写方法,编写定时器中断服务程序,使,P1.0,引脚上输出周期为,4ms,,占空比为,1:1,的方波。晶振,12MHz,。,#include ,sbit p10=p10;,void clock_initial(),TR0=0;,TF0=0;,TH0=0xF8;,TL0=0x30;,TR0=1;,void main(),TMOD=0x01;,for(;),clock_initial();,do,while(!TF0);,p10=!p10;,2.4 51单片机定时器C语言编程一、定时器查询方式程序编写,21,二、定时器中断的服务程序编写方法,#include ,void main(),TMOD = 0x01; P10 = 0;,TF0 = 0;,TR0 = 0; /,*关闭定时器,0,*,/,TH0 = 0xF8; /,*装载级数初值*,/,TL0 = 0x30;,TR0 = 1; /,*启动定时器,1,*,/,ET0 = 1; /,*允许定时器中断,*/,EA = 1;,for( ; ; ) ,void clk_int(void) interrupt 1 using 0,TR0 = 0; /,*关闭定时器,0,*,/,TH0 = 0xF8; /,*装载级数初值*,/,TL0 = 0x30;,TR0 = 1; /,*启动定时器,1,*,/,P10 =! P10;,编写定时器中断服务程序,使,P1.0,引脚上输出周期为,4ms,,占空比为,1:1,的方波。晶振,12MHz,。,二、定时器中断的服务程序编写方法#include reg5,22,2.5 51,单片机串行口,C,语言编程,一、串行口,查询方式,程序编写方法,设串行口数据传送的波特率为,4800,,晶振,11.0592MHz,。采用查询方式,接收到数据后,立即发送。,#include ,void init_serialcomm(void),SCON = 0x50; /8N1,TMOD |= 0x20; /,定时器设置,PCON |= 0x80; /SMOD=1;,/Baud:4800 fosc=11.0592MHz,TH1 = 0xF4;,IE |= 0x90; /,使能外部中断,TR1 = 1; / timer 1 run,void main(),init_serialcomm();,while(1),while(RI=0);,a=SBUF;,SBUF = a;,while(TI=0);,TI=0;,2.5 51单片机串行口C语言编程一、串行口查询方式程序编写,23,四、串行口中断的服务程序编写方法,设串行口数据传送的波特率为,4800,,编写串口接收中断服务程序。串口接收到数据后,立即通过串口发送出去。,#include ,void init_serialcomm(void),SCON = 0x50; /8N1,TMOD |= 0x20; /,定时器设置,PCON |= 0x80; /SMOD=1;,/Baud:4800 fosc=11.0592MHz,TH1 = 0xF4;,IE |= 0x90; /,使能外部中断,TR1 = 1; / timer 1 run,void main(void),init_serialcomm();,for(; ;) ,void serial_server() interrupt 4 using 3,unsigned ch;,RI = 0;,ch = SBUF;,SBUF = ch;,While(TI = 0),;,TI = 0;,四、串行口中断的服务程序编写方法设串行口数据传送的波特率为4,24,2.6 51,单片机外部扩展的,C,语言编程方法,xdata,片外数据存储区(,64KB,)由,MOVX DPTR,访问,值域,065535,char xdata com;,com = 0x01;,char xdata com;,com = 0x01;,MOV DPTR, #0x0000,MOV A,#0x01,MOVX DPTR,A,C,语言程序,汇编程序,如何确定,DPTR,值?,2.6 51单片机外部扩展的C语言编程方法xdata片外数据,25,一、,C51,指针类型,1,、基于存储器的指针,指针所指向的地址在编译时确定。,char xdata com; com = 0x01;,2,、通用指针,三字节组成。,第一个字节为:指针类型,第二和第三字节为:,16,位地址高,8,位和低,8,位。,通用指针的形式为:,#define XBYTE ( (char*)0x20000L),指向,xdata,,偏移量为,0,的通用指针,指针类型:,1,为,idata, 2,为,xdata, 3,为,pdata,,,4,为,data,,,5,为,code,一、C51指针类型1、基于存储器的指针指针所指向的地址在编译,26,二、通用指针,例:将常数,0x41,写入地址为,0x8057,的外部数据存储器,#define XBYTE (char *) 0x20000L),XBYTE0x8057 = 0x41;,10: XBYTE0x8057 = 0x41;,MOV DPTR,#0x8057,MOV A,#0x41,MOVX DPTR,A,偏移量,二、通用指针例:将常数0x41写入地址为0x8057的外部数,27,三、,absacc.h,#define CBYTE (unsigned char volatile code *) 0),#define DBYTE (unsigned char volatile data *) 0),#define PBYTE (unsigned char volatile pdata *) 0),#define XBYTE (unsigned char volatile xdata *) 0),#define CWORD (unsigned int volatile code *) 0),#define DWORD (unsigned int volatile data *) 0),#define PWORD (unsigned int volatile pdata *) 0),#define XWORD (unsigned int volatile xdata *) 0),#define XBYTE (char *) 0x20000L),XBYTE0x8057 = 0x41;,#include ,#include ,void main(void),XBYTE0x8057 = 0x41;,#include ,#include ,#define COM XBYTE0x8057,void main(void),COM = 0x41;,三、absacc.h#define CBYTE (unsi,28,2.5,几类重要的库函数,C51,提供了丰富的库函数资源,包括大量的关于,I/O,操作、内存分配、字符串操作、据类型转换、数学计算等函数库。它们是以执行代码的形式出现,供用户在连接定位时用。在用预处理器命令,include,包含相应的头文件后,就可以在程序中使用这些函数。,2.5几类重要的库函数C51提供了丰富的库函数资源,包括大量,29,一、硬件地址定义头文件,reg5x.h,定义了特殊功能寄存器的地址。,在文件开头首先要包含该文件。,/* BYTE Register */,sfr P0 = 0x80;,sfr P1 = 0x90;,sfr P2 = 0xA0;,sfr P3 = 0xB0;,sfr PSW = 0xD0;,sfr ACC = 0xE0;,sfr B = 0xF0;,sfr SP = 0x81;,sfr DPL = 0x82;,一、硬件地址定义头文件reg5x.h定义了特殊功能寄存器的地,30,这个库中提供的是一些用汇编语言编写的函数。用汇编语言编写非常直接简单且目代码很短,而用,C51,编写则代码很长。这些函数主要有:,_crol_/_cror_,无符号字符型变量左,/,右移位函数,_irol_/_iror_,无符号整型变量左,/,右移位函数,_lrol_/_lror_,无符号长整型变量左,/,右移位函数,_nop_,空操作函数,_testbit_,位测试函数,一、内部函数库,intrins.h,这个库中提供的是一些用汇编语言编写的函数。用汇编语言编写非常,31,#inclucle ,void main,(),unsigned int y,;,y,0x00ff,;,y,_irol_,(,y,,,4,);,举例:,运行后,,y,0x0ff0,。,一、内部函数库,intrins.h,#inclucle 举例:运行后,y,32,二、绝对地址访问函数,absacc.h,用预处理器伪指令,define,为各空间的绝对地址定义宏数组名如下:,define CBYTE,(,unsigned char*,),0x500000L,),/*code,空间*,/,define DBYTE,(,unsigned char*,),0x400000L,),/*data,空间*,/,define PBYTE,(,unsigned char*,),0x300000L,),/*pdata,空间*,/,define XBYTE,(,unsigned char*,),0x200000L,),/*xdata,空间*,/,以上存取对象是,char,类型字节。,DBYTE0x10,表示,data,空间绝对地址,16,处的字节对象,,XWORD0xff,表示,xdata,空间绝对地址,255,处的字对象。,define CWORD,(,unsigned int*,),0x500000L,),/*code,空间*,/,define DWORD,(,unsigned int*,),0x400000L,),/*data,空间*,/,define PWORD,(,unsigned int*,),0x300000L,),/*pdata,空间*,/,define XWORD,(,unsigned int*,),0x200000L,),/*xdata,空间*,/,以上存取对象是,int,类型字。,二、绝对地址访问函数absacc.h用预处理器伪指令def,33,三、其他函数库,math.h,数学函数图,stdio.h,标准,IO,库,主要是用来操作串口的。,string.h,字符串操作函数,stdlib.h,标准库函数。包括格式转换,基本数值运算等。,setjmp.h,全程跳转函数,允许程序从深层函数调用中直接返回。,三、其他函数库math.h,34,习题与思考,请简述与汇编语言对比,采用,C51,进行单片机程序设计的优点,设晶振频率为,12MHz,,利用定时器,/,计数器,0,,采用查询方式设计单片机程序,使单片机在,P1.0,引脚上输出周期为,4ms,,占空比为,1:1,的方波。,设单片机需要相应,8,个外部中断源。请设计相应的电路原理图和程序框架。(提示:可使用,74LS148,优先编码器对,8,个中断进行编码,,74LS148,的,GS,引脚可作为中断请求输出。),请设计串口接收中断服务程序。程序按照接收的命令发送数据。要求接收数字,1,,发送字符,a,,接收其他数据不响应。设晶振速度为,11.0592MHz,,波特率为,4800.,习题与思考请简述与汇编语言对比,采用C51进行单片机程序设计,35,
展开阅读全文