第6次:C51语言程序设计课件_第1页
第6次:C51语言程序设计课件_第2页
第6次:C51语言程序设计课件_第3页
第6次:C51语言程序设计课件_第4页
第6次:C51语言程序设计课件_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

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

文档简介

四川师范大学成都学院腾讯微云:/DSdKRL2013-09-01刘强课件下载课程教学内容绪论第0章计算机的基础知识第1章单片机的硬件结构----重点

第2章单片机的指令系统----了解 第3章单片机的汇编语言程序设计---了解

第4章单片机的C语言(C51语言)编程----重点第5章单片机的输入、输出口----重点 第6章单片机的中断系统----重点 第7章单片机的定时器/计数器----重点 第8章单片机的串行接口----重点

第9章单片机总线与系统扩展 第10章单片机应用接口技术

————后面章节选择自学四川师范大学成都学院教师:刘强C51语言程序设计

现在几乎所有的单片机都能用C语言编程了,采用C语言编程确实能带来很多好处,至少可读性比汇编语言强多了。C语言的基础知识不足的同学希望大家课后找时间补充!希望同学们在实践中去学习和领悟C语言!接下来我们来看C51与C的不同之处!单片机的C语言标准C语言单片机的C语言(C51语言)单片机的C是在标准C语言的基础上扩展而成。故我们仅需学习与单片机紧密关联的扩展部分,即可达到快速掌握C51高级语言的目的。“语言不是教出来的,而是学出来的”。那么,C51语言能力也类似:不是背C语言“条文”背出来的,是读程序“读”出来的,是编程序“编”出来,是在做项目编程序、调试程序的实践中形成和提高的。学习C51语言,还必须读C51源程序范文:从范文中加深对语言法则的理解,认识并熟悉语言元素、用语范例,理解语言和单片机硬件行为的关联,学习程序结构的组织(流程图设计),积累编程的通常技巧和算法。尽量作到读懂人家的成熟的软件,领悟、总结、模仿和借鉴,进一步作到能够根据自己实际的需要对成熟的软件模块进行仿写、借代、适配性修改、拼装,在编程实践中逐步提高编程能力。引言(深入软硬件底层,以达到知其然知之所以然。)一、函数定义(一)函数的定义函数类型函数名(形式参数表)[reentrant][interruptm][usingn]{

局部变量定义 函数体}

前面部件称为函数的首部,后面称为函数的尾部,格式说明:

1.函数类型函数类型说明了函数返回值的类型。

2.函数名函数名是用户为自定义函数取的名字以便调用函数时使用。

3.形式参数表形式参数表用于列录在主调函数与被调用函数之间进行数据传递的形式参数。voiddelay02s(void) //一般函数定义 { unsignedchari,j,k; for(i=20;i>0;i--) for(j=20;j>0;j--) for(k=230;k>0;k--);}voiddelay02s(unsignedcharn)//带参数传递的函数 { unsignedchari,j,k; for(i=n;i>0;i--) for(j=20;j>0;j--) for(k=230;k>0;k--);}intmax(intx,inty)//带参数传递和有返回值的函数{ intz; z=x>y?x:y; returnz;}例程unsignedint

fac(unsignedintn)reentrant//递归调用必须设置为重置函数{ unsignedintresult;

if(n==0) result=1; else result=n*fac(n-1); return(result);}voidTIMER0_isr()interrupt0using1//中断函数{ count++;

if(count==20) { count=0; P2_0=!P2_0; //时间到反转电平

}}例程externintmax(intx,inty);voidmain(){intc;intx1=13,y1=-8;c=max(x1,y1);while(1);}intmax(intx,inty){intz;z=x>y?x:y;returnz;}fun1.cfun2.c例程externunsignedintx;externintmax(intx,inty);voidmain(){intc;intx1=x,y1=-8;c=max(x1,y1);while(1);}unsignedintx=13;intmax(intx,inty){intz;z=x>y?x:y;returnz;}fun1.cfun2.c例程(一)普通变量定义的格式

[存储类别]数据类型说明符

[存储器类型]变量名1[=初值],…;在C51中,变量在使用前必须对变量进行定义,指出变量的数据类型和存储模式。以便编译系统为它分配相应的存储单元。二、C51的变量

此部分需要关注与标准C不同的地方!1、变量的存储类别存储类别指的是数据在内存中存储的方式。存储类别具体有四种:---编译器默认为auto。

自动的(auto) 静态的(static) 寄存器的(register) 外部的(extern)

在C语言中,存储的方式分为两大类:

(1)静态存储:程序运行期间分配固定存储空间。(2)动态存储:程序运行期间根据需要动态分配存储空间。

数据类型长度值域bit1位0或1signedchar1字节-128~+127unsignedchar1字节0~255signedint2字节-32768~+32867unsignedint2字节0~65535signedlong4字节-2147483648~+2147483647unsignedlong4字节0~4294967295float4字节±1.176E-38~±3.40E+38指针1~3字节对象地址(物理地址)sbit1位0或1sfr1字节0~255sfr162字节0~655352、数据类型说明符3、c51扩展的存储器类型

----C51特有存储类型寻址空间数据长度(bit)值域范围bdata片内可位寻址的RAM(20H~2FH)10~127data片内直接寻址RAM(00~7FH)80~128idata片内间接寻址RAM(00~0FFH)80~255pdata分页寻址片外RAM(0000H~00FFH)80~255xdata片外RAM(64K)(0000H~0FFFFH)160~65535code片内、外统一编址ROM(64K)(0000H~0FFFFH)160~65535存储器类型映射图databdatacode外部程序空间

60KB内部4KBEA=1外部4KBEA=0外部数据存储器64KB0FFFH0000H0000H0FFFFH0FFFH0000H片内RAM(256B)片外RAM(64KB)0FFFFH1000H片内、外ROM(64KB)特殊功能寄存器SFR数据缓冲区(普通RAM区)80H00H1FH20H2FH30H7FH80H52子系列才有的扩展RAM区128B位地址区工作寄存器区0FFH00FFHidataxdatapdata0FFH例:变量定义存储种类和存储器类型相关情况。

unsignedchardata

varl;

//在片内RAM中的data区定义无符号字符型变量Var1

unsignedintidatavar2;

//在片内RAM中的idata区定义无符号整型变量Var2

externfloatxdatavar3;

//在片外RAM中的xdata区定义实型外部变量Var3

intcodevar4=5;

//在ROM空间定义整型变量var4并赋值4*/

unsignedcharbdatavar5;

//在片内RAM中的bdata区定义可字节处理和位处理的无符号字符型变量var5思考

inti;内部数据存储器外部数据存储器程序存储器省略存储器类型关键字定义的i被编译后会放在哪里????三种存储模式变量默认为data存储类型小模式变量默认为pdata存储类型中模式变量默认为xdata存储类型大模式缺省默认情况(二)变量的存储模式

---C51特有

(三)指针声明方式数据类型存储类型(指针指向位置)存储类型(指针存放位置)

*变量名

如:unsignedcharxdata*datap1;如:unsignedint

xdata*datap2;指向idata、data和pdata的存储器指针用1个字节保存

指向code和xdata的存储器指针用2个字节保存idata

、bdata、data、pdata、xdataidata

、bdata、data、code、pdata、xdata3个字节,通用型指针,未指明存储器空间

unsignedchar*point1; unsignedint*point2;2个字节,指向16位寻址的存储器空间

unsigned

int

code*point1; unsigned

int

xdata*point2;1个字节,指向8位寻址的存储器空间

unsigned

chardata*point1; unsigned

charidata*point2; unsigned

charpdata*point3;

采用指针的方法,可以实现在C51程序中对任意指定的存储器单元进行访问。显示指针与通用指针的对比描述idata指针xdata指针通用指针C源程序idatachar*ip;charval;val=*ip;xdatachar*xp;charval;val=*xp;char*p;charval;val=*p;编译后的汇编代码MOVR0,ipMOVval,@R0MOVDPL,xp+1MOVDPH,xpMOVXA,@DPTRMOVval,AMOVDPL,pMOVDPH,p+1MOVB,p+2LCALL__gptrget指针大小1字节2字节3字节代码长度4字节9字节11字节+库调用执行时间4周期7周期远大于13周期通用指针使用方便,但速度慢显式指针效率高、速度快,但寻址范围小例1:通过指针实现绝对地址的访问。typedefunsignedcharuchar;//定义符号uchar为数据类型符unsignedchartypedefunsignedint

uint;//定义符号uint为数据类型符unsignedintvoidmain(void){

uchardata*dp1;//定义一个指向data区的指针dp1

uintxdata*dp2;//定义一个指向xdata区的指针dp2 dp1=0x30;//dp1指针赋值,指向data区的30H单元

dp2=0x1000;//dp2指针赋值,指向xdata区的1000H单元 *dp1=0x55;//将数据0x55送到片外RAM30H单元 *dp2=0x1234;//将数据0x1234送到片外RAM1000H单元

while(1);}(二)特殊功能寄存器变量的定义---C51特有

定义后可实现C51中对特殊功能寄存器的访问databdata特殊功能寄存器sfr数据缓冲区(普通RAM区)80H00H1FH20H2FH30H7FH80H0FFH52子系列才有的RAM区位地址区工作寄存器区0FFH0FFHidata片内RAM(256B)

MSC-51系列包括多种寄存器,其中一些具有特殊功能,如定时器,端口的控制寄存器等,为了能够直接访问这些寄存器,C51编译器提供了一种定义的自主形式,这是必要的,因为这些定义与标准C语言是不兼容的。为了支持这些特殊功能寄存器(SFR)的声明,引入了关键词“sfr”,语法如下:

sfr

特殊功能寄存器名=地址;sfr16特殊功能寄存器名=地址;

//定义8051的8位寄存器:

sfrP0=0x80;

//定义8051的状态字寄存器P0,地址为0X80。

sfrP1=0x90;

//定义8051的状态字寄存器P1,地址为0X90。

sfrPSW=0xd0;

//定义8051的状态字寄存器PSW,地址为0XD0。

sfrSCON=0x98;

//定义8051的串行控制寄存器SCON,地址为0X98。

sfrTMOD=0x89;//定义8051的定时器模式寄存器TMOD,地址为0X89。

//定义8051的其他16位寄存器:sfr16DPTR=0x82;//sfrDPH=0X83sfrDPL=0X82

(二)特殊功能寄存器变量的定义---C51特有

定义后可实现C51中对特殊功能寄存器的访问例:sfrP0=0X80;sfrP1=0X90;sfr16DPTR=0X82;voidmain(void){ P0=0X55; P1=0X66; DPTR=0X1234;

while(1);}可以改成以下程序#include<regx51.h>sfr16DPTR=0X82;voidmain(void){ P0=0X55; P1=0X66; DPTR=0X1234;

while(1);}大家可以看看书上后面的单片机的程序,一般都包含有#include<regx51.h>(三)位变量的定义---C51特有

定以后实现C51中对位地址的访问databdata特殊功能寄存器sfr数据缓冲区(普通RAM区)80H00H1FH20H2FH30H7FH80H0FFH52子系列才有的RAM区位地址区工作寄存器区0FFH0FFHidata片内RAM(256B)低128字节RAM区—128个高128字节RAM区(SFR区)--83个

在C51中,允许用户通过位类型符定义位变量。位类型符有两个:bit和sbit。可以定义两种位变量。(1)bit位类型符用于定义一般的可位处理位变量。格式:bit位变量名;

在格式中可以加上各种修饰,但注意存储器类型只能是bdata、data、idata。只能是片内RAM的可位寻址区,严格来说只能是bdata。例:bit型变量的定义。

bitidataflag1; √

bitdataflag2; √

bitbdataflag3; √

bitpdataflag4; × bitxdataflag5; × bit*p ×

bitstring[5] ×

bitfunc(bita1,bita2)

√可以定义函数例1:

voidmain(void) { bitbdataflag1,flag2; flag1=0; flag2=1; while(1); }例2:

bitbdataflag1,flag2;voidmain(void) {

flag1=0; flag2=1; while(1); }低128字节RAM区—128个在典型的8051单片机应用问题中,经常需要单独访问SFR中的位,C51扩充功能使之成为可能,特殊位,象SFR一样,不与标准C语言兼容,使用保留字“sbit”可访问位寻址对象。与SFR声明一样,用保留字“sbit”声明某些特殊位接受符号名,“=”后语句将绝对值地址赋给变量名,这种地址分配有三种方法:方法1:sbit

变量名=sfr_name^int_constant

当字节是特殊功能寄存器的地址可用这个方法。sfr_name必须是已定义的SFR的名字,“^”后的语句定义了基地址上的特殊位的位置,该位置必须是一个0~7的数。例1: sfrPSW=0xD0;

sbitOV=PSW^2;

sbitCY=PSW^7;(2)sbit位类型符方法2:sbit变量名=int_constant^int_constant

这种方法以一整常数作基地址,该值必须在0x80~0xFF之间,并能被8整除,确定位的位置方法同上。 例2:sbitOV=0xD0^2;

sbitCV=0xD0^7;

方法3:sbit

变量名=int_constant----此方法最常用

这种方法是将位的绝对地址赋给变量,地址必须位于0x80~0xFF之间。 例3:sbitOV=0xD2;

sbitCY=0xD7;特殊功能位代表了一个独立的声明类,它不能与其它声明和位域互换。高128字节RAM区(SFR区)--83个例:sbitP0_0=0x80;

sbitP0_0=0X80^0;

sfrP0=0X80;

sbitP0_0=P0^0;

voidmain(void){ P0_0=0; P0_0=1; while(1);}方法一方法二方法三低128字节RAM区—128个unsignedcharbdataflag;sbitflag0=flag^0;voidmain(void){ flag=0x55; flag0=1; while(1);}---------------------------------unsignedint

bdataflag;sbitflag0=flag^15;voidmain(void){ flag=0x55; flag0=1; while(1);}

注意:在此区域不允许使用:

sbitflag0=0x20;或sbitflag0=0x24^0;三、C51绝对地址的访问databdatacode外部程序空间

60K内部4KEA=1外部4KEA=0外部数据存储器64KB0FFFH0000H0000H0FFFFH0FFFH0000H片内RAM(256B)片外RAM(64KB)0FFFFH1000H0FFFFH片内、外ROM(64KB)特殊功能寄存器sfr数据缓冲区(普通RAM区)80H00H1FH20H2FH30H7FH80H0FFH52子系列才有的RAM区位地址区工作寄存器区0FFH0FFH00FFHidataxdatapdata

C51编译器提供了一组宏定义来对51系列单片机的code、data、pdata和xdata空间进行绝对寻址。规定只能以无符号数方式访问,定义了8个宏定义,其函数原型如下:

#defineCBYTE((unsignedcharvolatilecode*)0)#defineDBYTE((unsignedcharvolatiledata*)0)#definePBYTE((unsignedcharvolatilepdata*)0)#defineXBYTE((unsignedcharvolatilexdata*)0)#defineCWORD((unsignedintvolatilecode*)0)#defineDWORD((unsignedintvolatiledata*)0)#definePWORD((unsignedintvolatilepdata*)0)#defineXWORD((unsignedintvolatilexdata*)0)

这些函数原型放在absacc.h文件中。使用时须用预处理命令把该头文件包含到文件中,形式为:#include<absacc.h>。(一)采用C51中的预定义宏的方式访问

例1:绝对地址对存储单元的访问#include<absacc.h>//将绝对地址头文件包含在文件中typedefunsignedcharuchar;typedefunsignedint

uint;voidmain(void){

ucharvar1;//定义变量var1

uintvar2;//定义变量var2

var1=XBYTE[0x0005];

//XBYTE[0x0005]访问片外RAM的0005字节单元

var2=XWORD[0x0002];//

XWORD[0x0002]实质是访问的是片外RAM的0002字单元

DBYTE[0x30]=0X55; XBYTE[0x0002]=0X66; DWORD[0x40]=0X1234; XWORD[0x0000]=0X1234; while(1);}(二)通过指针方式访问3个字节,通用型指针,未指明存储器空间

unsignedchar*point1; unsignedint*point2;2个字节,指向16位寻址的存储器空间

unsigned

int

code*point1; unsigned

int

xdata*point2;1个字节,指向8位寻址的存储器空间

unsigned

char

data*point1; unsigned

char

idata*point2; unsigned

char

pdata*point3;

采用指针的方法,可以实现在C51程序中对任意指定的存储器单元进行访问。例1:通过指针实现绝对地址的访问。typedefunsignedcharuchar;//定义符号uchar为数据类型符unsignedchartypedefunsignedint

uint;//定义符号uint为数据类型符unsignedintvoidmain(void){

uchardata*dp1;//定义一个指向data区的指针dp1

uintxdata*dp2;//定义一个指向xdata区的指针dp2 dp1=0x30;//dp1指针赋值,指向data区的30H单元

dp2=0x1000;//dp2指针赋值,指向xdata区的1000H单元 *dp1=0x55;//将数据0x55送到片外RAM30H单元 *dp2=0x1234;//将数据0x1234送到片外RAM1000H单元

while(1);}例2:通过指针实现绝对地址的访问。typedefunsignedcharuchar;typedefunsignedint

uint;

voidmain(void){

uchardatax;

uchar

idata*p1;//定义一个指向idata区的指针p1 p1=&x;//p1指针指向data区的x变量 *p1=0x55;//等价于给变量x赋值0x55 while(1);}例3:通过指针实现绝对地址的访问。typedefunsignedcharuchar;typedefunsignedint

uint;voidmain(void){

uchardatax=9,y;

uchar

idata*p1;//定义一个指向idata区的指针p1 p1=&x;//p1指针指向data区的x变量

y=*p1;//执行完后y的值位9 while(1);}例4:统计片外RAM中2000H地址开始的16个单元中0的个数,将统计个数存入片外的2100单元。typedefunsignedcharuchar;typedefunsignedint

uint;voidmain(void){

uint

n=0,i;

uchar

xdata*p=0x2000;//指针p指向xdata

区的2000H单元

for(i=0;i<16;i++) {

if(*p==0)n++;//若该单元内容为零,则n+1 p++; //指针指向下一单元

} p=0x2100; //指针p指向2100H单元

*p=n; //把个数放在2100H单元中

while(1);}

使用_at_

对指定的存储器空间的绝对地址进行访问。一般格式:数据类型说明符[存储器类型]变量名_at_地址常数;其中,存储器类型为data、

温馨提示

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

评论

0/150

提交评论