【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单片机中的特殊功能寄存器数据。
分为sfr
和sfr16
两种类型。C51中对特殊功能寄存器的访问必须先用sfr或sfr16进行声明。
sfr
为字节型特殊功能寄存器类型,占一个字节,可以访问51内部的所有特殊功能寄存器;sfr16
为双字节型特殊功能寄存器,占两个字节,可以访问51内部所有两个字节的特殊功能寄存器。
4. 位类型
该类型也是C51扩充的数据类型,用于访问51单片机中的可寻址的位单元。
C51支持两种位类型:bit
和sbit
类型,在内存中都只占一个二进制位,值可以是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允许用户对这些特殊功能寄存器进行访问,访问时需要通过sfr
或sfr16
类型说明符进行定义,定义时还需要指明他们所对应的片内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.h
或reg52.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;
相关文章:

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

openssl1.0.2版本Windows安装问题
之前安装过1.1版本,Windows环境下C 安装OpenSSL库 源码编译及使用(VS2019)_vs2019安装openssl_肥宝Fable的博客-CSDN博客 后来发现linux编译不过,以为是版本问题,相差太大,所以降一下版本,以免…...

【Java 进阶篇】Ajax 实现——原生JS方式
大家好,欢迎来到这篇关于原生 JavaScript 中使用 Ajax 实现的博客!在前端开发中,我们经常需要与服务器进行数据交互,而 Ajax(Asynchronous JavaScript and XML)是一种用于创建异步请求的技术,它…...

Spring Cloud Stream实践
概述 不同中间件,有各自的使用方法,代码也不一样。 可以使用Spring Cloud Stream解耦,切换中间件时,不需要修改代码。实现方式为使用绑定层,绑定层对生产者和消费者提供统一的编码方式,需要连接不同的中间…...

高精度算法【Java】(待更新中~)
高进度加法 在Java中可以使用BigInteger进行高精度计算,除此也可以仿照竖式相加的计算原理进行计算。 BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger 还提供以下运算࿱…...

说一说HTTP1.0、1.1、2.0版本区别和优化
说一说HTTP1.0、1.1、2.0版本区别和优化 HTTP(Hypertext Transfer Protocol)是一种用于传输超文本的应用层协议。 在不同的版本中,HTTP经历了一系列的演进和改进,主要包括HTTP 1.0、HTTP 1.1和HTTP 2.0。 下面详细解释它们之间…...

51.Sentinel微服务保护
目录 (1)初识Sentinel。 (1.1)雪崩问题及解决方案。 (1.1.1)雪崩问题。 (1.1.2)解决雪崩问题的四种方式。 (1.1.3)总结。 (1.2)…...

【Java 进阶篇】Ajax 实现——JQuery 实现方式 `ajax()`
嗨,亲爱的读者们!欢迎来到这篇关于使用 jQuery 中的 ajax() 方法进行 Ajax 请求的博客。在前端开发中,jQuery 提供了简便而强大的工具,其中 ajax() 方法为我们处理异步请求提供了便捷的解决方案。无需手动创建 XMLHttpRequest 对象…...

I.MX6ULL开发笔记(一)——环境搭建、镜像烧录、网络连接
本系列为使用野火IMX6ULL开发的学习笔记,使用的开发板为如下: 具有的硬件资源有如下: 文章目录 一、环境搭建Win11安装WSL安装串口驱动安装串口工具安装Ubuntu与windows文件互传 二、镜像烧录修改串口终端登录前信息 三、fire-config工具配…...

Javaweb之Ajax的详细解析
1.1 Ajax介绍 1.1.1 Ajax概述 我们前端页面中的数据,如下图所示的表格中的学生信息,应该来自于后台,那么我们的后台和前端是互不影响的2个程序,那么我们前端应该如何从后台获取数据呢?因为是2个程序,所以…...

java基于RestTemplate的微服务发起http请求
实现的效果...

django理解02 前后端分离中的问题
前后端分离相对于传统方式的问题 前后端数据交换的问题跨域问题 页面js往自身程序(django服务)发送请求,这是浏览器默认接受响应 而请求其它地方是浏览器认为存在潜在危险。自动隔离请求!!! 跨域问题的解决…...

设计模式-迭代器模式-笔记
动机(Motivaton) 在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们呢希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一…...

【数据结构】C语言实现队列
目录 前言 1. 队列 1.1 队列的概念 1.2 队列的结构 2. 队列的实现 2.1 队列的定义 2.2 队列的初始化 2.3 入队 2.4 出队 2.5 获取队头元素 2.6 获取队尾元素 2.7 判断空队列 2.8 队列的销毁 3. 队列完整源码 Queue.h Queue.c 🎈个人主页:…...

牛客——OR36 链表的回文结构(C语言,配图,快慢指针)
目录 思路一:链表翻转 思路二:快慢指针,分别从头和尾间开始比较 本题是没有对C的支持的,但因为CPP支持C,所以这里就用C写了,可以面向更多用户 链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 思路一&am…...

Docker build 技巧 —— 筑梦之路
实现目标 更快的构建速度 更小的Docker镜像大小 更少的Docker镜像层 充分利用镜像缓存 增加Dockerfile可读性 让Docker容器使用起来更简单 如何实现 编写.dockerignore文件 容器只运行单个应用 将多个RUN指令合并为一个 基础镜像的标签不要用latest 每个RUN指令后删除…...

2 Redis的高级数据结构
1、Bitmaps 首先,最经典的应用场景就是用户日活的统计,比如说签到等。 字段串:“dbydc”,根据对应的ASCII表,最后可以得到对应的二进制,如图所示 一个字符占8位(bit),…...

Hive默认分割符、存储格式与数据压缩
目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限(ROW FORMAT)配置标准HQL为: ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

update_engine-FilesystemVerifierAction和PostinstallRunnerAction
在介绍完了DownloadAction之后,还剩下FilesystemVerifierAction和PostinstallRunnerAction,下面开始对其进行分析。 FilesystemVerifierAction 在数据下载完成后,在DownloadAction中会切换到FilesystemVerifierAction void DownloadAction:…...

深度学习乳腺癌分类 计算机竞赛
文章目录 1 前言2 前言3 数据集3.1 良性样本3.2 病变样本 4 开发环境5 代码实现5.1 实现流程5.2 部分代码实现5.2.1 导入库5.2.2 图像加载5.2.3 标记5.2.4 分组5.2.5 构建模型训练 6 分析指标6.1 精度,召回率和F1度量6.2 混淆矩阵 7 结果和结论8 最后 1 前言 &…...

【Python百宝箱】掌握Python Web开发三剑客:Flask、Django、FastAPI一网打尽
前言 在当今互联网时代,Web应用的开发变得愈发重要和复杂。选择一个合适的Web框架,掌握安全性与认证、数据库与ORM库、前端框架与交互、测试与调试工具等关键知识点,是每个Web开发者都必须面对的挑战。本文将带你深入了解三个流行的Python W…...

【人工智能时代的刑法体系与责任主体概述】
第一节:引言 随着科技的快速发展,人工智能 (Artificial Intelligence, AI) 正日益成为我们生活中不可或缺的一部分。从自动驾驶汽车到语音助手,从智能家居到金融机器人,AI 的广泛应用正不断改变着我们的生活方式和社会结构。然而…...

透视maven打包编译正常,intellj idea编译失败问题的本质
前言 maven多模块类型的项目,在Java的中大型应用中非常常见, 在 module 很多的情况,经常会出现各种各样的编辑依赖错误问题,今天记录一种比较常见的 case : A 子模块依赖 B 子模块,在 Terminal 上终端上 …...

npm报错
npm报错 npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution. npm ERR! npm ERR! npm ERR! For a full report s…...

【FFmpeg实战】ffmpeg播放器-音视频解码流程
音视频介绍 音视频解码流程 FFmpeg解码的数据结构说明 AVFormatContext:封装格式上下文结构体,全局结构体,保存了视频文件封装格式相关信息AVInputFormat:每种封装格式,对应一个该结构体AVStream[0]:视频文件中每个视频ÿ…...

基于SSM的高校毕业选题管理系统设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...

一个简单的Oracle Redaction实验
本实验包含了: 简单的Oracle Redaction演示针对指定用户的Redaction 实验环境 假设有一个19c多租户数据库,PDB名为orclpdb1。 我们将在orclpdb1中建立2个用户: redact_user: redact管理员schema_user: schema用户 基础实验 首先进入数…...

getchar函数的功能有哪些
getchar函数是C语言标准库中的一个函数,主要用于从标准输入(通常是键盘)获取一个字符。它的功能包括: 从标准输入获取一个字符:getchar函数会等待用户输入一个字符,然后将其返回给程序。可以通过控制台输入…...

信息机房监控系统(动环辅助监控系统)
信息机房监控系统是一个综合性的系统,用于对机房的所有设备及其环境进行集中监控和管理。这种系统主要针对机房的各个子系统进行监控,包括动力系统、环境系统、消防系统、保安系统、网络系统等。 依托电易云-智慧电力物联网,以下是信息机房监…...

最强英文开源模型Llama2架构与技术细节探秘
prerequisite: 最强英文开源模型LLaMA架构探秘,从原理到源码 Llama2 Meta AI于2023年7月19日宣布开源LLaMA模型的二代版本Llama2,并在原来基础上允许免费用于研究和商用。 作为LLaMA的延续和升级,Llama2的训练数据扩充了40%,达到…...