8051单片机的C语言程序设计

article/2025/11/2 11:11:20

一、数据类型
(一)基本类型:
1. 位类型(bit):1)是C51的扩充数据类型,用于访问8051中可寻址的位单元。
2)8051支持两种位类型:bit型和sbit类型,它们在内存中都只占一个二进制位,其值可以是1或0。
3)用bit定义的位变量在C51编译器编译时,在不同的时候位地址是可以变化的。
4)用sbit定义的位变量必须与8051系列单片机的一个可以寻址单元或可位寻址的字节单元中的某一位
联系在一起,在C51编译器编译时,其对应的位地址是不可以变化的。
2. 字符型(char):1)有signed char和unsigned char之分,默认signed char。占一个字节。
2)signed char定义带符号字节数据,字节最高位用0表示正数,1表示负数,一补码表示,数值
范围-128~+127.
3)unsigned char定义无符号字节数据或字符,可以存放一个字节的无符号数,数值范围0~255;
unsigned char还可以表示西文字符,占一个字节,在计算机中用ASCII码存放
3. 整型(int):1)有signed int和unsigned int之分,默认signed int。占两个字节。
2)signed int,用于存放两字节带符号数,以补码表示,数值范围-32768~+32767;
3)unsigned int,用于存放两个字节无符号数,数值范围0~65535;
4. 长整型(long):1)有signed long和unsigned long之分,默认signed long,占4个字节;
2)signed long,用于存放4字节带符号数,以补码表示,数值范围-2147483648~+2147483648;
3)unsigned long,用于存放4个字节无符号数,数值范围0~4294967695;
5. 浮点型(float):占4个字节
6. 特殊功能寄存器型:1)这是C51的扩充的数据类型,用于访问8051单片机中的特殊功能寄存器数据;
2)分为sfr和sfr16两种。sfr为字节型特殊功能寄存器类型,占一个字节单元,利用它可以访问
8051单片机内部所有的特殊功能寄存器;sfr16为2字节特殊功能寄存器类型,占2进行个字
节单元,利用它可以访问8051单片机内部所有2字节的特殊功能寄存器。
3)在C51中对特殊功能寄存器的访问必须先用sfr和sfr16进行声明
(二)构造类型
1. 数组类型(array)
2. 结构体类型(struct)
3. 共用体(union)
4. 枚举(enum)
(三)指针类型
指针型本身是一个变量,在这个变量中存放着指向另一个数据的地址。这个指针变量要占用一定的内 存单元,对于不 同的处理器器长度不一样,在C51中指针的长度一般为1~3个字节。
(四)空类型
二、C51的运算量
(一)常量
包括整型常量、浮点型常量、字符型常量、字符串型常量
(二)变量
1. 存储器类型在这里插入图片描述
2. 特殊功能寄存器变量
1)格式:sfr/sfr16 特殊功能寄存器名=地址。
2)特殊功能寄存器名一般用大写字母表示,地址一般采用直接地址形式,具体特殊功能寄存器地址看之前的文章
例:sfr PSW=0xD0;–>定义程序状态字PSW的地址为D0H;
sfr TMOD=0x89;–>定义定时器控制寄存器TMOD的地址为89H;
sfr P1=0x90;–>定义p1端口的地址为90H;
3. 位变量
1)格式:bit 位变量名(注意:在格式中可以加上各种修饰符,但存储器类型只有bdata data idata)
例:bit data a1;正确
bit pdata a2;错误
2)格式:sbit 位变量名=位地址;(注意:如位地址为为直接地址,其取值范围为0x00~0xFF;如位地址是可位寻址变量带位号或特殊功能寄存器名带位号,则在它前面需对可位寻址变量或特殊功能寄存器进行定义。字节地址与位号之间、特殊功能寄存器与位号之间一般用……作间隔。
例:sbit Cy=0xD7;–>定义进位标志Cy的地址位D7H;
sbit AC=0xD0……6;–>定义辅助进位标志AC的地址为D6H;
sbit RS0=0xD0^3;–>定义RS0的地址为D0H;
(三)存储模式
C51编译器支持3种存储模式:SMALL模式、COMPACT模式和LARGE模式。
1. SMALL模式:称为小编译模式,编译时函数参数和变量被默认在片内RAM中,存储器类型为data;
2. COMPACT模式:称为紧凑编译模式,函数参数被默认在片外RAM的低256B空间,存储类型为pdata;
3. LARGE模式:称为大编译模式,编译时函数参数和变量被默认在片外RAM的64B空间,存储类型为xdata;
在程序中变量存储模式的指定通过#pragma预处理指令来实现。函数的存储模式可通过函数定义时后面带存储模式来说明。如果没有指定,则默认为SMALL模式。
例:#pragma small/int func() small/int func() -->都是变量的存储模式为small模式
(四)绝对地址访问
在C51中,可以通过变量的形式访问8051单片机的的存储器,也可以通过绝对地址来访问存储器,访问绝对地址有3种
1. 使用C51运行库中预定义宏(使用时加头文件 #include <absacc.h>)
在C51中,可以通过变量的形式访问8051单片机的code、data、pdata、xdata空间进行绝对寻址。规定只能以无符号的方式访问,定义了8个宏,原型如下:
#difine CBYTE((unsigned char volatile*)0x50000L)–>(CBYTE以字节形式对code区寻址)
#difine DBYTE((unsigned char volatile*)0x40000L)–>(DBYTE以字节形式对data区寻址)
#difine PBYTE((unsigned char volatile*)0x30000L)–>(PBYTE以字节形式对pdata区寻址)
#difine XBYTE((unsigned char volatile*)0x20000L)–>(XBYTE以字节形式对xdata区寻址)
#difine CWORD((unsigned int volatile*)0x50000L)–>(CWORD以字节形式对code区寻址)
#difine DWORD((unsigned int volatile*)0x50000L)–>(DWORD以字节形式对data区寻址)
#difine PWORD((unsigned int volatile*)0x50000L)–>(PWORD以字节形式对pdata区寻址)
#difine XWORD((unsigned int volatile*)0x50000L)–>(XWORD以字节形式对xdata区寻址)
访问形式:宏名[地址];其中CBYTE、DBYTE、PBYTE、XBYTE、CWORD、DWORD、PWORD、XWORD为宏名,地址用16进制表示:
例:var1 = XBYTE[0x0005];–>XBYTE[0x0005]访问片外RAM的0005字节单元;
2. 通过指针访问
采用指针的方法,可以实现C51程序中对任意指定的存储器单元进行访问。
例: int xdata *dpt1;–>定义一个指向xdata区的指针dpt1;
dpt1=0x30;–>dpt1指针赋值,指向xdata区的30H单元;
dpt1=0xFF;–>将数据0xFF送到片外RAM的30H单元;
3. 使用C51关键扩展字_at_
使用_at_是对指定的存储器空间的绝对地址进行访问,格式:[存储器类型] 数据类型说明符 变量名 at 地址常数;
地址常数用于指定变量的绝对地址,必须位于有效的存储空间之内,使用_at_定义的变量必须为全局变量。
例:data char x1_at_0x40;–>在data区中定义字节变量x1,它的地址为40H;
三、函数
(一)函数的定义
一般格式:函数类型 函数名(形式参数表) [reentrant] [interrupt m] using n
(二)reentrant修饰符
在C51中,这个修饰符用于把函数定义可重入函数。所谓的可重入的函数就是允许被递归调用的函数。一般的函数不可以递归调用,只有可重入函数才允许递归调用。在C51中,当函数被定义为可重入函数,C51编译器编译时将会为可重入函数生成一个模块栈,通过这个模块栈来完成参数的传递和局部变量存放。关于可重入函数,应该注意以下几点:
1. 用reentrant修饰的可重入函数被调用的时,实参列表内不允许使用bit类型的参数。函数体内也不允许存在任何关于位变量的操作,更不能返回bit类型的值。
2. 编译时,系统为可重入函数在内部或外部存储器中建立一个模拟堆栈区,称为重入栈。可重入函数的局部变量及参数被放入重入栈中,时可重入函数可以实现被递归调用。
3. 在参数的传递上,实际参数可以传递给间接调用的可重入参数。无重入属性的间接调用函数不能包含调用函数,但是可以使用定义的全局变量来进行参数传递。
(三)interrupt m修饰符
interrupt m是C51函数中一个非常重要的修饰符,是因为中断函数必须通过它来进行修饰。在C51程序设计时,当函数用interrupt 修饰时,系统编译把对应的函数转化为中断函数,自动加上程序头段和尾段,并按MCS-51系统中断的处理方式自动把它安排在程序存储器的相应位置。在该修饰符中,m的取值为0~31,对应的中断如下:
0——外部中断;1——定时器/计数器T0;2——外部中断;3——定时器/计数器T1;
4——串行口中断;5——定时器/计数器T2;其他值预留。使用中断函数应注意以下7点:
1. 中断函数不能进行参数传递,如果中断函数中包含任何参数声明,都将导致编译出错;
2. 中断函数没有返回值,如果试图定义一个返回值,将得不到正确的结果,建议在定义中断函数时将其定义为void型,以说明没有返回值;
3. 在任何情况下都不能之间调用中断函数,否则会产生编译错误。因为中断函数的返回由8051单片机的RETI指令完成,RETI指令影响8051单片机的硬件中断系统。如果在没有实际中断情况下之间调用中断函数,RETI指令的操作结果会产生一个致命的错误。当中断条件满足时自动调用。
4. 如果在中断函数中直接调用了其他函数,则被调用函数所使用的寄存器必须与中断函数相同,否则不会输出正确结果。
5. C51编译器对中断函数编译时,会自动在程序开始和结束加上相应的内容。具体如下:在程序开始处ACC、B、DPH、DPL、PSW入栈,结束时出栈;中断函数未加using n修饰符的,开始时还要将R0~R1入栈,结束时出栈,如中断函数加using n修饰符,则在开始PSW将入栈后还要修改PSW中的工作寄存组选择位。
6. C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,即interrupt后面的数字,该向量包含一个到中断函数入口的绝对跳转。
7. 中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明,以防其他程序调用。
(四)using n修饰符
MCS-51单片机有4组工作寄存器:0组、1组、2组、3组。每组8个寄存器,分别用R0~7R表示。修饰符using n用于指定本函数内部使用的工作寄存器组,其中n的取值范围0–3,表示寄存器组号。对应using n的使用,注意以下几点:
1. 加入using n后,C51在编译时自动在函数的开始处和结束处加入以下命令。
{
PUSH PSW;//标志寄存器入栈
MOV PSW,#与寄存器组号n相关的常量;//常量值为(PSW&OXET)&n
8
~~~~~
POP PSW;//标志寄存器出栈
}
2. using n修饰符不能用于有返回值的函数,因为C51函数的返回值是放在寄存器中的。如果寄存器组改变了,返回值就会出错。


http://chatgpt.dhexx.cn/article/ymQZO9lo.shtml

相关文章

c语言程序设计实训

任务一、顺序结构程序设计 1.编写已知半径r为15的圆面积 #include <stdio.h> int main() {double r, s, pi 3.14159;printf("请输入圆的半径为&#xff1a;");scanf_s("%lf", &r);s pi * r * r;printf("面积为&#xff1a;%f", s)…

51单片机基础实验例程

代码来源见代码注释。 Table of Contents 实验1&#xff1a;点亮第一个LED 实验2&#xff1a;LED闪烁 实验3&#xff1a;LED流水灯 实验4&#xff1a;蜂鸣器 实验5&#xff1a;静态数码管显示 实验6&#xff1a;动态数码管显示 实验7&#xff1a;独立按键 实验8&#x…

单片机c语言应用100例第3版课后答案,单片机C语言应用100例(第3版)

读者对象&#xff1a; 本书在编写时力求通俗、易懂&#xff0c;硬件原理以"有用、够用”为原则&#xff0c;内容讲解以"紧密结合实践”为特色。因此&#xff0c;本书特别适合单片机零起点的初学者使用&#xff0c;可作为高等院校控制类专业学生、电子爱好者及各类工程…

51单片机C语言程序100例分析(1)IO+C语言+头文件

51单片机C语言程序100例分析&#xff08;1&#xff09;IOC语言头文件 \\\插播一条&#xff1a;文章末尾有惊喜哟~/// P10xfe;//P111111110B&#xff0c;即P1.0输出低电平} 分析&#xff1a;通过这短短的几行代码就能够让51单片机的P1.0引脚输出低电平&#xff0c;首先#includ…

单片机c语言赚钱,单片机C语言程序设计实训100例(从初级入手).pdf

您所在位置&#xff1a;网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp嵌入式开发 单片机C语言程序设计实训100例(从初级入手).pdf59页 本文档一共被下载&#xff1a;次,您可全文免费在线阅读后下载本文档。 下载提示 1.本站不保证该用户上传的…

51单片机C语言编程100例pdf,51单片机C语言编程100例.doc

51单片机C语言编程100例.doc .目 录实例3用单片机控制第一个灯亮3实例4用单片机控制一个灯闪烁认识单片机的工作频率3实例5将 P1口状态分别送入P0、P2、P3口认识I/O口的引脚功能3实例6使用P3口流水点亮8位LED3实例7通过对P3口地址的操作流水点亮8位LED3实例8用不同数据类型控制…

单片机c语言程序设计实训报告,(整理)单片机C语言程序设计实训100例.doc

(整理)单片机C语言程序设计实训100例.doc .单片机C语言程序设计实训100例基于8051Proteus仿真案例第 01 篇 基础程序设计01闪烁的LED/* 名称闪烁的LED说明LED按设定的时间间隔闪烁*/includereg51.hdefine uchar unsigned chardefine uint unsigned intsbit LEDP10;延时void Del…

单片机C语言程序设计实训100例基于8051+Proteus仿真

初学单片机的时候&#xff0c;需要一些比较基础的例子来参考和提高自己 &#xff0c;这里整理一下常用的基本例子&#xff0c;给有需要的人也下载哦 内如下&#xff1a; 分2个文件夹基础部分和硬件应用部分 比如基础里面第一个 闪烁LED程序&#xff0c;C文件如下 #include &…

pchpch

在Xcode6之前&#xff0c;创建一个新工程xcode会在Supporting files文件夹下面自动创建一个“工程名-Prefix.pch”文件&#xff0c;也是一个头文件&#xff0c;pch头文件的内容能被项目中的其他所有源文件共享和访问。是一个预编译文件。 首先说一下pch的作用&#xff1a; 1.存…

Chip-seq简介

欢迎关注”生信修炼手册”! 染色质免疫共沉定技术&#xff0c;可以研究生物体内DNA与蛋白质的相互作用&#xff0c;首先在活细胞内固定DNA与蛋白结合的复合体&#xff0c;然后用蛋白特异性的抗体&#xff0c;通过抗原抗体特异性结合的免疫学手段捕获该复合体&#xff0c;然后洗…

CPC是什么意思和CPM、CPV有什么不同?

本文转载自&#xff1a;http://www.seolhj.com/baidujj/244.html 作者&#xff1a;木子seo 如果你有接触过百度竞价网络投放广告&#xff0c; 你是不是在工作中常常听到CPC、CPM、CPT等这些词汇&#xff0c; 却搞不懂他们到底是什么意思&#xff0c;之间的差异和内涵是什么&am…

SPI总线时钟的极性(CPOL)与相位(CPHA)

文章来源&#xff1a;转来转去的不知道是谁的了。。 SPI由于接口相对简单&#xff08;只需要4根线&#xff09;&#xff0c;用途算是比较广泛&#xff0c;主要应用在EEPROM&#xff0c;FLASH&#xff0c;实时时钟&#xff0c;AD转换器&#xff0c;还有数字信号处理器和数字信号…

CPT

Cisco Packet Tracer 实验 目录 一、直接连接两台 PC 构建 LAN二、用交换机构建 LAN三、交换机接口地址列表四、生成树协议五、路由器配置初步六、静态路由七、动态路由RIP八、动态路由OSPF九、基于端口的网络地址翻译 PAT十、虚拟局域网 VLAN十一、虚拟局域网管理 VTP十二、VL…

【process.popen】

原文链接&#xff1a;https://blog.csdn.net/liuyingying0418/article/details/100939697 subprocess.Popen()用法 subprocess.Popen()主要是用来在python中实现多进程程序。例如&#xff0c;在python脚本中&#xff0c;我们需要执行另一个python脚本&#xff0c;或者执行shel…

一文读懂 ChIPseq

文章目录 一、介绍二、测序原理三、检测蛋白质与DNA序列的结合峰1、测序片段匹配到参考基因组2、检测峰3、提高峰质量 四、影响ChIPseq测序结果的因素1、免疫共沉淀的影响2、测序的影响测序深度的对组蛋白修饰检测的影响3、重复样和重现性 一、介绍 ChIP-seq&#xff0c;测序方…

怎样理解SPI总线时钟的极性(CPOL)与相位(CPHA)?

转自 https://zhuanlan.zhihu.com/p/32803973 在单片机与外围设备的通信中&#xff0c;SPI总线是一种常用的通信方式。SPI是英文"Serial Periphral Interface"的缩写&#xff0c;中文翻译为"串行外围设备接口"。今天这篇文章&#xff0c;我们就来谈谈SPI通…

Python 之 cPickle用法

欢迎大家扫码关注我的微信公众号&#xff1a; Python 之 cPickle 用法 - 目录 一、概述二、序列化与反序列化的几个常用方法2.1 dump() 与 load()2.2 dumps() 与 loads()2.3 带 s 与不带 s 的区别 三、cPickle 类的孪生—— pickle 一、概述 序列化 &#xff08;Serializatio…

HDU 2509 Nim博弈变形

&#xff11;、HDU 2509   &#xff12;、题意&#xff1a;n堆苹果&#xff0c;两个人轮流&#xff0c;每次从一堆中取连续的多个&#xff0c;至少取一个&#xff0c;最后取光者败。 &#xff13;、总结&#xff1a;Nim博弈的变形&#xff0c;还是不知道怎么分析&#xff0c;…

LibreOJ #2509.「HNOI2018」排列 贪心+堆

题意 n<500000 分析 不难分析到其实就是有一棵树&#xff0c;然后每次要选一个节点。在选某个节点时必须先选其父节点&#xff0c;第i个选的节点的系数为i&#xff0c;问最大的权值和。 先这么想&#xff0c;对于一个最权值小的节点&#xff0c;当我们选了其父亲后&#…