- 水元素sl
-
我来回答你的问题吧,前几天对这个方面有一定的深入了解,也写下了大量的笔记
虽然C编程的时候,对于不同的芯片,有不同的头文件,但是,万变不离其宗。
只要学会了写自己的头文件,就可以应付各类型号单片机了,就算你用的是AT89C2052,还是AT89C51,STC12C等等,都可以用一个头文件reg51.h 不过要做相应的修。
以下是我对reg51.h个人的见解:(对于你很有用的) 后面带上了在编写C51时带用的头文件,及其内部函数和宏定义的详细解说。
想了解如下方面的知识来来邮amwjie72@163.com
一, C51内存结构深度剖析
二, reg51.头文件剖析
三, 浅淡变量类型及其作用域
四, C51常用头文件
五, 浅谈中断
六, C51编译器的限制
七, 小淡C51指针
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
reg51.头文件剖析
我们平时写单片机应用程序的时候,所使用的头文件大多都是用的的reg51.h或是用reg52.h。会写C51的人都会用,但对其头文件内部的定义有所了解的人确并不多。
下面对其内部做详细解释,方便读者作进一步的了解,并能运用各类型号的单片机。因为增强型号的单片机的增强功能都是通过特殊功能寄存器控制。
打开 reg52.h 头文件,会发现是由大量的 sfr ,sbit的声明组成,甚至于还有sfr16.其实这样的声明都是与单片机内部功能寄存器(特殊功能寄存器)联系起来的,下面对其做出详细解释
sfr: 声明变量
SFR 声明一个变量,它的声明与其它的C变量声明基本相同,唯一的区别,SFR在声明的同时为其指定特殊功能寄存器作为存储地址,而不同于C变量声明的整型,字符型等等由编译器自动分配存储空间。
如reg52.h头文件,第一条声明就是sfr P0 = 0x80;
此处声明一个变量P0,并指定其存储地址为特殊功能寄存器0x80;,在加入reg52.h头文件后。编写应用程序时P0就可以直接使用而无需定义,对P0的操作就是,对内部特殊功能寄存器(0x80对应用MCU的P0口)的操作,可进行读写操作。
如果将第一条声明改为sfr K0 = 0x80; 那么,如果要把单片机的P0口全部拉低,则不能写P0=0x00;而应保存后再在应用程序中写成K0=0x00;否则编译器会提示“P0为未定义标识符”
使用方法:
sfr [variable] = [address] //为变量分配一个特殊功能寄存器。
1 等号右边,只能是十进制,十六进制整型的数据常量,,不允许带操作符的表达式
经典的8051内核支持的SFR地址从0x80H~0xFF 飞利浦80C51MX系列0x180H~0x1FF
2 SFR不能声明于任何函数内部,包括main函数。只能声明于函数外。
3 用SFR声明一个变量后,不能用取地址运算符&获取其地址, 编译无法通过,编译器会提示非法操作。
4 有一点须特别注意,51内核0x80~0xff,为特殊功能寄存器地址区间,但并不是所有的地址都有定义,如果说你所用的MCU芯片上对于某个地址没有定义,那么用sfr在定义变量的时候,不要把变量的地址分配到未定义的特殊功能寄存器上,虽然编译时能通过,用KEIL仿真时貌似是没有问题,但下载到芯片里运行时,是会出问题的。比如说,向一个未定义的特殊功能寄存器执行读操作,读出来的就是一个未知的数。(读者可自行测试,先把串口通信调通,然后做一个简单的人机交互。读出一个数后,再发给计算机,用串口调试助手或是串口监控查看。这用方法在仿真的时候很有用。)所以具体那些特殊功能寄存器能够用,就要查看你使用的芯片手册。
5 若遇到增强性的单片机,只要知道其扩展的特殊功能寄存器的地址,用SFR定
就可以很方便进行编程。
sbit: 声明变量
sbit 同样是声明一个变量,和SFR 使用方法类似,但是SBIT是用来声明一个位变量,因为,在51系列的应用中,非常有必要对SFR的单个位进行存取,而通过bit 数据类型,使其具备位寻址功能。
如,在reg52.h中有如下声明
sfr IE = 0xA8;
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;
所以,对EA的操作即是对IE最高位的操作。
但如果想让 SP DPL DPH PCON TMOC TL0 TL1 TH0 TH1 SBUF这些特殊功能寄存器具备位寻址,采用上述如IE类似的定义,是不行的,虽然修改后,在编译的时候不会出现错误,但只要用到你定义的位变量名时就会出错。原因是,只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址。
打开reg52.h头文件可以看到,所有用sbit声明了的特殊功能寄存器的地址均是以0或8结尾
如硬要达到上述要求,可用带参的宏定义来完成。此处不做详细说明(意义并不大)。
下面对sbit的使用做详细介绍:
随着8051的应用,非常有必要对特殊功能寄存器的单个bit位进行存取,C51编译器通过sbit 数据类型,提供了对特殊功能寄存器的位操作。
以下是sbit的三种应用形式:
一, sbit name = sfr-name^bit-position;
sfr PSW =0xD0;
sfr IE =0xA8;
sbit OV= PSW^2;
sbit CY=PSW^7;
sbit EA= IE^7;
二, sbit name= sft-address^bit-position;
sbit OV =0xD0^2;
sbit CY =0xD0^7;
sbit EA =0xA8^7;
三, sbit name= sbit-address;
sbit OV =0xD2;
sbit CY =0xD7;
sbit EA =0xAF;
现对上述三种形式的声明做必要的说明
第一种形式sbit name = sfr-name^bit-position;如sbit OV= PSW^2; 当中的这个特殊功能寄存器必须在此之前已经用sfr 定义,否则编译会出错。
bit-position范围从0~7;
第二种形式 sbit name= sft-address^bit-position如sbit OV =0xD0^2; 与第一种形式不同之外在于,此处直接使用PSW的地址.第一种形式须先定义PSW
第三种形式. sbit name= sbit-address 如sbit OV =0xD2 是直接用的OV的地址
OV的地址计算方式,是OV所在的寄存器地址加上OV的bit-position
注意:
不是所有的SFR都可位寻址。只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址,并且sbit声明的变量名,虽可以是任意取,但是最好不要以下划线开头,因为以下划线开头的都保留给了C51的头文件做保留字。
sfr16: 声明变量
许多8051的派生型单片机,用两个连续地址的特殊功能寄存器,来存储一个16bit的值。例如,8052就用了0xCC和0xCD来保存定时/计数寄存器2的高字节和低字节。编译器提供sfr16这种数据类型,来保存两个字节的数据。虚拟出一个16bit的寄存器。
如下:
sfr16 T2 = 0xCC
存储方面为小端存储方式,低字节在前,高字节在后。定义时,只写低字节地址,如上,则定义T2为一个16位的特殊功能寄存器。 T2L= 0CCh, T2H= 0CDh
使用方法:
sfr [variable] = [low_address]
1 等号右边,只写两个特殊功能寄存器的低地址,且只能是十进制,十六进制的整型数据常量,不允许带操作符的表达式
2 SFR不能声明于任何函数内部,包括main函数。只能声明于函数外。
3 用SFR声明一个变量后,不能用取地址运算符&获取其地址, 编译无法通过,编译器会提示非法操作。
4 当你向一个sfr16写入数据的时候,KEIL CX51 编译器生成的代码,是先写高字节,后写低字节,(可通过返汇编窗口查看)在有些情况下,这并非我们所想要的操作顺序。使用时,须注意。
5 当你所要写入sfr16的数据,当是高字节先写还是低字节先写非常重要的时候,就只能用sfr 这个关键字来定义,并且任意时刻只保存一个字节,这样操作才能保证写入正确。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
C51常用头文件
在KEIL 中,对于单片机所使用的头文件,除了reg51 reg52以外,还有一些从各芯片制商的官网下载与reg51,reg52功能类似的头文件,需了解透外,还要对各类型单片机均可通用且相当有用的的头文件,做相应的了解。因为,内部所包含的函数与宏定义,可以及大的方便我们编写应用程序。
1字符函数 ctype.h
1 extern bit isalpha(char);
功能:检查参数字符是否为英文字母,是则返回1
2 extern bit isalnum(char)
功能:检查字符是否为英文字母或数字字符,是则返回1
3 extern bit iscntrl(char)
功能:检查参数值是否在0x00~0x1f 之间或等于0x7f,是则返回1
4 extern bit isdigit(char)
功能: 检查参数是否为数字字符,是则返回1
5 extern bit isgraph(char)
功能: 检查参数值是否为可打印字符,是则返回1,可打印字符为0x21~0x7e
6 extern bit isprint(char)
功能:除了与isgraph相同之外,还接受空格符0x20
7 extern bit ispunct(char)
功能:不做介绍。
8 extern bit islower(char)
功能:检查参数字符的值是否为小写英文字母,是则返回1
9 extern bit isupper(char)
功能:检查参数字符的值是否为大写英文字母,是则返回1
10 extern bit isspace(char)
功能:检查字符是否为下列之一,空格,制表符,回车,换行,垂直制表符和送纸。如果为真则返回1
11 extern bit isxdigit(char)
功能:检查参数字符是否为16进制数字字符,是则返回1
12 extern char toint(char)
功能:将ASCII字符0~9 a~f(大小写无关)转换成对应的16进制数字,
返回值00H~0FH
13 extern char tolower(char)
功能:将大写字符转换成小写形式,如字符变量不在A~Z之间,则不作转换而直接返回该字符
14 extern char toupper(char)
功能:将小写字符转换成大写形式,如字符变量不在a~z之间,则不作转换而直接返回该字符
15 define toascii(c) ((c)&0x7f)
功能:该宏将任何整形数值缩小到有效的ASCII范围之内,它将变量和0x7f相与从而去掉第7位以上的所有数位
16 #define tolower(c) (c-‘A"+"a")
功能:该宏将字符与常数0x20 逐位相或
17 #define toupper(c) ((c)-‘a"+"A")
功能:该宏将字符与常数0xdf 逐位相与
2数学函数 math.h
extern int abs (int val);
extern char cabs (char val);
extern long labs (long val);
extern float fabs (float val);
功能:返回绝对值。上面四个函数,除了形参和返回值不一样之外,
其它功能完全相同。
extern float exp (float val);
extern float log (float val);
extern float log10 (float val);
功能: exp 返回eval
log 返回 val 的自然对数
log10 返回 以10为底,val的对数
extern float sqrt (float val);
功能: 返回val的正平方根
extern int rand();
extern void srand(int n);
功能: rand返回一个0到32767之间的伪随机数,srand用来将随机数发生器初始化成一个已知的(期望)值。
Keil uVision3中的math.h库中,不包含此函数。
extern float sin (float val);
extern float cos (float val);
extern float tan (float val);
功能: 返回val的正弦,余弦,正切值。val为弧度 fabs(var) <=65535
extern float asin (float val);
extern float acos (float val);
extern float atan (float val);
extern float atan2 (float y, float x);
功能: asin 返回val的反正弦值。acos 返回val的反余弦值。
atan 返回val的反正切值。
asin atan acos的值域均为 -π/2~+π/2
atan2返回x/y,的反正切值,其值域为-π~+π
extern float sinh (float val);
extern float cosh (float val);
extern float tanh (float val);
功能:cosh返回var的双曲余弦值,sinh返回var的双曲正弦值,
tanh返回var的双曲正切值。
extern float ceil (float val);
功能: 向上取整,返回一个大于val的最小整数。
extern float floor (float val);
功能: 向下取整,返回一个小于val的最大整数。
extern float pow (float x, float y);
功能: 计算计算xy的值。当(x=0,y<=0)或(x<0.y不是整数)时会发生错误。
extern void fpsave(struct FPBUF *p)
extern void fprestore(struct FPBUF *p)
功能:fpsave 保存浮点了程序的状态,fprestore恢复浮点子程序的原始状态,当中断程序中需要执行浮点运算时,这两个函数是很有用的。
注: Keil uVision3中的math.h库中,不包含此函数。
3绝对地址访问 absacc.h
#define CBYTE ((unsigned char volatile code *) 0)
#define DBYTE ((unsigned char volatile data *) 0)
#define PBYTE ((unsigned char volatile pdata *) 0)
#define XBYTE ((unsigned char volatile xdata *) 0)
功能:CBYTE 寻址 CODE区
DBYTE 寻址 DATA区
PBYTE 寻址 XDATA(低256)区
XBYTE 寻址 XDATA区
例: 如下指令在对外部存储器区域访问地址0x1000
xvar=XBYTE[0x1000];
XBYTE[0x1000]=20;
#define CWORD ((unsigned int volatile code *) 0)
#define DWORD ((unsigned int volatile data *) 0)
#define PWORD ((unsigned int volatile pdata *) 0)
#define XWORD ((unsigned int volatile xdata *) 0)
功能:与前面的一个宏相似,只是它们指定的数据类型为unsigned int .。
通过灵活运用不同的数据类型,所有的8051地址空间都是可以进行访问。
如
DWORD[0x0004]=0x12F8;
即内部数据存储器中(0x08)=0x12; (0x09)=0xF8
4 内部函数 intrins.h
extern unsigned char _cror_ (unsigned char var, unsigned char n);
extern unsigned int _iror_ (unsigned int var, unsigned char n);
extern unsigned long _lror_ (unsigned long var, unsigned char n);
功能:将变量var 循环右移 n 位。
上三个函数的区别在于,参数及返回值的类型不同
extern unsigned char _crol_ (unsigned char var, unsigned char n);
extern unsigned int _irol_ (unsigned int var, unsigned char n);
extern unsigned long _lrol_ (unsigned long var, unsigned char n);
功能:将变量var 循环左移 n 位。
上三个函数的区别在于,参数及返回值的类型不同
例如:
#include<intrins.h>
void main()
{
unsigned int y;
y=0x0ff0;
y=_irol_(y,4); //y=0xff00
y=_iror_(y,4); //y=0x0ff0
}
void _nop_(void);
功能:_nop_产生一个8051单片机的NOP指令,C51编译器在程序调用_nop_ 函数的地方,直接产生一条NOP指令。
- Chen
-
为了你调用函数
- 善士六合
-
预定义
c语言位变量定义
在c语言中定义bit型变量,可以使用位域来自定义。位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为: struct 位域结构名 { 位域列表 };其中位域列表的形式为: 类型说明符 位域名:位域长度;示例:通过位域来计算IEEE754浮点数标准中,单精度浮点数的最大值、最小值以及最小弱规范数。#include <stdio.h>typedef struct FP_SINGLE{unsigned __int32 fraction : 23;unsigned __int32 exp : 8;unsigned __int32 sign : 1;} fp_single;int main(){float x;fp_single * fp_s = (fp_single *)&x;fp_s->sign = 0;fp_s->exp = 0xfe;fp_s->fraction = 0x7fffff;printf ("float 最大数: %le ",(double)x);fp_s->sign = 0;fp_s->exp = 0x1;fp_s->fraction = 0x0;printf ("float 最小数: %le ",(double)x);fp_s->sign = 0;fp_s->exp = 0;fp_s->fraction = 0x1;printf ("float 最小弱规范数:%le ",(double)x);return 0;}2023-06-10 18:51:021
位变量与字节变量的区别 BIT与EQU的区别
bit用于定义位变量,处于内部RAM的位寻址区,取值为0或1;EQU是将一个常数或汇编符号赋给字符名,相当于C语言的#define。2023-06-10 18:51:091
位变量bit和sbit有什么用?
定义特殊功能寄存器的位变量,bit和sbit都是C51扩展的变量类型。C语言是一门面向过程、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括一些类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。扩展资料:c语言语言特点:1、丰富的数据类型C语言包含的数据类型广泛,不仅包含有传统的字符型、整型、浮点型、数组类型等数据类型,还具有其他编程语言所不具备的数据类型,其中以指针类型数据使用最为灵活,可以通过编程对各种数据结构进行计算。2、丰富的运算符c语言包含34个运算符,它将赋值、括号等均视作运算符来操作,使C程序的表达式类型和运算符类型均非常丰富。3、可对物理地址进行直接操作C语言允许对硬件内存地址进行直接读写,以此可以实现汇编语言的主要功能,并可直接操作硬件。c语言不但具备高级语言所具有的良好特性,又包含了许多低级语言的优势,故在系统软件编程领域有着广泛的应用。4、代码具有较好的可移植性c语言是面向过程的编程语言,用户只需要关注所被解决问题的本身,而不需要花费过多的精力去了解相关硬件,且针对不同的硬件环境,在用C语言实现相同功能时的代码基本一致,不需或仅需进行少量改动便可完成移植,这就意味着,对于一台计算机编写的C程序可以在另一台计算机上轻松地运行,从而极大的减少了程序移植的工作强度。参考资料来源:百度百科-c语言2023-06-10 18:51:271
plc控制命令中,位变量是什么意思?
移动的电角度所对应的变量位2023-06-10 18:51:462
单片机中怎么声明位变量?就是仅有一位的变量那种,是bit a吗?
是sbit如sbit led=P0^1;2023-06-10 18:51:552
位变量是什么
bit 是单片机 C 语言中的一种数据类型bit 位标量是 c51 编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义 位指针,也不能定义位数组。它的值是一个二进制位,不是 0 就是 1,类似一些高级语 言中的 Boolean 类型中的 True 和 False。数据类型为 bit 的变量就是位变量2023-06-10 18:52:061
什么是位变量
编程简述:返回指定套接口上一个重叠操作的结果。 #include <winsock2.h> BOOL WSAAPI WSAGetOverlappedResult( SOCKET s, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags );s:标识套接口。这就是调用重叠操作(WSARecv()、 WSARecvFrom()、WSASend()、WSASendTo() 或 WSAIoctl())时指定的那个套接口。lpOverlapped:指向调用重叠操作时指定的WSAOVERLAPPED结构。lpcbTransfer:指向一个32位变量,该变量用于存放一个发送或接收操作实际传送的字节数,或WSAIoctl()传送的字节数。fWait:指定函数是否等待挂起的重叠操作结束。若为真TRUE则函数在操作完成后才返回。若为假FALSE且函数挂起,则函数返回FALSE,WSAGetLastError()函数返回 WSA_IO_INCOMPLETE。lpdwFlags:指向一个32位变量,该变量存放完成状态的附加标志位。如果重叠操作为 WSARecv()或WSARecvFrom(),则本参数包含lpFlags参数所需的结果。返回值: 如果函数成功,则返回值为真TRUE。它意味着重叠操作已经完成,lpcbTransfer所指向的值已经被刷新。应用程序可调用WSAGetLastError()来获取重叠操作的错误信息。 如果函数失败,则返回值为假FALSE。它意味着要么重叠操作未完成,要么由于一个或多个参数的错误导致无法决定完成状态。失败时,lpcbTransfer指向的值不会被刷新。应用程序可用WSAGetLastError()来获取失败的原因。错误代码:WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。WSAENETDOWN 网络子系统失效。WSAENOTSOCK 描述字不是一个套接口。WSA_INVALID_HANDLE WSAOVERLAPPED结构的hEvent域未包含一个有效的事件对象句柄。WSA_INVALID_PARAMETER 有不可接受的参数。WSA_IO_INCOMPLETE fWait假FALSE且输入/输出操作尚未完成。另请参阅: WSACreateEvent(), WSAWaitForMultipleEvents(),WSARecv(), WSARecvFrom(), WSASend(), WSASendTo(),WSAConnect(), WSAAccept(), WSAIoctl().2023-06-10 18:52:152
单片机(仅有一位的那种)怎么声明位变量?
是的,对于C51单片机来说,以下有以下类型变量:bit a 1位unsigned char a,或者char a 8位unsigned short a 或者 short a 16位unsigned long a或者 long a 32位unsigned int a 或者 int a 16位,注意,int是与编译器有关的,对于 C51,int等效于shortfloat 或者 double 对于 51来说,都是一样的,32位。2023-06-10 18:52:431
单片机c语言位变量取反
a=~a;2023-06-10 18:52:534
位变量和特殊功能寄存器变量有什么作用?
作用是对片内各功能模块进行管理、控制和监视。通过特殊功能寄存器变量可访问MCS51系列单片机的特殊功能寄存器,访问时需通过sfr或sfr16类型说明符进行定义,定义时需指明它们所对应的特殊功能寄存器的地址即可。2023-06-10 18:53:001
sbit led1 = P1^0是什么意思
sbit led1 = P1^0 位设置,将发光二极管 led1 接 P1口 0 位端,用以控制 led1 的亮灭。2023-06-10 18:53:233
单片机汇编中,flag bit 00H是什么意思?
地址设为02023-06-10 18:53:396
c 语言中 bit与sbit的区别
C51编程中有两个位变量的申明语句即:sbit 和 bitsbit申明一个特殊功能的位变量,该位变量地址是确定的,比如sbit p10=P1^0;bit申明一个通用的位变量,该位变量的地址是可变的,范围在20H~2FH(十六进制)之间,其位地址范围为:00H~FFH2023-06-10 18:54:077
单片机C51编程中bdata的问题
在51中的位变量包含2类,一类是特殊功能寄存器中的可位寻址的位,比如EA,TR0等;这部分位在C中通过sbit来特殊声明,比如sbit Beep=P1^0; ;另一种即为bdata存储模式的位变量。 bdata是布尔变量的存储方式,表示位变量存储在位于单片机内部RAM字节地址0x20~0x2F的16个字节中,每个字节8位,共计16x8=128个可寻址位,位地址从0x00~0x7F。bdata所指只包含这个区域。 其实一般而言不用去特别声明位变量存储模式,比如bit bdata flag; ,在C51中普通的bit变量只能存放在bdata中,所以只需要bit flag这样去定义变量就行了。关于bit型变量的应用,:1、可以作为参数传递:比如uchar test(bit flag){ if(flag) {//传递来的是真则返回3, return 3; } else {//是假则返回2 return 2; }}main(){ uchar x; bit flag = 1; x = test(falg);}2、可以作为函数的返回值bit test1(uchar a,uchar b){ if(a>b) {//如果a>b则返回真,否则返回假 return 1; } else { return 0; }}main(){ bit flag; flag = test1(2,3);}3、不能使用的场合:C51中没有位变量指针一说,比如 bit bdata *flag1;的定义就是非法的。位变量也不能定义位数组,比如 bit bdata flag[8]也不允许。 另外,返回值采用位变量有两种情况也是不允许的:一种是在函数中禁止使用中断时,第二则是函数中有类似using x这种寄存器组切换时。关于这两种情况我没验证过,没有感性认识,所以不能给你举例说明了,总之在使用中断时慎用返回位变量的函数。 bit变量应用最多的情况:执行一个函数,只是想知道操作是否成功,这时就可以用bit变量作为返回值,这样占用资源少,判断起来也快。当然,如果返回值是char型,判断速度上和bit型差不多,但如果是int型,由于是双字节,就要多花些时间了。2023-06-10 18:54:461
如何定义内部RAM的可位寻址区的字符变量? 有什么意义
1、C51中要定义内部RAM的位寻区的位作字符变量,用bit语句,bit work;程序中就可以用work变量了,而变量的位地址是系统自动分配,但要清楚,这个位变量取值只有0和1,一般可作为标志位。 2、8051本身包含数据RAM,所以叫片内RAM,另外,51可以外挂 RAM芯片来扩展 RAM ,那是片外RAM。2023-06-10 18:55:131
西门子PLC 中的IB、QB、VB、MB、SMB、SB、LB、AC各代表什么意思啊?特别是AC可以存储什么样的数据?
楼上的回答正确2023-06-10 18:55:246
bit定义的位变量地址空间是多少
比如:typedef union aa{ struct { char bit0:1; char bit1:1; char bit2:1; char bit3:1; char bit4:1; char bit5:1; char bit6:1; char bit7:1; }; char bit;}AA;这样 位变量的地址空间就是你定义一个AA联合体变量的空间AA union_aa; 那么位变量的地址空间就是union_aa 了啊。2023-06-10 18:56:011
51单片机有没有位变量?
操,学汇编还TM将什么变量变量是高级语言的产物,汇编中只有数据2023-06-10 18:56:115
sbit是char型变量?
不是,sbit是位定义2023-06-10 18:56:402
位地址和字节地址有何区别
通俗易懂而不严谨的回答:一个单元=一个字节,一个字节包含八个位,一个位的内容可以是0或1(这一段不严谨勿喷,以下举例)比如:累加器A是个八位寄存器,也就是可以存一个八位二进制数AT89S52单片机中规定,累加器A的字节地址是E0H,规定它的八个位地址是E7H~E0H如果累加器A此时存数00001011那么,字节地址E0H内容是00001011。位地址E0H的内容是1,位地址E1H的内容是1,位地址E2H的内容是0,位地址E3H的内容是1,位地址E4H,E5H,E6H,E7H的内容都是02023-06-10 18:56:507
请问STM32 中,如何设置一个位变量? ? keil51中是用 bit 加上 变量名字 就可以了!!STM32中呢?
KEIL51使用的不是标准C,而是在C基础上针对51单片机的硬件做了修改的C51。因为51单片机对某些地址可以位寻址,并且要节约每一个资源,所以才有bit这个类型。ARM的资源比51多得多,所以没有对BIT做特别的处理,你可以把普通的字符型变量作为布尔型使用。2023-06-10 18:57:271
8051的内部ram中安排了多少位变量
位变量在20H~2FH(一共16个单元每个单元有8个可位定址的,从00H~7FH),以及SFR里面从80H~F0H都可以2023-06-10 18:57:421
程序中u8是uchar,u16是uint,stm32中bit不识别啊,定义一个bit变量怎么办?
stm32不能定义位变量,虽然有个“位带”但也麻烦,如果你真的想用到位,那就试试“位域”。2023-06-10 18:57:501
单片机C程序模块化的写法,用sbit定义位变量的时候写在写哪个位置?全局变量写在哪?局部变量写在哪?
sbit声明位成员,视作全局。sbit声明位成员建议放在头文件中。全局变量声明在函数体外,引用之前。局部变量声明在函数体内,引用之前。不同编译器采用不同版本的C标准,因此细微之处有些差别。例如Keil C51是基于C90的,局部变量声明只允许放在函数实体语句之前;而其他一些编译器基于较新的C99版本,使用起来较灵活,局部变量可随时声明随时使用;至于C11,目前尚未普及……2023-06-10 18:57:592
请问STM32 中,如何设置一个位变量? ? keil51中是用 bit 加上 变量名字 就可以了!!STM32中呢?
KEIL51使用的不是标准C,而是在C基础上针对51单片机的硬件做了修改的C51。因为51单片机对某些地址可以位寻址,并且要节约每一个资源,所以才有bit这个类型。ARM的资源比51多得多,所以没有对BIT做特别的处理,你可以把普通的字符型变量作为布尔型使用。2023-06-10 18:58:212
单片机C语言怎么声明一个可以位寻址的变量
int *cc;cc=(int*)0X6300 ;*cc=3;2023-06-10 18:58:314
DGUS组态软件中位变量图标怎么用?
控件使用之位变量图标显示1、用到的控件2、添加控件2.1、添加【位变量图标显示】控件3、保存工程及生成文件4、下载文件 1、用到的控件 要想实现点击触控控件切换图标效果,需要用到的显示控件为【位变量图标显示】控件,用到的触控控件为【增量调节】控件2023-06-10 18:58:372
主程序中的bit位变量,子程序模块中如何声明
为了这个问题,浪费好长时间,挤进了脑汁,伤透了脑筋,曾一度有个现在看来应该是挺好笑的想法——怀疑keil不向标准c一样,不能很好的支持多c文件工程,在多c文件共享变量时,尚无法很好处理。不过就在要点发送帖子按的一瞬间,偶却有了灵感,并通过验证,知道如何解决了。然后再接着想下去,通过实验,有个更多收获:1)如果两个或更多c文件都需要使用某非bit型变量,那么声明是应将相应存储类型同时注明,即如果定义“uchar idata cntembuf;”,那么应声明为“extern uchar idata cntembuf;”或者“extern idata cntembuf;”;2)如果是bit型变量,则数据类型“bit”必须注明,而存储类型可以省略;LN认为,keil里之所以将bit变量和其他类型变量分开处理,是keil面向的处理器都是51内核的,而51内核bit变量只存在于特殊功能寄存器和内存的位寻址区(bdata区),而特殊功能寄存器中的位变量若在两个以上文件中使用各各文件都只能用类似于sbit abcd = P1^6;的形式进行声明,并且keil不检测abcd这个位变量在不同文件中是否代替相同位(例如,可以在另一个c文件中声明为:sbit abcd = P0^5;等),这样一来,用extern声明的bit变量就只有在bdata区了,所以,允许在在一个c文件中定义位变量后,在其它c文件中省略“bdata”这个存储类型;而非bit型变量则可以在特殊功能寄存器,内存,外存,所以声明时要使存储类型与定义时的存储类型相同(也可以在定义和声明时都不规定存储类型,而又编译器根据编译模式自动分配)。感觉今天这事真有点搞笑,不过说明:交流是非常有用的。因为尽管帖子未能发出,但是在要跟他人交流时,人会不自觉的将所要描述给他人的问题屡一下头绪,而往往就这么一屡,可能就让自己有了办法。当然很多时候怎么屡也不行,这时候就要靠别人直接教了2023-06-10 18:59:121
c51中位变量能怎么赋值,位变量能比较吗?
格式的问题2023-06-10 18:59:195
stm8s在iar环境下,怎么定义位变量最为方便
struct BitFlag{ unsigned char db0: 1; unsigned char db1: 1; unsigned char db2: 1;}Flag;Flag.db0= 1;2023-06-10 18:59:371
keil中结构体变量能定义位变量吗
标准C的结构体只支持位域(Bit Field)。使用起来是通过掩码或移位实现的,代码效率不高。如果你想实现类似于(unsigned char型变量的最高位也是个bit变量、可以直接访问)这样的需求,可以借助Keil扩展的bdata以及sbit功能实现。2023-06-10 18:59:441
bitflag_1s=01秒的变量什么意思
意思是位变量,定时时间是1秒。bitflag,就是声明了一个位变量。bitflag_1s=01的意思是1秒定时标志,意思是在程序的运行中,让程序能实现不同的操作,不同的操作通常时间先后顺序不等,时间就需要设定,如果时间需要设定为1秒,就用bitflag_1s=01来设定。变量来源于数学,是计算机语言中能储存计算结果或能表示值的抽象概念。2023-06-10 18:59:501
modbus通信,已知三个位变量,怎么把这三个位变量体现在一个16位的数里。
位变量,二进制位吗?那不就是开关量吗,也就是线圈寄存器的数据类型。如果PLC前端设备的三个线圈寄存器连续的话,只写入一个字节八位二进制数就行了,字节的最高位开始的前三个二进制位置0或1就行,写入数量为3。如果不连续,就要三个线圈分别单独写,一次性写入16位数据,可能会改变不需要改变的线圈,从而产生安全隐患。虽然先读取,再更改,再写入可行,但是这样也不安全。2023-06-10 19:00:091
段变量位变量什么意思
位地址是指可以对某些寄存器或存储器的某一位直接操作,这时这些寄存器的某一位都有一个地址,就叫位地址。编程时用不到位地址,直接写该位的名称即可,如 C语言编程直接写TR0=1,TR0=0,EA=0等 汇编语言写SET B P1.0 CLR EX0. TR0 EA P1.0 等即是特殊功能寄存器中的某一位,是位变量。位变量一位二进制变量,如bit A 结果只能 是1或0,当然它是保存在可位寻址的存储器区域如R0 到 R7中的某一位。2023-06-10 19:00:451
51单片机中位地址和位变量是什么意思呢
位地址是指可以对某些寄存器或存储器的某一位直接操作,这些这些寄存器的某一位都有一个地址,就叫位地址。编程时用不到位地址,直接写该位的名称即可,如C语言编程直接写TR0=1,TR0=0,EA=0等汇编语言写SETBP1.0CLREX0.位变量一位二进制变量,如bitA结果只能是1或0,当然它是保存在可位寻址的存储器区域如R0到R7中的某一位。2023-06-10 19:00:541
STM32 C语言中如何定义位变量
可以利用C语言扩展特性定义结构体如下struct {int bit0:1;int bit1:1;...} bitblock;引用 bitblock.bit02023-06-10 19:01:031
C51位变量bit定义
sbit led=P2^1;2023-06-10 19:01:113
c语言中sbit的意思是?
C语言中没有这个关键字,这个是编译器里面的关键字。2023-06-10 19:01:297
关于bit型变量的用法,说法正确的
什么语言的位变量?2023-06-10 19:02:122
sbit在单片机中的表示和作用?
我只知道是位定义,如 sbit a=P0^0; 就表示a代表P0^0口a=1; P0^0口就输出高电平2023-06-10 19:02:445
单片机(仅有一位的那种)怎么声明位变量?
是的,对于C51单片机来说,以下有以下类型变量:x0dx0abita1位x0dx0aunsignedchara,或者chara8位x0dx0aunsignedshorta或者shorta16位x0dx0aunsignedlonga或者longa32位x0dx0aunsignedinta或者inta16位,注意,int是与编译器有关的,对于C51,int等效于shortx0dx0afloat或者double对于51来说,都是一样的,32位。2023-06-10 19:03:201
单片机汇编中,flag bit 00H是什么意思?
相当于起个小名一般写在程序最前当需要修改时不需要把程序中的所有FLAG都改动只要改00H就好很方便2023-06-10 19:03:293
数组的数据类型可否是位变量
当然可以,但是后面一定要对变量赋值数组里的内容还有数组长度都可以是变量2023-06-10 19:03:561
sbit led1 = P1^0是什么意思
sbit led1 = P1^0 含义:是将发光二极管 led1 接 P1口 0 位端,用以控制 led1 的亮灭。sbit是定义特殊功能寄存器的位变量。bit和sbit都是C51扩展的变量类型。典型应用是:sbit P0_0=P0^0;//即定义P0_0为P0口的第1位,以便进行位操作。bit和int char之类的差不多,只不过char=8位, bit=1位而已。都是变量,编译器在编译过程中分配地址。扩展资料在C语言里,如果直接写P1.0,C编译器并不能识别,而且P1.0也不是一个合法的C语言变量名,所以得给它另起一个名字,这里起的名为P1_0,sbit的用法有三种:第一种方法:sbit 位变量名=地址值第二种方法:sbit 位变量名=SFR名称^变量位地址值第三种方法:sbit 位变量名=SFR地址值^变量位地址值如定义PSW中的OV可以用以下三种方法:sbit OV=0xd2 (1)说明:0xd2是OV的位地址值sbit OV=PSW^2 (2)说明:其中PSW必须先用sfr定义好sbit OV=0xD0^2 (3)说明:0xD0就是PSW的地址值因此这里用sbit P1_0=P1^0;就是定义用符号P1_0来表示P1.0引脚,如果你愿意也可以起P10一类的名字,只要下面程序中也随之更改就行了。参考资料:百度百科sbit2023-06-10 19:04:051
如题,KeilC51位变量能不能定义数组
试试呗我的结论是不行 会报错 error C168: array of bit 手册描述:An array may not have type bit as its basic type. This limitation is imposed by the architecture of the 8051.2023-06-10 19:04:171
单片机那个sbit是什么意思,位声明是什么
bit和sbit都是C51扩展的变量类型。定义特殊功能寄存器的位变量。bit和sbit都是C51扩展的变量类型。典型应用是:sbit P0_0=P0^0;//即定义P0_0为P0口的第1位,以便进行位操作。在C语言里,如果直接写P1.0,C编译器并不能识别,而且P1.0也不是一个合法的C语言变量名,所以得给它另起一个名字,这里起的名为P1_0,可是P1_0是不是就是P1.0呢?你这么认为,C编译器可不这么认为,所以必须给它们建立联系,这里使用了Keil C的关键字sbit来定义,sbit的用法有三种:第一种方法:sbit 位变量名=地址值第二种方法:sbit 位变量名=SFR名称^变量位地址值第三种方法:sbit 位变量名=SFR地址值^变量位地址值如定义PSW中的OV可以用以下三种方法:sbit OV=0xd2 (1)说明:0xd2是OV的位地址值sbit OV=PSW^2 (2)说明:其中PSW必须先用sfr定义好sbit OV=0xD0^2 (3)说明:0xD0就是PSW的地址值因此这里用sbit P1_0=P1^0;就是定义用符号P1_0来表示P1.0引脚,如果你愿意也可以起P10一类的名字,只要下面程序中也随之更改就行了。单片机学习最好有自己的单片机开发板,这样学习效率会更好,看视频教程,目前比较主流的吴鉴鹰单片机开发板适合学习单片机用2023-06-10 19:04:351
如何定义内部RAM的可位寻址区的字符变量?
C51中要定义内部RAM的位寻区的位作字符变量,用bit语句,例如bit work;程序中就可以用work变量了,而变量的位地址是系统自动分配,但要清楚,这个位变量取值只有0和1,一般可作为标志位。2023-06-10 19:04:431
51单片机能不能定义位数组? 比如:bit i;//定义一个位变量i
不可。位寻址,只能使用直接寻址。就像特殊功能寄存器一样,不可用数组。2023-06-10 19:04:521
c语言中bit和sbit的区别哪些
c语言中bit和sbit的区别哪些1 1.bit和sbit都是C51扩展的变量类型。 bit和int char之类的差不多,只不过char=8位, bit=1位而已。都是变量,编译器在编译过程中分配地址。除非你指定,否则这个地址是随机的。这个地址是整个可寻址空间,RAM+FLASH+扩展空间。bit只有0和1两种值,意义有点像Windows下VC中的BOOL。 sbit是对应可位寻址空间的一个位,可位寻址区:20H~2FH。一旦用了sbi xxx = REGE^6这样的定义,这个sbit量就确定地址了。sbit大部分是用在寄存器中的,方便对寄存器的某位进行操作的。 2.bit位标量 bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。它的值是一个二进制位,不是0就是1,类似一些高级语言中的Boolean类型中的True和False。 3.sfr特殊功能寄存器 sfr也是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfr P1 = 0×90这一句定P1为P1端口在片内的寄存器,在后面的语句中我们用以用P1 = 255(对P1端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。 sfr P1 = 0×90; //定义P1 I/O 口,其地址90H sfr 关键定后面是一个要定义的名字,可任意选取,但要符合标识符的命名规则,名字最好有一定的含义如P1 口可以用P1 为名,这样程序会变的好读好多.等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH),具体可查看附录中的相关表. sfr 是定义8 位的特殊功能寄存器而sfr16 则是用来定义16 位特殊功能寄存器, 如8052 的T2 定时器,可以定义为: sfr16 T2 = 0xCC; //这里定义8052 定时器2,地址为T2L=CCH,T2H=CDH 用sfr16 定义16 位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上.注意的是不能用于定时器0 和1 的定义. sbit 可定义可位寻址对象.如访问特殊功能寄存器中的某位.其实这样应用是经常要用的如要访问P1 口中的第2 个引脚P1.1.我们可以照以下的方法去定义: (1) sbit 位变量名=位地址 sbit P1_1 = Ox91; 这样是把位的绝对地址赋给位变量.同sfr 一样sbit 的位地址必须位于80H-FFH 之间. (2) sbit 位变量名=特殊功能寄存器名位位置 sft P1 = 0×90; sbit P1_1 = P1 ^ 1; //先定义一个特殊功能寄存器名再指定位变量名所在的位置,当可寻址位位于特殊功能寄存器中时可采用这种方法 (3) sbit 位变量名=字节地址位位置 sbit P1_1 = 0×90 ^ 1; 这种方法其实和2 是一样的,只是把特殊功能寄存器的位址直接用常数表示. 在C51存储器类型中提供有一个bdata 的存储器类型,这个是指可位寻址的数据存储器,位于单片机的可位寻址区中,可以将要求可位录址的数据定义为bdata,如: unsigned char bdata ib; //在可位录址区定义ucsigned char 类型的变量ib int bdata ab[2]; //在可位寻址区定义数组ab[2],这些也称为可寻址位对象 sbit ib7=ib^7 //用关键字sbit 定义位变量来独立访问可寻址位对象的其中一位 sbit ab12=ab[1]^12; 操作符”^”后面的位位置的最大值取决于指定的基址类型,char0-7,int0-15,long0-31.sfr 并标准C 语言的关键字,而是Keil 为能直接访问80C51 中的`SFR 而提供了一个新的关键词,其用法是: sfrt 变量名=地址值。 2)符号P1_0 来表示P1.0 引脚。 在C 语言里,如果直接写P1.0,C 编译器并不能识别,而且P1.0 也不是一个合法的C语言变量名,所以得给它另起一个名字,这里起的名为P1_0,可是P1_0 是不是就是P1.0呢?你这么认为,C 编译器可不这么认为,所以必须给它们建立联系,这里使用了Keil C的关键字sbit 来定义,sbit 的用法有三种: 第一种方法:sbit 位变量名=地址值 第二种方法:sbit 位变量名=SFR 名称^变量位地址值 第三种方法:sbit 位变量名=SFR 地址值^变量位地址值 如定义PSW 中的OV 可以用以下三种方法: sbit OV=0xd2 (1)说明:0xd2 是OV 的位地址值 sbit OV=PSW^2 (2)说明:其中PSW 必须先用sfr 定义好 sbit OV=0xD0^2 (3)说明:0xD0 就是PSW 的地址值 因此这里用sfr P1_0=P1^0;就是定义用符号P1_0 来表示P1.0 引脚,如果你愿意也可以起P10 一类的名字,只要下面程序中也随之更改就行了。 4.sfr16 16位特殊功能寄存器 sfr16占用两个内存单元,值域为0~65535。sfr16和sfr一样用于操作特殊功能寄存器,所不同的是它用于操作占两个字节的寄存器,好定时器T0和T1。 5.sbit可录址位 sbit同位是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。如先前我们定义了 sfr P1 = 0×90; //因P1端口的寄存器是可位寻址的,所以我们可以定义 sbit P1_1 = P1^1; //P1_1为P1中的P1.1引脚 //同样我们可以用P1.1的地址去写,如sbit P1_1 = 0×91; 这样我们在以后的程序语句中就可以用P1_1来对P1.1引脚进行读写操作了。通常这些可以直接使用系统提供的预处理文件,里面已定义好各特殊功能寄存器的简单名字,直接引用可以省去一点时间,我自己是一直用的。当然您也可以自己写自己的定义文件,用您认为好记的名字。 c语言中bit和sbit的区别哪些2 bit和sbit这两者不是C语言里面的,而是C51里面的; bit和sbit的区别在于两者功能不同,具体如下: bit是变量类型,相当于boot 只占一个位,最多可定128个bit变量,而sbit是给可位寻址的变量的某一个位定个别名,不另占空间; 扩展资料: bit定义: 比特是英文 binary digit的缩写,比特是表示信息的最小单位,是二进制数的一位包含的信息或2个选项中特别指定1个的需要信息量,一般来说,n比特的信息量可以表现出2的n次方种选择; sbit定义: sbit是定义特殊功能寄存器的位变量,bit和sbit都是C51扩展的变量类型,应用如sbit P0_0=P0^0;//即定义P0_0为P0口的第1位,以便进行位操作,bit和int char之类的差不多,只不过char=8位, bit=1位而已,都是变量,编译器在编译过程中分配地址;2023-06-10 19:05:011
51单片机能不能定义位数组? 比如:bit i;//定义一个位变量i
不可。位寻址,只能使用直接寻址。就像特殊功能寄存器一样,不可用数组。2023-06-10 19:05:141