89C51单片机C语言编程
教学课件PPT 89C51单片机的C51程序设计
程序存储器(64K字节)
对应MOVC @DPTR访问
可位寻址片内数据存储器(16字节,128位) 允许位和字节混合访问
间接寻址片内数据存储器(256字节)
可访问片内全部RAM空间
分页寻址片外数据存储器(256字节)
对应MOVX @R0访问
4.2 C51程序设计基础
C51存储类型定义举例:
unsigned char data x,y,z; /*在内部RAM区定义了3个无符号字节型变量x,y,z*/
40M/80M/100M,而且还有很多是单周期的。
4.2 C51程序设计基础
4.2.1 C51变量/常量存储类型
C51存储类型 对应89C51单片机存储器空间
data
直接寻址片内数据存储器(128字节)
xdata
片外数据存储器(64K字节)
说明 访问速度快 对应MOVX @DPTR访问
code bdata idata pdata
序号 语句
1
=
2
if
3
表达式1 ? 表达式2 : 表达式3
4
switch/case
5
while
6
do-while
7
for
8
函数
含义 赋值语句 条件语句 条件运算符 多分支语句 循环语句 循环语句 循环语句 模块化程序设计
4.2 C51程序设计基础
表4-6 常用语句
序号 语句
1
=
2
if
3
表达式1 ? 表达式2 : 表达式3
4.3 C51程序举例
例4:把外部数据RAM中从地址2000H单元开始的100个有符号 数逐一取出,若为正数则放回原单元,若为负数则求补后放回。
单片机89C51指令
MOV @Ri, direct;
0101 011i direct
(direct)
(Ri)
MOV @Ri, #data ;
0111 011I data
#data
(Ri)
Back
(Ri)表示 Ri 中的内容为指定的 RAM 单 元。 MOV 指令在片内存储器的操作功能如 图 3-6 示。
图 3-6 传送指令在片内存储器的操作功能
例如:将片内RAM 65H单元内容47H送A,可执
行指令“MOV A,@R0”。其中R0内容为65H。 如图所示:
以指令中所指定 的R0内容(65H) ① 为指针
数据存储器
R0
65H
地址
┋
② A 47H
将片内RAM 65H 单元内容47H送A
65H ┋
47H
BACK
5、变址寻址(基址寄存器+变址寄存器间接寻址)
@Ri
direct
Rn
#data
direct
将直接地址源 direct 所指出的片内存储单 元中内容传送到直接 地址目的 direct 所 指出的片内存储单元 中 将间接寻址 (Ri 为 R0 或 R1) 所得的片内RAM 单元内容传送到直接 地址 direct 所指出 的片内存储单元中 将立即数传送到直接 地址 direct 所指出 的片内存储单元中
如:(A)=78H,(R5)=47H,(70H)=F2H, 执行指令: MOV R5,A ;(A) R5, (R5)=78H MOV R5,70H ;(70H) R5, (R5)=F2H MOV R5,#A3H; A3H R5, (R5)=A3H 注意,在89C51指令系统中没有“MOV Rn”传送指令。
单片机实用教程_5 89C51单片机汇编语言程序设计
;除以100得百位数
;余数除以10得十位数 ;余数为个位数
5.4.2 分支结构程序设计 程序分支是通过条件转移指令实现的,满足条件 则进行程序转移,不满足条件就顺序执行程序。 分支程序又分为单分支和多分支结构。 通过条件判断实现单分支程序转移的指令有: JZ、JNZ、CJNE、DJNZ等。 以位状态作为条件进行程序分支的指令有: JC、JNC、JB、JNB、JBC等。 完成0, 1, 正, 负以及相等,不等作为条件判断。 多分支程序根据条件判断,分别转移去执行不 同的程序,有散转指令“JMP @A+DPTR” 。
第5章 89C51单片机 汇编语言程序设计
汇编语言进行程序设计是面向过程 设计的典型方法,也是程序设计最基本 的能力体现。本章介绍89C51汇编语言 程序设计的方法和一些实用程序。
5.1 汇编语言语句的类型和组成 5.1.1 汇编语言
汇编语言: 用指令的助记符、符号地址、标号等符 号书写程序的编程语言。 源程序: 用汇编语言编写的程序为汇编语言源程序.
[标号:] 操作码 [目的操作数, 源操作数] [;注释]
其中: 方括号[ ]的部分为可选项, 可有可无, 随指令而异. 字段之间要用分隔符(空格,冒号,逗号,分号)分开.
⑴. 标号
标号位于语句的开始, 代表该语句的地址(符号地址) 标号由1-8个字母和数字组成, 由字母打头, 以冒号结 尾。不能使用指令助记符、寄存器名、伪指令等。 每个语句标号可用可不用。转移指令可以标号作为 指令的目标地址, 汇编中自动计算出转移的偏移量。 标号可以用赋值伪指令来赋值。
ORG 0000H LJMP CMPT ORG 1000H CMPT: MOV A,30H JNB ACC.7,NCH MOV C,ACC .7 CPL A ADD A,#1 MOV ACC.7,C NCH: MOV 31H,A SJMP $ END
第4章89C51汇编语言程序的设计与调试
汇编语言程序设计举例
程序设计方法和技巧
1. 程序设计的一般步骤 (1) 分析工作任务,明确要达到的工作目的、技术指标等。 (2) 确定解决问题的算法。算法就是如何将实际问题转化成程序模块来处理, 要对不同的算法进行分析、比较,找出最适宜的算法。 (3) 画程序流程图。其图形的符号规定均与高级语言流程图相同,如桶形框 表示程序的开始或结束,矩形框表示需要进行的工作,菱形框表示需要 判断的事情,指向线表示程序的流向等。 (4) 分配内存工作单元,确定程序与数据的存放地址。 (5) 编写源程序。 (6) 上机调试、修改源程序。
2. 汇编语言(Assembly Language) 汇编语言是一种用助记符来表示的面向机器的程序设计 语言。不同的机器所使用的汇编语言一般是不同的。但计 算机的CPU不能直接识别汇编语言,所以计算机不能立即执 行汇编语言程序。用汇编语言编写的源程序,在由计算机 执行之前,必须将它翻译成机器语言程序。 特点:这种语言弥补了机器语言的不足,用汇编语言编写程序 比用机器语言方便、直观、易懂、易用、易记。可以编写 出结构紧凑、运行时间精确的程序。所以,这种语言非常 适合于实时控制的需要。
2.程序设计的一般原则 按照尽可能使程序简短和缩短运行时间两个原则编写程序。 应用程序一般都由一个主程序(包括若干个功能模块)和多个子程序构 成,即采用模块化的程序设计方法。 每一功能模块或子程序都能完成一个明确的任务,实现某个具体功能, 如检测输入信号、码制转换、输出控制信号、发送数据、接收数据、 延时、显示、打印等。 3. 模块化程序设计方法的特点 单个模块结构的程序功能单一,易于编写、调试和修改。 对程序的局部修改,可以使无关的部分保持不变。 程序可读性好,便于功能扩展和版本升级。 对于使用频繁的子程序可以建立子程序库,便于多个模块调用。 可实现多人同时进行程序的编写和调试工作,缩短程序编写时间。
c单片机C语言编写的PWM程序
89c51单片机C语言编写的PWM程序PWM, 单片机, C语言, 程序, 编写分享到:新浪微博 QQ空间开心网人人网说明:本程序使用STC89C52RC单片机,22.1184MHz晶振,要使用本程序需要自己修改,我是用来控制直流电机的,外接了L298驱动电路,有问题或意见请回复,谢谢^_^#include "reg52.H"#include "MyType.h"//=============L298端口定义===============sbit ENA = P3^6;?//左轮驱动使能sbit IN1 = P0^3;?//左轮黑线(-)sbit IN2 = P0^4;?//左轮红线(+)sbit IN3 = P0^5;?//右轮红线(-)sbit IN4 = P0^6;?//右轮黑线(+)sbit ENB = P3^7;?//右轮驱动使能//=============PWM================#define PWM_COUST 100?//PWM细分等份uchar MOTO_speed1;??//左边电机转速uchar MOTO_speed2; ??//右边电机转速uchar PWM_abs1;???//左边电机取绝对值后占空比uchar PWM_abs2;???//左边电机取绝对值后占空比?uchar PWM_var1=20;??//左边电机直走速度(不同的电机,此参数不同)uchar PWM_var2=20;??//右边电机直走速度uchar PWMAnd = 0;??//PWM自增变量/****************************************************************** 名称:motor(char speed1,char speed2);功能:同时调节电机的转速参数:speed1:电机1的PWM值;speed2:电机2的PWM值?? speed>0.正转;speed<0.反转(-100~100)调用:extern int abs(int val); 取绝对值返回:/******************************************************************/ void motor(char speed1,char speed2){??//==============左边电机=============?if (speed1>0)??{??IN1 =0;IN2 =1;//正转??}???else if (speed1<0)??{??IN1 =1;IN2 =0;//反转??}?//==============右边电机=============?if (speed2>0)??{??IN3 =1;IN4 =0;//正转??}?else if (speed2<0)??{??IN3 =0;IN4 =1;//反转??}}/******************************************************************名称:motor_PWM();功能:PWM占空比输出参数:无调用:无返回:无/******************************************************************/void motor_PWM (){?uchar PWM_abs1;?uchar PWM_abs2;?PWM_abs1=MOTO_speed1;?PWM_abs2=MOTO_speed2;?if (PWM_abs1>PWMAnd) ENA=1;??? //左边电机占空比输出??else ENA=0;?if (PWM_abs2>PWMAnd) ENB=1;??? //右边电机占空比输出??else ENB=0;?if (PWMAnd>=PWM_COUST) PWMAnd=0;? //PWM计数清零??else PWMAnd+=1;}???/******************************************************************名称:void TIME_Init ();功能:定时器初始化指令:调用:无返回:无/******************************************************************/void TIME_Init ()?{//=========定时器T2初始化 PWM==================?T2CON = 0x00;? ?T2MOD = 0x00;? ?RCAP2H = 0xff;?//定时0.1ms? ?RCAP2L = 0x47;? ?TH2 = 0xff;? ?TL2 = 0x47;?ET2 = 1;??//定时器2中断开?TR2 = 1;??//PWM定时器关,PWM周期为10ms?}/******************************************************************名称:void PWM_Time2 () interrupt 5功能:T2中断,PWM控制参数:调用:motor_PWM();//PWM占空比输出返回:/******************************************************************/?void PWM_Time2 () interrupt 5{? ?TR2 = 0;?TF2 = 0;?ET2 = 0;?//定时器0中断禁止?motor_PWM();//PWM占空比输出?ET2 = 1;?//定时中断0开启?TR2 = 1;}main(){TIME_Init ()?;motor(50,50);//左右电机的转速都是50}。
st89c51单片机内部Eeprom编程源代码
// 外部函数列表:
extern void SectorErase(uint sector_addr); // 扇区擦除
extern uchar byte_read(uint byte_addr); // byte读
extern void byte_write(uint byte_addr, uchar original_data); // byte写
====================================================================================== */
#include "src51rd.h"
#include <intrins.h>
#define uchar unsigned char
ISPgoon(); /* 触发执行 */
/* 开始读,没有在此重复给地址,地址不会被自动改变 */
ISP_DATA = 0x00; /* 清数据传递寄存器 */
ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */
ISP_CMD = ISP_CMD | RdCommand; /* 读命令1 */
说明:本文为st89c51单片机内部Eeprom的应用,源代码都有详细讲解,大家建立一个C文件后,复制进去稍微做一些地址改动就可以用了,
有什么问题请留言,我本人已经调试通过,非常好用
代码一:文件54rdEeprom.c
/*=======================================================================================
89c51单片机汇编语言
89c51单片机汇编语言1.引言概述部分的内容可以介绍本文的主题:89C51单片机汇编语言。
该部分可以简要说明单片机的概念和应用领域,并强调本文将重点介绍汇编语言在89C51单片机中的应用和相关原理。
以下是一个示例:引言1.1 概述单片机是一种嵌入式系统中常用的微型计算机。
它具备微处理器、存储器、输入输出接口等核心部件,并通过时钟信号实现对不同外设的控制。
作为一种低成本、体积小、功耗低的控制器,单片机广泛应用于各个领域,如家电、通信、工业自动化等。
本文着重介绍了89C51单片机的汇编语言编程。
汇编语言是一种低级语言,直接操作底层硬件,非常适合在单片机上进行程序开发。
本文旨在帮助读者理解汇编语言在89C51单片机中的运行原理和应用场景。
首先,将会对89C51单片机进行详细介绍,包括其基本特性、内部结构和常见的应用领域。
然后,将会对汇编语言的基础知识进行解析,包括指令系统、寄存器和内存的使用方法等相关内容。
通过本文的学习,读者将能够掌握如何使用汇编语言编写简单的单片机程序,并了解如何利用89C51单片机进行各种实际应用的开发。
本文的结论将对所学内容进行总结,并对未来的学习和应用提出展望。
通过深入学习和实践,读者可以不仅仅掌握汇编语言的编程技巧,还能够开发出更加复杂和实用的单片机应用。
希望本文能够对读者在89C51单片机的汇编语言编程方面提供有价值的指导和帮助。
让我们开始探索吧!1.2 文章结构文章结构部分主要介绍了本文的组织结构和各章节的内容概述。
正文中介绍了89C51单片机的基本知识,以及汇编语言的基础知识。
结论部分总结了本文的主要观点,并展望了相关领域的发展方向。
在本文中,我们首先会在引言部分进行概述,介绍本文的总体内容和目的。
其次,在正文部分的第2.1节中,我们将详细介绍89C51单片机的基本知识,包括其特点、应用领域以及与其他单片机的比较等内容。
在第2.2节中,我们将深入讲解汇编语言的基础,包括指令集、寄存器、数据传送等重要概念和操作方法。
AT89C51单片机编程
{ while ((p34&&p35) ! = 0); delay( ); if ((p34&p35) != 0 ) continue; else break; }
/* 下列语句分析被按下的键所在的列号 */ mask = 0xfe; while (1)
{ TI = 0; SBUF = mask; while(TI = = 0); if((p34&&p35) ! = 0)
7.5.2
•
模块设计原则
若我们把复杂的问题分解成许多容易解决的小问题,复 杂的问题也就容易解决了。但是如果只是简单地分解任务, 不注意对一些子任务的归纳与抽象,不注意模块之间的关系, 往往会使模块数太多,模块之间的关系变得复杂,从而使程 序的调试、修改变得更加复杂。一般说来,模块设计应该遵 从以下几条原则: (1)模块独立 模块的独立性原则应保证模块完成独立的功能,模块与 模块之间关系简单,修改某一模块,不会造成整个程序的混 乱。保证模块的独立性应注意以下几点: ①每个模块完成一个相对独立的特定功能。在对任务分 解时,要注意对问题的综合。 ②模块之间的关系力求简单。例如:模块之间最好只通 过数据传递发生联系,而不发生控制关系。 C 语言中禁止 goto语句作用到另一函数,就是为了保证函数的独立性。
带寄存器参数的函数名加入“ _” 字符前缀,表明这类 函数包含寄存器的参数传递 对于重入函数加上“_?”字符串前缀,表明这类函数包 含栈内的参数传递
void func(void)
_FUNC
void func(void) reentrant
_?FUNC
例2 用汇编语言编写函数"toupper",参数传递发生在寄存器R7中。
c单片机C语言编写的PWM程序
89c51单片机C语言编写的PWM程序PWM, 单片机, C语言, 程序, 编写分享到:新浪微博 QQ空间开心网人人网说明:本程序使用STC89C52RC单片机,22.1184MHz晶振,要使用本程序需要自己修改,我是用来控制直流电机的,外接了L298驱动电路,有问题或意见请回复,谢谢^_^#include "reg52.H"#include "MyType.h"//=============L298端口定义===============sbit ENA = P3^6;?//左轮驱动使能sbit IN1 = P0^3;?//左轮黑线(-)sbit IN2 = P0^4;?//左轮红线(+)sbit IN3 = P0^5;?//右轮红线(-)sbit IN4 = P0^6;?//右轮黑线(+)sbit ENB = P3^7;?//右轮驱动使能//=============PWM================#define PWM_COUST 100?//PWM细分等份uchar MOTO_speed1;??//左边电机转速uchar MOTO_speed2; ??//右边电机转速uchar PWM_abs1;???//左边电机取绝对值后占空比uchar PWM_abs2;???//左边电机取绝对值后占空比?uchar PWM_var1=20;??//左边电机直走速度(不同的电机,此参数不同)uchar PWM_var2=20;??//右边电机直走速度uchar PWMAnd = 0;??//PWM自增变量/****************************************************************** 名称:motor(char speed1,char speed2);功能:同时调节电机的转速参数:speed1:电机1的PWM值;speed2:电机2的PWM值?? speed>0.正转;speed<0.反转(-100~100)调用:extern int abs(int val); 取绝对值返回:/******************************************************************/ void motor(char speed1,char speed2){??//==============左边电机=============?if (speed1>0)??{??IN1 =0;IN2 =1;//正转??}???else if (speed1<0)??{??IN1 =1;IN2 =0;//反转??}?//==============右边电机=============?if (speed2>0)??{??IN3 =1;IN4 =0;//正转??}?else if (speed2<0)??{??IN3 =0;IN4 =1;//反转??}}/******************************************************************名称:motor_PWM();功能:PWM占空比输出参数:无调用:无返回:无/******************************************************************/void motor_PWM (){?uchar PWM_abs1;?uchar PWM_abs2;?PWM_abs1=MOTO_speed1;?PWM_abs2=MOTO_speed2;?if (PWM_abs1>PWMAnd) ENA=1;??? //左边电机占空比输出??else ENA=0;?if (PWM_abs2>PWMAnd) ENB=1;??? //右边电机占空比输出??else ENB=0;?if (PWMAnd>=PWM_COUST) PWMAnd=0;? //PWM计数清零??else PWMAnd+=1;}???/******************************************************************名称:void TIME_Init ();功能:定时器初始化指令:调用:无返回:无/******************************************************************/void TIME_Init ()?{//=========定时器T2初始化 PWM==================?T2CON = 0x00;? ?T2MOD = 0x00;? ?RCAP2H = 0xff;?//定时0.1ms? ?RCAP2L = 0x47;? ?TH2 = 0xff;? ?TL2 = 0x47;?ET2 = 1;??//定时器2中断开?TR2 = 1;??//PWM定时器关,PWM周期为10ms?}/******************************************************************名称:void PWM_Time2 () interrupt 5功能:T2中断,PWM控制参数:调用:motor_PWM();//PWM占空比输出返回:/******************************************************************/?void PWM_Time2 () interrupt 5{? ?TR2 = 0;?TF2 = 0;?ET2 = 0;?//定时器0中断禁止?motor_PWM();//PWM占空比输出?ET2 = 1;?//定时中断0开启?TR2 = 1;}main(){TIME_Init ()?;motor(50,50);//左右电机的转速都是50}。
89C51单片机的串口通信编程1
89C51单片机的串口通信编程1一、pc机上的串口通信编程过程如下:1.建立项目打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest(与我源代码一致,等会你会方便一点);2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX 控件出现在列表框中。
选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。
(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX 就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。
3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #include "mscomm.h" //}}AFX_INCLUDES (这时运行程序,如果有错,那就再从头开始)。
4.在对话框中添加控件向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。
第4章89C51单片机汇编语言程序设计知识2010
(2)特殊功能寄存器:21个SFR的名字。
(3)标号名:赋值标号—由汇编指令EQU等赋值的标号;指令标号—指 令标号指示的指令的第一字节地址是该标号的值。
(4)常数:可用二进制(B)、十进制、十六进制(H),若常数以字符 开头,前面加0。
(5)$:用来表示程序计数器的当前值。
如:JNB TF0,$
例4-4:片内RAM30H单元开始有10个字节的二进制 数。编一子程序,求它们的和(设和小于256), 将和存入20H单元中。
ORG 1000H MOV R0,#30H CLR A MOV R7,#10 CLR C LOOP:ADDC A,@R0 INC R0 DJNZ R7,LOOP MOV 20H,A RET
4、DATA伪指令在程序中用来定义数据地址。
DB
定义字节命令
格式:DB(项或项表)
功能:通知汇编程序从当前ROM地址开始,保留一个 字或字节串的存储单元,并存入DB后的数据。
注意:项或项表可以是一个字节,用逗号隔开的字 节串或括在单引号中的ASCII字符串。 例如:
DB
定义字节命令
置初值
循环体
置初值
完
循环控制 退出循环
循环修改
未完
循环体
未完
循环控制
完
退出循环
循环修改
(a)
图4-2
(b) 循环组织方式流程图
例4-3:统计字串长度。内存从STRING开始有一字串, 该字串以$结束,试统计该字串长度,结果存于NUM单 元中。(条件控制循环结构)
程序如下: NUM STRING CLR MOV LOOP:CJNE SJMP NEXT:INC INC SJMP COMP:MOV DATA 20H DATA 21H
89C51单片机C语言编程
第三章单片机C语言程序设计一.C语言的特点1. 语言简洁、紧凑,使用方便、灵活。
2. 运算符丰富。
3. 数据结构丰富。
具有现代化语言的各种数据结构。
4. 可进行结构化程序设计。
5. 可以直接对计算机硬件进行操作。
6. 生成的目标代码质量高,程序执行效率高。
7. 可移植性好。
C语言程序采用函数结构,每个C语言程序由一个或多个函数组成,在这些函数中至少应包含一个主函数main(),也可以包含一个main()函数和若干个其它的功能函数。
不管main()函数放于何处,程序总是从main() 函数开始执行,执行到main()函数结束则结束。
在main()函数中调用其它函数,其它函数也可以相互调用, fimain()函数只能调用其它的功能函数,而不能被其它的函数所调用。
功能函数可以是C语言编译器提供的库函数,也可以是由用户定义的自定义函数。
在编制C程序时,程序的开始部分一般是预处理命令、函数说明和变量定义等。
用C 语言编写89C51单片机程序与用汇编语言编写 9C51单片机程序不一样。
用汇编语言编写89C51单片机程序必须要考虑其存储器结构,尤其必须考虑其片内数据存储器与特殊功能 寄存器的使用以及按实际地址处理端口数据o用C 语言编写的89C51单片机应用程序,则不用像 汇编语言那样须具体组织、分配存储器资源和处理端口必须要与单片机的存储结构相关联,否则编译器不能正 确地映射定位。
数据,但在C,C语言编写单片机应用程序时,需根据单片机存储结构及内部资源定义相应的数据类型和变量,而标准的C语言程序不需要考虑这些问题;C54包含的数据类型、变量存储模式、输入输出处理、函数等方面与标准的C语言有一定的区别。
其它的语法规则、程序结构及程序设计方法等与标准的C语言程序设计相同。
现在支持89C51系列单片机的C语言编译器有很多种,女0American Automation> Avocet、BSO/TASKING、DUNFIELD SHAREWARE>KEIL/Franklin等。
!!89C51汇编语言程序的设计与调试
(2)长调用指令:LCALL addr16;
3.注意设置堆栈指针和现场保护
4.最后一条指令必须是RET指令 5.子程序可以嵌套,即子程序可以调用子程序 6.在子程序调用时,还要注意参数传递的问题 2. 子程序的基本结构
MAIN:
┇
┇ LCALL ┇ ┇ SUB
;MAIN为主程序或调用程序标号
;调用子程序SUB
两条查表指令如下:
⑴ MOVC
⑵ MOVC MOVC A,@A+DPTR
A,@A+DPTR
A,@A+PC
完成把A中的内容作为一个无符号数与DPTR中的内容相加,所得 结果为某一程序存储单元的地址,然后把该地址单元中的内
容送到累加器A中。
MOVC A,@A+PC 以PC作为基址寄存器,PC的内容和A的内容作为无符号数,相加 后所得的数作为某一程序存储器单元的地址,根据地址取
反汇编——分析现成产品的程序,要将二进制的机器代码语言 程序翻译成汇编语言源程序。
4.3
4.3.1
汇编语言实用程序设计
汇编语言程序的基本结构
常采用以下几种基本结构: 顺序结构、分支结构和循环结构,再加上广泛使用的子程序和 中断服务子程序。
1.顺序结构
2.分支结构 程序中含有转移指令, 无条件分支,有条件分支。 有条件分支又分为:单分支结构和多分支结构。 3.循环结构 4.子程序 5.中断服务子程序
(4)操作数字段和注释字段之间的分界符用分号“;”相隔。
操作码字段为必选项,其余各段为任选项。 例4-1 下面是一段汇编语言程序的四分段书写格式
标号字段
操作码字段
操作数字段
注释字段
START:
MOV
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.1.2 C语言与89C51单片机
用C语言编写89C51单片机程序与用汇编语言编写 89C51单片机程序不一样。 用汇编语言编写89C51单片机程序必须要考虑其存 储器结构,尤其必须考虑其片内数据存储器与特殊功能 寄存器的使用以及按实际地址处理端口数据。 用C语言编写的89C51单片机应用程序,则不用像 汇编语言那样须具体组织、分配存储器资源和处理端口 数据,但在C语言编程中,对数据类型与变量的定义, 必须要与单片机的存储结构相关联,否则编译器不能正 确地映射定位。
【例】变量定义存储种类和存储器类型相关情况。 char data varl; /*在片内RAM低128B定义用直接寻 址方式访问的字符型变量var1*/ int idata var2; /*在片内RAM256B定义用间接寻址 方式访问的整型变量var2*/ auto unsigned long data var3; /*在片内 RAM128B定义用直接寻址方式访问的自动无符号长整型变量 var3*/ extern float xdata var4; /*在片外RAM64KB空间 定义用间接寻址方式访问的外部实型变量var4*/ int code var5; /*在ROM空间定义整型变量var5*/ unsign char bdata var6; /*在片内RAM位寻址区 20H~2FH单元定义可字节处理和位处理的无符号字符型变量 var6*/
[存储种类] 数据类型说明符 [存储器类型] 变量 名1[=初值],变量名2[初值]…;
三.存储种类 存储种类是指变量在程序执行过程中的作用范围。 C51变量的存储种类有四种,分别是自动(auto)、外 部(extern)、静态(static)和寄存器(register)。 1.auto: 使用auto定义的变量称为自动变量,其作用范围 在定义它的函数体或复合语句内部,当定义它的函数 体或复合语句执行时,C51才为该变量分配内存空间, 结束时占用的内存空间释放。自动变量一般分配在内 存的堆栈空间中。定义变量时,如果省略存储种类, 则该变量默认为自动(auto)变量。
3.2 C51的数据类型
C51的数据类型分为基本数据类型和组合数据类 型,情况与标准C中的数据类型基本相同,但其中 char型与short型相同,float型与double型相同,另 外,C51中还有专门针对于89C51单片机的特殊功能 寄存器型和位类型。
特殊功能寄存器型 这是C51扩充的数据类型,用于访问89C51单片机 中的特殊功能寄存器数据,它分sfr和sfr16两种类型。 其中: sfr为字节型特殊功能寄存器类型,占一个内存单元, 利用它可以访问89C51内部的所有特殊功能寄存器; sfr16为双字节型特殊功能寄存器类型,占用两个字 节单元,利用它可以访问89C51内部的所有两个字节的 特殊功能寄存器。 在C51中对特殊功能寄存器的访问必须先用sfr或 sfr16进行声明。
4.register: 使用register定义的变量称为寄存器变量。它定义 的变量存放在CPU内部的寄存器中,处理速度快,但
数目少。C51编译器编译时能自动识别程序中使用频率
最高的变量,并自动将其作为寄存器变量,用户可以无 需专门声明。
四.存储器类型 存储器类型是用于指明变量所处的单片机的存储器 定义变量时也可以省“存储器类型”,省时C51编 区域情况。存储器类型与存储种类完全不同。C51编译 译器将按编译模式默认存储器类型,具体编译模式的情 器能识别的存储器类型有以下几种,见表所示。 况在后面介绍。
(3)C51变量的存储模式与标准C中变量的存储模式 不一样,C51中变量的存储模式是与89C51单片机的 存储器紧密相关; (4)C51与标准C的输入输出处理不一样,C51中的 输入输出是通过89C51串行口来完成的,输入输出指 令执行前必须要对串行口进行初始化; (5)C51与标准C在函数使用方面也有一定的区别, C51中有专门的中断函数。
3.3.1 常量 常量是指在程序执行过程中其值不能改变的量。在 C51中支持整型常量、浮点型常量、字符型常量和字符串 型常量。
3.3 C51的运算量
3.3.2 变量 变量是在程序运行过程中其值可以改变的量。一 个变量由两部分组成:变量名和变量值。 在C51中,变量在使用前必须对变量进行定义, 指出变量的数据类型和存储模式。以便编译系统为它 分配相应的存储单元。定义的格式如下:
六.位变量 在C51中,允许用户通过位类型符定义位变量。位 类型符有两个:bit和sbit。可以定义两种位变量。 bit位类型符用于定义一般的可位处理位变量。它的 格式如下: bit 位变量名; 在格式中可以加上各种修饰,但注意存储器类型只 能是bdata、data、idata。只能是片内RAM的可位寻址 区,严格来说只能是bdata。 【例】 bit型变量的定义。 bit data a1; /*正确*/ bit bdata a2; /*正确*/ bit pdata a3; /*错误*/ bit xdata a4; /*错误*/
二.C语言的程序结构
C语言程序采用函数结构,每个C语言程序由一个 或多个函数组成,在这些函数中至少应包含一个主函数 main(),也可以包含一个main()函数和若干个其它的功 能函数。不管main()函数放于何处,程序总是从main() 函数开始执行,执行到main()函数结束则结束。在 main()函数中调用其它函数,其它函数也可以相互调用, 但main()函数只能调用其它的功能函数,而不能被其它 的函数所调用。 功能函数可以是C语言编译器提供的库函数,也可 以是由用户定义的自定义函数。在编制C程序时,程序 的开始部分一般是预处理命令、函数说明和变量定义等。
用C语言编写单片机应用程序与标准的C语言程序 也有相应的区别:
C语言编写单片机应用程序时,需根据单片机存储 结构及内部资源定义相应的数据类型和变量,而标准的 C语言程序不需要考虑这些问题;
C51包含的数据类型、变量存储模式、输入输出处 理、函数等方面与标准的C语言有一定的区别。其它的 语法规则、程序结构及程序设计方法等与标准的C语言 程序设计相同。
-32768~+32767
0~4294967295 -2147483648~+2147483647
float
bit sbit
4字节
1位 1位
1.175494E-38~3.402823E+38
0或1 0或1
sfr
sfr16
1字节
2字节
0~255
0~65535
在C51语言程序中,有可能会出现在运算中数据类型 不一致的情况。C51允许任何标准数据类型的隐式转换, 隐式转换的优先级顺序如下: bitcharintlongfloat signedunsigned 也就是说,当char型与int型进行运算时,先自动对 char型扩展为int型,然后与int型进行运算,运算结果为 int型。C51除了支持隐式类型转换外,还可以通过强制类 型转换符“()”对数据类型进行人为的强制转换。 C5l编译器除了能支持以上这些基本数据类型之外, 还能支持一些复杂的组合型数据类型,如数组类型、指 针类型、结构类型、联合类型等这些复杂的数据类型, 在后面将相继介绍。
3.1.3 C51程序结构
C51的语法规定、程序结构及程序设计方法都与标 准的C语言程序设计相同,但C51程序与标准的C程序在 以下几个方面不一样: (1)C51中定义的库函数和标准C语言定义的库函数 不同。标准的C语言定义的库函数是按通用微型计算机 来定义的,而C51中的库函数是按89C51单片机相应情 况来定义的; (2)C51中的数据类型与标准C的数据类型也有一定 的区别,在C51中还增加了几种针对89C51单片机特有 的数据类型;
存储器类型
data bdata idata pdata xdata code
描 述 直接寻址的片内RAM低128B,访问速度快
片内RAM的可位寻址区(20H~2FH),允许字节和 位混合访问
间接寻址访问的片内RAM,允许访问全部片内RAM
用Ri间接访问的片外RAM的低256B 用DPTR间接访问的片外RAM,允许访问全部64k片 外RAM 程序存储器ROM 64k空间
KEIL C51编译器能够识别的基本数据类型:
基本数据类型 长度 取值范围
unsigned char
signed char unsigned int
1字节
1字节 2字节
0~255
-128~+127 0~65535
signed int
unsigned long signed long
2字节
4字节 4字节
2.extern: 使用extern定义的变量称为外部变量。在一个函数体内, 要使用一个已在该函数体外或别的程序中定义过的外部变量 时,该变量在该函数体内要用extern说明。外部变量被定义 后分配固定的内存空间,在程序整个执行时间内都有效,直 到程序结束才释放。 3.static: 使用static定义的变量称为静态变量。它又分为内部静 态变量和外部静态变量。在函数体内部定义的静态变量为内 部静态变量,它在对应的函数体内有效,一直存在,但在函 数体外不可见,这样不仅使变量在定义它的函数体外被保护, 还可以实现当离开函数时值不被改变。外部静态变量上在函 数外部定义的静态变量。它在程序中一直存在,但在定义的 范围之外是不可见的。如在多文件或多模块处理中,外部静 态变量只在文件内部或模块内部有效。
【例】sbit型变量的定义: sbit OV=0xd2; sbit位类型符用于定义在可位寻址字节或特殊功能 sbit CY=oxd7; 寄存器中的位,定义时须指明其位地址,可以是位直接 unsigned char bdata flag; 地址,可以是可位寻址变量带位号,也可以是特殊功能 sbit flag0=flag^0; 寄存器名带位号。格式如下: P1=0x90; sfr sbit 位变量名=位地址; P1_0=P1^0; sbit sbit P1_1=P1^1; 如位地址为位直接地址,其取值范围为0x00~0xff; sbit P1_2=P1^2; 如位地址是可位寻址变量带位号或特殊功能寄存器名带 sbit P1_3=P1^3; 位号,则在它前面须对可位寻址变量或特殊功能寄存器 sbit P1_4=P1^4; 进行定义。字节地址与位号之间、特殊功能寄存器与位 号之间一般用“^”作间隔。 sbit P1_5=P1^5; sbit P1_6=P1^6; sbit P1_7=P1^7;