第七章单片机c51基础_第1页
第七章单片机c51基础_第2页
第七章单片机c51基础_第3页
第七章单片机c51基础_第4页
第七章单片机c51基础_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

第7章单片机C51基础7.1C51的程序结构7.2C51的数据结构7.3C51与汇编语言的混合编程7.4C51仿真开发环境7.5C51初步应用编程51汇编语言能直接操作单片机的系统硬件,指令执行速度快。但其程序可读性差,且编写、移植困难。

汇编语言的问题C51是为51系列单片机设计的一种C语言,其特点:C51语言已成为51系列单片机程序开发的主流软件方法。结构化语言,代码紧凑——效率可与汇编语言媲美接近真实语言,程序可读性强——易于调试、维护库函数丰富,编程工作量小——产品开发周期短机器级控制能力,功能很强——适合于嵌入式系统开发与汇编指令无关,易于掌握——在单片机基础上上手快C51的好处相同之处:语法规则、程序结构、编程方法差异之处:数据类型、存储模式、中断处理教学安排:①

介绍C51语言的数据结构及C51编程手段;②

介绍单片机I/O口的初步应用及C51编程方法。C51与标准C语言对比7.1C51的程序结构7.2C51的数据结构7.3MCS-51内部资源使用的C语言编程7.4C51与汇编语言的混合编程

1.在C51中调用汇编程序

2.C51中嵌入汇编代码7.5C51仿真开发环境7.6C51初步应用编程

7.1C51的程序结构Project(可包含若干程序文件)C51(库函数)LIB(库函数)(头文件)KeilC51(μVionsion3)Main(函数)File_1(*.c)Func_k(函数)…….………File_n(*.*)Func_1(函数)Func_n(函数)…….用户编程编译系统C51单片机软件系统结构①程序由函数组成(一个主函数,或一个主函数和若干自定义函数);②利用预处理命令对变量或函数进行集中定义或说明;③函数和变量都需遵循先定义后使用的基本原则;④主函数中的所有语句执行完毕,则程序结束。C51与标准C程序结构完全相同程序结构举例:LED闪烁控制功能预处理命令---------函数说明------------全局变量定义------

主函数------------调用函数------------局部变量定义---------

程序体

程序体------C51程序代码7.1C51的程序结构7.2C51的数据结构7.3MCS-51内部资源使用的C语言编程7.4C51与汇编语言的混合编程

1.在C51中调用汇编程序

2.C51中嵌入汇编代码7.5C51仿真开发环境7.6C51初步应用编程7.2C51的数据结构在程序执行过程中,数值可以发生改变的量称为变量。变量名与存储单元地址相对应,变量值与存储单元的内容相对应。例如在哈佛结构的存储空间中如何建立变量概念?1.C51的变量【存储种类】数据类型【存储类型】变量名存储地址(标准C)作用范围(标准C)*方括号项——可以缺省存储空间(C51特有)数据格式(C51扩充)C51变量定义的四个要素:

①自动变量(auto)——在函数内部定义的变量,退出函数后,分配给该变量的存储单元即自行消失(局部变量)。【存储种类】

数据类型【存储类型】变量名②外部变量(extern)——在函数外部定义的变量,可始终保持变量的数值(全局变量)。

【强调】一个外部变量只能被定义一次,在定义文件之外的地方使用时需用extern进行声明。③静态变量(static)——静态局部变量/静态全局变量④寄存器变量(register)——以寄存器为存储空间的变量*若省略存储种类选项,则变量默认为自动变量

存储种类举例:自动变量与外部变量的差异数据的不同格式叫做数据类型*有符号数类型可以忽略signed标识符标准C语言的数据类型【存储种类】

数据类型

【存储类型】变量名数据类型bit型用bit定义一个位变量,语法规则如下:bitbit_name

[=常数0~1];例如:bitdoor=0;//定义一个叫door的变量且初值为0注意:利用bit可以定义一个位变量或位函数,但不能定义位指针,也不能定义位数组。例如:

bitgate=0;

C51扩充数据类型:bit、sfr或sfr16、sbit

sfr定义特殊功能寄存器SFR,语法规则如下:

sfr

sfr16sfr_name=字节地址常数;Sfr或sfr16型例如,sfrP0=0x80;//定义P0口地址80H

sfrPCON=0x87;//定义PCON地址87H

sfr16DPTR=0x82;//定义DPTR的低端地址82H将SFR范围内的位地址(0x80~0xFF)定义为位变量序号特殊功能寄存器名称符号字节地址位地址sbit型

1)sbit

bit_name=

位地址常数;

将位于SFR字节地址内的绝对位地址定义为位变量名。例如,sbitCY=0xD7;

序号特殊功能寄存器名称符号字节地址位地址2)sbitbit_name=sfr_name^位位置;

将已有定义的SFR的0~7位定义为位变量名。

例如:sfrPSW=0xD0;sbitCY=PSW^7;

序号特殊功能寄存器名称符号字节地址位地址3)sbitbit_name=sfr字节地址

^位位置;

将SFR字节地址的相对位地址定义为位变量名。

例如:sbitCY=0xD0^7;

序号特殊功能寄存器名称符号字节地址位地址C51编译器在头文件“reg51.h”中定义了全部sfr/sfr16和sbit变量。用一条预处理命令#include<reg51.h>把这个头文件包含到C51程序中,无需重定义即可直接使用它们的名称。3.C51对存贮器和外接I/O口的绝对地址访问和定义①对存贮器的绝对地址访问利用绝对地址访问的头文件absacc.h可对不同的存贮区进行访问。该头文件的函数有:

CBYTE(访问code区字符型)DBYTE(访问data区字符型)PBYTE(访问pdata或I/O区字符型)XBYTE(访问xdata或I/O区字符型)

还有CWORD、DWORD、PWORD和XWORD四个函数,它们的访问区域同上,只是访问的类型为int型。例:#include<absacc.h>#definecomXBYTE[0x07ff]那么后面程序com变量出现的地方,就是对地址为07ffH的外部RAM或I/O口进行访问。

访问绝对地址例:XWORD[0]=0x9988;即将9988H(int类型)送入外部RAM的0号和1号单元。

使用中要注意:absacc.h一定要包含进程序,XWORD必须大写。

②对外部I/O口的访问

由于单片机的I/O口和外部RAM统一编址,因此对I/O口地址的访问可用XBYTE(MOVX@DPTR)或PBYTE(MOVX@Ri)进行。例:#include“absacc.h”

#definePAXBYTE[0xffec]//将PA定义为外部I/O口,地址0FFECH#defineNAMEDBYTE[0x40]//将NAME定义为片内RAM,地址40H

voidmain(void){PA=0x3a;NAME=0x01;}③对绝对地址的定义定义变量时,使用_at_关键词指定变量的绝对地址,格式为:

[存储类型]数据类型变量名_at_绝对地址;例:dataunsignedcharx1_at_0x40;//在data区定义字节变量x1,它的地址为40Hxdataunsignedintx2_at_0x2000;//在xdata区定义字变量x2,它的地址为2000Hvoidmain(void){x1=0xff;x2=0x1234;}

应用举例:51系列单片机有三个逻辑存储空间:【存储种类】数据类型

【存储类型】变量名片内数据存储器,片外数据存储器和程序存储器。存储类型80HFFH8052data区xdata区code区bdata区建立C51存储类型与存储空间的对应关系80HFFH8052idata区256B256B256B256B每一个256字节都是pdata区存储区

描述data片内RAM的低128字节,可在一个周期内直接寻址bdata片内RAM可按位寻址区idata片内RAM的高128字节,必须采用间接寻址,使用Ri间接寻址pdata片外RAM及接口区(256B),使用Ri间接寻址xdata片外RAM及接口区(64KB),使用DPTR间接寻址code程序存储区(64KB),使用DPTR寻址C51的存储类型与存储空间对应关系表三种默认存储类型与编译模式之间的关系: SMALL:参数及局部变量放入可直接寻址的片内RAM区,默认类型是DATA。COMPACT:参数及局部变量放入分页片外RAM区(最大256B),默认类型是PDATA。LARGE:参数及局部变量放入片外RAM区(最大64KB)

,默认类型是XDATA。C51编译器指定了三种默认存储类型:【存储种类】数据类型

【存储类型】

变量名C51编译器的三种编译模式:小编译模式(SMALL)紧凑编译模式(COMPACT)大编译模式(LARGE)变量名可以由字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线,变量名长度随编译系统而定。变量名具有字母大小写的敏感性,如SUM和sum代表不同的变量。强调:头文件中定义的变量都是大写的【存储种类】数据类型【存储类型】

变量名C51扩展的若干关键字一览表

变量名不得使用标准C语言和C51语言的关键字。unsignedchardatasystem_status=0;

//定义system_status为无符号字符型自动变量,该变量位于data区中且初值为0。数据结构定义举例变量名为system_status位于片内RAM区无符号字符型自动型初值为零unsignedcharbdatastatus_byte;

unsignedintcodeunit_id[2]={0x1234,0x89ab};

staticcharm,n;

//定义status_byte为无符号字符型自动变量,该变量位于bdata区//定义unit_id[2]为无符号整型自动变量,该变量位于code区中,是长度为2的数组,且初值为0x1234和0x89ab。//定义m和n为2个位于data区中的有符号字符型静态变量。7.1C51的程序结构

7.2C51的数据结构7.3MCS-51内部资源使用的C语言编程7.4C51与汇编语言的混合编程

1.在C51中调用汇编程序

2.C51中嵌入汇编代码7.5C51仿真开发环境7.6C51初步应用编程7.3MCS-51内部资源使用的C语言编程7.3MCS-51内部资源使用的C语言编程7.3.1中断应用的C语言编程

C51编译器支持在C源程序中直接开发中断程序。中断服务程序是通过按规定语法格式定义的一个函数。中断服务程序的函数定义的语法格式如下:

返回值函数名([参数])interruptm[usingn]{

}…MCS-51中断源编号编号中断源入口地址0外部中断00003H1定时器/计数器0000BH2外部中断10013H3定时器/计数器1001BH4串行口中断0023H

usingn

选项用于实现工作寄存器组的切换,n是中断服务子程序中选用的工作寄存器组号(0~3)。在许多情况下,响应中断时需保护有关现场信息,以便中断返回后,能使中断前的源程序从断点处继续正确地执行下去。这在MCS-51单片机中,能很方便地利用工作寄存器组的切换来实现。即在进入中断服务程序前的程序中使用一组工作寄存器,进入中断服务程序后,由"usingn"切换到另一组寄存器,中断返回后又恢复到原寄存器组。这样互相切换的两组寄存器中的内容彼此都没有被破坏。图7.5扩展多个中断源

例3

图7.5所示是利用优先权解码芯片,在单片机8051的一个外部中断INT1上扩展多个中断源的原理电路图。图中是以开关闭合来模拟中断请求信号。当有任一中断源产生中断请求,能给8051的INT1引脚送一个有效中断信号,由P1的低3位可得对应中断源的中断号。

在中断服务程序中仅设置标志,并保存I/O口输入状态。FranklinC51编译器提供定义特定MCS-51系列成员的寄存器头文件。MCS-51头文件为reg51.h。C51程序如下:#include<reg51.h>unsignedcharstatus;

bitflag;

voidservice_int1()interrupt2using2 /*INT1中断服务程序,使用第2组工 作寄存器*/{flag=1; /*设置标志*/status=p1; /*存输入口状态*/}voidmain(void){IP=0x04; /*置INT1为高优先级中断*/IE=0x84; /*INT1开中断,CPU开中断*/for(;;){if(flag) /*有中断*/{switch(status) /*根据中断源分支*/{case0:break; /*处理IN0*/case1:break; /*处理IN1*/case2:break; /*处理IN2*/case3:break; /*处理IN3*/default:;

}flag=0; /*处理完成清标志*/}}}7.3.2定时器/计数器(T/C)应用的C语言编程

例4

设单片机的fosc=12MHz晶振,要求在P1.0脚上输出周期为2ms的方波。周期为2ms的方波要求定时时间隔1ms,每次时间到P1.0取反。机器周期=12/fosc=1μs

需计数次数=1000/(12/fosc)=1000/1=1000

由于计数器是加1计数,为得到1000个计数之后的定时器溢出,必须给定时器置初值为65536-1000。(1)用定时器0的方式1编程,采用查询方式,程序如下:

#include<reg51.h>sbitP1_0=P1^0;

voidmain(void){TMOD=0x01; /*设置定时器1为非门控制方式1*/TR0=1; /*启动T/C0*/while(1){TH0=(64536/256); /*装载计数器初值*/TL0=(64536%256);

do{}while(!TF0); /*查询等待TF0置位*/P1_0=!P1_0; /*定时时间到P1.0反相*/TF0=0; /*软件清TF0*/}}(2)用定时器0的方式1编程,采用中断方式。程序如下:

#include<reg51.h>sbitP1_0=P1^0;

voidtime(void)interrupt1using1/*T/C0中断服务程序入口*/{P1_0=!P1_0; /*P1.0取反*/TH0=(64536/256); /*重新装载计数初值*/

TL0=(64536%256);

}voidmain(void){TMOD=0x01; /*T/C0工作在定时器非门控制方式1*/P1_0=0;

TH0=(64536/256); /*预置计数初值*/TL0=(64536%256);

ET0=1; /*T/C0中断开放*/EA=1; /*CPU中断开放*/TR0=1; /*启动T/C0开始定时*/do{}while(1); /*等待中断*/}

例5

采用10MHz晶振,在P1.0脚上输出周期为2.5s,占空比20%的脉冲信号。

10MHz晶振,使用定时器最大定时几十毫秒。取10ms定时,周期2.5s需250次中断,占空比20%,高电平应为50次中断。

10ms定时,晶振fosc=10MHz。需定时器计数次数=10×103×10/12=8333#include<reg51.h>#defineucharunsignedcharucharperiod=250;ucharhigh=50;uchartime=0;

timer0()interrupt1using1 /*T/C0中断服务程序*/{TH0=57203/256; /*重置计数值*/TL0=57203%256;if(++time==high)P1=0; /*高电平时间到变低*/elseif(time==period) /*周期时间到变高*/{time=0;P1=1;

}}main(){TMOD=0x01; /*定时器0方式1*/TH0=57203/256; /*预置计数初值*/TL0=57203%256;

ET0=1; /*开T/C0中断*/EA=1; /*开CPU中断*/TR0=1; /*启动T/C0*/do{}while(1);

}图7.6中断服务程序流程图7.1C51的程序结构

7.2C51的数据结构7.3MCS-51内部资源使用的C语言编程7.4C51与汇编语言的混合编程

1.在C51中调用汇编程序

2.C51中嵌入汇编代码7.5C51仿真开发环境7.6C51初步应用编程7.4C51与汇编语言的混合编程举例:在两个数据中选出较大的数据,并赋值给变量c。1.在C51中调用汇编函数//以下代码在main.c文件中实现charmax(chara,charb);//由汇编语言实现main(){chara=30,b=40,c;c=max(a,b);};以下代码在汇编语言文件max.asm中实现

PUBLIC

_MAX

DE SEGMENTCODE

RSEG DE_MAX:

MOV A,R7 ;取第一个参数 MOV 30H,R5;取第二个参数 CJNE A,30H,TAG SJMP EXITTAG:

JNC EXIT

MOV R7,30HEXIT:

RET END 1)程序的寻址,main.c中调用的max函数,如何与汇编文件中的相应代码对应起来;2)参数传递,main.c中传递给max()函数的参数a和b,存放在何处可使汇编程序能够获取到它们的值;3)返回值传递,汇编语言计算得到的结果,存放在何处可使C语言程序能够获取到。C51程序中调用汇编语言,需要解决三个问题:通过在汇编文件中定义同名的“函数”来实现。

1)程序的寻址问题c

温馨提示

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

评论

0/150

提交评论