【51单片机系列】C51基础

本文内容是关于C51语言的基础内容的,包括C51的数据类型、变量、运算符、函数以及reg52.h文件中的内容,有些与C中相同的内容没有记录在此,比如常量、某些变量、表达式、程序结构、数组等没有涉及。

文章目录

  • C51的数据类型
    • 1. C51中的基本数据类型
    • 2. 指针类型
    • 3. 特殊功能寄存器类型
    • 4. 位类型
  • C51的变量
    • 1. 存储种类
    • 2. 存储器类型
    • 3. 特殊功能寄存器变量
    • 4. 位变量
  • C51运算符
    • 1. 位运算符
  • C51中的函数
    • 1. reentrant修饰符
    • 2. interrupt m修饰符
  • 附录

C51的数据类型

C51的数据类型分为基本数据类型和组合数据类型。

1. C51中的基本数据类型

  • 整型
    • 有符号
      • (signed) int、16位、-2^15 ~ 2^15-1;
      • (signed) short、16位、-2^15 ~ 2^15-1;
      • (signed) long、16位、-2^31 ~ 2^31-1;
    • 无符号
      • unsigned int、16位、0 ~ 2^16-1;
      • unsigned short int、16位、0 ~ 2^16-1;
      • unsigned long int、32位、0 ~ 2^32-1;
  • 实型
    • 有符号
      • float、32位、3.4e-38 ~ 3.4e38;
      • double、64位、1.7e-308 ~ 1.7e308;
        字符型
      • 有符号
        • char、8位、-128 ~ 127;
      • 无符号
        • unsigned char、8位、0 ~ 255;

2. 指针类型

指针存放的是指向另一个数据的地址,C51中指针长度一般为 1 ~ 3个字节。

3. 特殊功能寄存器类型

该类型是C51扩充的数据类型,用于访问51单片机中的特殊功能寄存器数据。

分为sfrsfr16两种类型。C51中对特殊功能寄存器的访问必须先用sfr或sfr16进行声明。

  • sfr为字节型特殊功能寄存器类型,占一个字节,可以访问51内部的所有特殊功能寄存器;
  • sfr16为双字节型特殊功能寄存器,占两个字节,可以访问51内部所有两个字节的特殊功能寄存器。

4. 位类型

该类型也是C51扩充的数据类型,用于访问51单片机中的可寻址的位单元。

C51支持两种位类型:bitsbit类型,在内存中都只占一个二进制位,值可以是1或0.

  • bit定义的位变量在C51编译器编译时,在不同的时候地址是可以变化的;
  • sbit定义的位变量必须与51单片机的一个可以寻址位单元或可位寻址的字节单元中的某一位联系在一起,编译时对应的位地址不可变;

C51允许任何标准数据类型的隐式转换,优先级顺序为:
bit → char → int → long → float → signed → unsigned

还可以使用圆括号()进行强制转换。

C51的变量

C51变量定义的格式如下:

[存储种类] 数据类型说明符 [存储器类型] 变量名1 [= 初值], 变量名2[=初值],...

1. 存储种类

存储种类指的是变量在程序执行过程中的作用范围,C51变量的存储种类有四种,分别是自动(auto)、外部(extern)、静态(static)、寄存器(register)。

  • auto定义的变量称为自动变量,作用范围在定义它的函数体或复合语句内部,当定义它的函数体或复合语句执行时,C51才为该变量分配内存空间,结束时占用的内存空间释放。自动变量一般分配在内存的堆栈空间中。定义变量时,如果省略存储种类,该变量默认为自动变量。

  • extern定义的变量称为外部变量。在一个函数体内,要使用一个已在该函数体外或别的程序中定义过的变量时,该变量在该函数体内要用extern说明,外部变量被定义后分配固定的内存空间,在程序整个执行时间内都有效,直到程序结束释放。

  • static定义的变量称为静态变量,分为内部静态变量和外部静态变量。
    内部静态变量定义在函数体的内部,在对应的函数体内有效,一直存在,但在函数体外是不可见的,这样不仅使变量在定义它的函数体外被保护,还可以实现当离开函数时值不被改变。
    外部静态变量定义在函数外部,它在程序中一直存在,但在定义的范围之外不可见,比如在多文件或多模块处理中,外部静态变量只在本文件内部或本模块内部有效。

  • register定义的变量称为寄存器变量,它定义的变量存放在CPU内部的寄存器中,处理速度快,但数目少。C51编译器编译时能够自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,可以无需专门声明。

没有特殊要求定义的一般是auto自动变量;
如果每次调用函数时需要记录某个变量的值,比如记录该函数调用了多少次可以在函数体内使用static修饰位内部静态变量;
如果在某个文件中的所有函数都需要用到某个变量,但其它文件不需要,就可以在文件中使用static修饰位外部静态变量;
如果要在函数体内使用外部定义的变量,要用extern修饰;

2. 存储器类型

存储器类型用于指明变量所处的单片机的存储器区域情况。存储器类型与存储种类完全不同。
C51编译器能够识别的存储器类型有以下几种,如果省略存储器类型,默认为存储器类型

存储器类型描述
data直接寻址的片内RAM低128B,访问速度快
bdata片内RAM的可位寻址区(20H ~ 2FH),允许字节和位混合访问
idata间接寻址访问的片内RAM,允许访问全部片内RAM
pdata用Ri间接访问的片外RAM的低256B
xdata用DPTR间接访问的片外RAM,允许访问全部64k片外RAM
code程序存储器ROM 64k空间

3. 特殊功能寄存器变量

51系列单片机片内有许多特殊功能寄存器,通过这些特殊功能寄存器可以控制51系列单片机的定时器、计数器、串口、I/O及其它功能部件,每一个特殊功能寄存器在片内RAM中都对应一个字节单元或两个字节单元。reg52.h定义了一些常用的特殊功能寄存器变量,见本文附录。

C51允许用户对这些特殊功能寄存器进行访问,访问时需要通过sfrsfr16类型说明符进行定义,定义时还需要指明他们所对应的片内RAM单元的地址,格式如下:

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

特殊功能寄存器一般用大写字母表示,地址一般用直接地址形式。

示例:

// 特殊功能寄存器的定义
sfr PSW = 0xd0;
sfr SCON = 0x98;
sfr TMOD = 0x89;
sfr P1 = 0x90;
sfr16 DPTR =0x82;
sfr16 T1 = 0x8A;

4. 位变量

C51中允许通过位类型(bit或sbit)可以定义位变量。

  • bit位类型用于定义一般的可位处理位变量,格式为:bit 位变量名;,可以加上各种修饰,但存储器类型只能是bdata、data、idata,只能是片内RAM的可位寻址区,严格说只能是bdata。
  • sbit位类型用于定义在可位寻址字节或特殊功能寄存器中的位,定义时需要指明其位地址,可以是位直接地址,也可以是可位寻址变量带位号,也可以是特殊功能寄存器名带位号。格式为sbit 位变量名 = 位地址;,如果位地址是位直接地址,取值范围为0x00 ~ 0xff;如果位地址是可位寻址变量带位号或特殊功能寄存器名带位号,则在它前面需要对可位寻址变量或特殊功能寄存器进行定义。字节地址与位号之间、特殊功能寄存器与位号之间使用^间隔。比如定义51单片机管脚,sbit LED = P1^0;表示有一个LED接到了P1的0端口。

C51把51单片机中常用的特殊功能寄存器和特殊位进行了定义,放在reg51.hreg52.h头文件中,见本文附录,要使用时,将该头文件包含进来即可。

C51运算符

C51运算符同C的运算符一致,支持:

  • 赋值运算符 =
  • 算术运算符 + - * / %
  • 关系运算符 > < >= <= == !=
  • 逻辑运算符 && || !
  • 位运算符 & | ^ ~ << >>
  • 复合赋值运算符 += -= *= /= %= &= |= ^= ~= <<= >>=
  • 逗号运算符 ,
  • 条件运算符 ?:
  • 指针与地址运算符 * &

1. 位运算符

C51能对运算对象按位进行操作。位运算按位对变量进行运算,但不改变参与运算的变量的值。
C51位运算符只能对整数进行操作,不能对浮点数进行操作。
C51中的位运算符有:

  • & 按位与
  • | 按位或
  • ^ 按位异或
  • ~ 按位取反
  • << 左移
  • >> 右移

C51中的函数

C51函数定义的一般格式:

函数类型 函数名(形参列表) [reentrant][interrupt m][using n]

1. reentrant修饰符

reentrant修饰符用于把函数定义为可重入函数。可重入函数就是允许被递归调用的函数。

函数的递归调用指当一个函数正被调用尚未返回时,又直接或间接调用函数本身,只有重入函数才允许递归调用。

使用重入函数时需要注意:

  • reentrant修饰的重入函数被调用时,实参不允许使用bit类型的参数。函数体内也不允许任何关于位变量的操作,更不允许返回bit类型的值。
  • 编译时,系统为重入函数在内部或外部存储器中建立一个模拟堆栈区,称为重入栈。重入函数的局部变量及参数被放在重入栈中,使重入函数可以实现递归调用。
  • 在参数传递上,实际参数可以传递给间接调用的重入函数。无重入属性的间接调用函数不能包含调用参数,但是可以使用定义的全局变量进行参数传递。

2. interrupt m修饰符

interrupt m修饰符是C51中的一个重要修饰符,中断函数通过该修饰符进行修饰。

当函数定义时使用了interrupt m修饰符,系统编译时把对应函数转换为中断函数,自动加上程序头段和尾段,并按51系统中断的处理方式自动把它安排在程序存储器中的相应位置。

该修饰符中,m的取值为0 ~ 31,对应的中断情况为:

  • 0 外部中断0
  • 1 定时器/计数器T0
  • 2 外部中断1
  • 3 定时/计数器T1
  • 4 串行口中断
  • 5 定时器/计数器T2
  • 其它值预留

附录

reg52.h文件中定义的特殊寄存器变量及位变量如下:

// 特殊功能寄存器
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
sfr P3 = 0xB0;  // 四个IO口
sfr PSW = 0xD0;
sfr ACC = 0xE0;
sfr B = 0xF0;
sfr SP = 0x81;
sfr DPL = 0x82;
sfr DPH = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0 = 0x8A;
sfr TL1 = 0x8B;
sfr TH0 = 0x8C;
sfr TH1 = 0x8D;
sfr IE = 0xA8;
sfr IP = 0xB8;
sfr SCON = 0x98;
sfr SBUF = 0x99;// 8052 额外增加的寄存器变量
sfr T2CON = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2 = 0xCC;
sfr TH2 = 0xCD;// 位变量// PSW的位变量
sbit CY = PSW^7;  // 即 0xD0的bit7位
sbit AC = PSW^6;
sbit F0 = PSW^5;
sbit RS1 = PSW^4;
sbit RS0 = PSW^3;
sbit OV = PSW^2;
sbit P = PSW^0;  // 仅8052支持// TCON寄存器的位变量
sbit TF1 = TCON^7;
sbit TR1 = TCON^6;
sbit TF0 = TCON^5;
sbit TR0 = TCON^4;
sbit IE1 = TCON^3;
sbit IT1 = TCON^2;
sbit IE0 = TCON^1;
sbit IT0 = TCON^0;// IE寄存器的位变量
sbit EA = IE^7;
sbit ET2 = IE^5;  // 8052 ONLY
sbit ES = IE^4;
sbit ET1 = IE^3;
sbit EX1 = IE^2;
sbit ET0 = IE^1;
sbit EX0 = IE^0;// IP寄存器的位变量
sbit PT2 = IP^5;
sbit PS = IP^4;
sbit PT1 = IP^3;
sbit PX1 = IP^2;
sbit PT0 = IP^1;
sbit PX1 = IP^0;// P3口的位变量
sbit RD = P3^7;
sbit WR = P3^6;
sbit T1 = P3^5;
sbit T0 = P3^4;
sbit INT1 = P3^3;
sbit INT0 = P3^2;
sbit TXD = P3^1;
sbit RXD = P3^0;// SCON寄存器的位变量
sbit SM0 = SCON^7;
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI = SCON^1;
sbit RI = SCON^0;// P1口的位变量
sbit T2EX = P1^1;  // 8052 ONLY
sbit T2 = P1^1;  // 8052 ONLY// T2CON寄存器的位变量,8052 ONLY
sbit TF2 = T2CON^7;
sbit EXF2 = T2CON^6;
sbit RCLK = T2CON^5;
sbit TCLK = T2CON^4;
sbit EXEN2 = T2CON^3;
sbit TR2 = T2CON^2;
sbit C_T2 = T2CON^1;
sbit CP_RL2 = T2CON^0;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/146892.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT基础入门【QSS】 伪状态,冲突解决、级联介绍

伪状态 伪状态的含义:伪状态指的是可以根据小部件的状态限制样式规则应用的标记。这些状态描述了小部件在特定情况下的状态,比如鼠标悬停、选中等状态。 伪状态的使用:伪状态出现在选择器的末尾,通过冒号(:)进行标记。比如,当鼠标悬停在 QPushButton(按钮)上时,下面…

【Mysql】复合查询详解+实战操作(多表查询、自链接、子查询等)

&#x1f308;欢迎来到Python专栏 &#x1f64b;&#x1f3fe;‍♀️作者介绍&#xff1a;前PLA队员 目前是一名普通本科大三的软件工程专业学生 &#x1f30f;IP坐标&#xff1a;湖北武汉 &#x1f349; 目前技术栈&#xff1a;C/C、Linux系统编程、计算机网络、数据结构、Mys…

Nginx实现负载均衡

Nginx实现负载均衡 负载均衡的作用 1、解决单点故障&#xff0c;让web服务器构成一个集群 2、将请求平均下发给后端的web服务器 负载均衡的软硬件介绍 负载均衡软件&#xff1a; # nginx 四层负载均衡&#xff1a;stream&#xff08;nginx 1.9版本以后有stream模块&#x…

STM32硬件调试器不一定准确,proteus不一定准确

我在做实验的过程中&#xff0c;发现里面的那个变量ii一直都不变搞了很久没有发现问题&#xff0c; 然后怀疑是不是软件出了问题&#xff0c;然后直接只用单片机的一个灯泡来检测是否正常&#xff0c;发现&#xff1a;单片机里面正常&#xff0c;但是硬件调试的时候&#xff0…

LaTeX 数学公式常见问题及解决方案

本文汇总了博主在使用 LaTeX 写文档过程中遇到的所有数学公式常见问题及对应的 LaTeX 解决方案 持续更新... 目录 1. 连等式2. 公式重新开始编号2.1 图片/表格重新编号 1. 连等式 在数学公式推导过程中常常会遇到如 Figure 1 所示的连等式&#xff0c;一般需要保证等号或者不等…

sqli-labs(Less-3)

1. 通过构造id1’ 和id1’) 和id1’)–确定存在注入 可知原始url为 id(‘1’) 2.使用order by 语句猜字段数 http://127.0.0.1/sqlilabs/Less-3/?id1) order by 4 -- http://127.0.0.1/sqlilabs/Less-3/?id1) order by 3 --3. 使用联合查询union select http://127.0.0.1…

CTF-PWN-tips

文章目录 overflowscanfgetreadstrcpystrcat Find string in gdbgdbgdb peda Binary ServiceFind specific function offset in libc手工自动 Find /bin/sh or sh in library手动自动 Leak stack addressFork problem in gdbSecret of a mysterious section - .tlsPredictable …

036、目标检测-锚框

之——对边缘框的简化 目录 之——对边缘框的简化 杂谈 正文 1.锚框操作 2.IoU交并比 3.锚框标号 4.非极大值抑制 5.实现 拓展 杂谈 边缘框这样一个指定roi区域的操作对卷积神经网络实际上是很不友好的&#xff0c;这可能会对网络感受野提出一些特定的要求&#xff0…

【脑与认知科学】【n-back游戏】

请参考课堂内容&#xff0c;设计一种测试工作记忆的实验方法&#xff0c;并选择三位同学作为被试测试工作记忆。请画出实验流程图&#xff0c;叙述实验测试目标&#xff0c;并分析实验结果。 举例&#xff1a;一般我们选择n_back来测试对数字或字母的记忆&#xff0c;选择色块实…

[深度学习]卷积神经网络的概念,入门构建(代码实例)

# 不再任何人,任何组织的身上倾注任何的感情,或许这就是能活得更开心的办法 0.写在前面: 卷积神经网络的部分在之前就已经有所接触,这里重新更全面地总结一下关于深度学习中卷积神经网络的部分.并且在这里对如何构建代码,一些新的思想和网络做出一点点补充,同时会持续更新一些…

传递函数的推导和理解

传递函数的推导和理解 假设有一个线性系统&#xff0c;在一般情况下&#xff0c;它的激励 x ( t ) x(t) x(t)与响应 y ( t ) y(t) y(t)所满足的的关系&#xff0c;可用下列微分方程来表示&#xff1a; a n y ( n ) a n − 1 y ( n − 1 ) a n − 2 y ( n − 2 ) ⋯ a 1 y…

k8s上Pod生命周期、重启策略、容器探测简介

目录 一.Pod的创建过程 二.Pod的终止过程 三.Pod的重启策略&#xff08;restartPolicy&#xff09; 1.Always 2.OnFailture 3.Never 4.示例 四.Pod生命周期内的5种状态&#xff08;相位&#xff09; 1.Pending 2.Running 3.Succeeded 4.Failed 5.Unknown 五.初始…

Pytorch reshape用法

这里-1是指未设定行数&#xff0c;程序自动计算&#xff0c;所以这里-1表示任一正整数 example reshape(-1, 1) 表示&#xff08;任意行&#xff0c;1列&#xff09;&#xff0c;4行4列变为16行1列reshape(1, -1) 表示&#xff08;1行&#xff0c;任意列&#xff09;&#xf…

微内核操作系统

微内核操作系统 采用微内核结构的操作系统与传统的操作系统相比&#xff0c;其优点是提高了系统的灵活性、可扩充性&#xff0c;增强了系统的可靠性&#xff0c;提供了对分布式系统的支持。其原因如下&#xff1a; ① 灵活性和可扩展性&#xff1a;由于微内核OS的许多功能是由…

SpringCache

1、基本信息 Spring缓存方案&#xff1a;JDK内置的缓存(ConcurrentHashMap)、第三方缓存组件(Caffeine)、分布式的缓存实现(Memcahed、Redis)。 ConcurrentHashMap是JUC之中提供最为重要的技术实现。SpringCache之中为了便于缓存结构的管理&#xff0c;在“org.s…

flutter TabBar指示器

第一层tabView import package:jade/configs/PathConfig.dart; import package:jade/customWidget/MyCustomIndicator.dart; importpackage:jade/homePage/promotion/promotionPost/MyPromotionListMainDesc.dart; import package:jade/homePage/promotion/promotionPost/MyPr…

C++入门(1)—命名空间、缺省参数

目录 一、什么是C 1、C关键字(C98) 2、C兼容C 二、C程序预处理指令 三、命名空间 1、命名冲突 第一种&#xff1a; 第二种&#xff1a; 2、域作用限定符 3、实现命名空间 4、命名空间冲突 5、访问命名空间 6、命名空间“std” 四、输入输出 1、定义 2、自动识…

生活总是自己的,请尽情打扮,尽情可爱,,

同色系拼接羽绒服了解一下 穿上时尚感一下子就突显出来了 90白鸭绒填充&#xff0c;不仅时尚还保暖 设计感满满的羽绒服不考虑一下吗?

腾讯云服务器租用价格,腾讯云服务器价格流量怎么算?

首先&#xff0c;让我们来看看腾讯云服务器租用价格。根据您的需求不同&#xff0c;腾讯云提供了多种不同的配置选项&#xff0c;从轻量级应用服务器到高性能的GPU服务器&#xff0c;都可以满足您的需求。以下是一些常见的腾讯云服务器租用价格&#xff1a; 一、腾讯云服务器租…

探讨MySQL存储过程返回记录集

探讨MySQL存储过程返回记录集 1.问题描述 通过存储过程计算统计后&#xff0c;返回程序一个记录集。如果使用表&#xff0c;把记录集保存在过渡表中&#xff0c;在多用户访问的时候&#xff0c;表的数据可能不可控。 使用MySQL 的临时内存表&#xff0c;可以实现在独立会话之…