STC89C52RC单片机额外篇 | 04 - 认识头文件<intrins.h>与_nop_函数

Posted Neutionwei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STC89C52RC单片机额外篇 | 04 - 认识头文件<intrins.h>与_nop_函数相关的知识,希望对你有一定的参考价值。

1 <intrins.h>头文件

头文件<intrins.h>在我们51单片机日常开发中经常使用,特别是_nop_()函数,以下是<intrins.h>的内容:

/*--------------------------------------------------------------------------
INTRINS.H

Intrinsic functions for C51.
Copyright (c) 1988-2010 Keil Elektronik GmbH and ARM Germany GmbH
All rights reserved.
--------------------------------------------------------------------------*/

#ifndef __INTRINS_H__
#define __INTRINS_H__

#pragma SAVE

#if defined (__CX2__)
#pragma FUNCTIONS(STATIC)
/* intrinsic functions are reentrant, but need static attribute */
#endif

extern void          _nop_     (void);
extern bit           _testbit_ (bit);
extern unsigned char _cror_    (unsigned char, unsigned char);
extern unsigned int  _iror_    (unsigned int,  unsigned char);
extern unsigned long _lror_    (unsigned long, unsigned char);
extern unsigned char _crol_    (unsigned char, unsigned char);
extern unsigned int  _irol_    (unsigned int,  unsigned char);
extern unsigned long _lrol_    (unsigned long, unsigned char);
extern unsigned char _chkfloat_(float);
#if defined (__CX2__)
extern int           abs       (int);
#endif
#if !defined (__CX2__)
extern void          _push_    (unsigned char _sfr);
extern void          _pop_     (unsigned char _sfr);
#endif

#pragma RESTORE

#endif


Intrinsic functions for C51.翻译过来看,里面的函数都是C51的内在函数。当然我们是看不了函数的原型,它们都是以接口的形式展现给大家,就像大家在编写C程序调用头文件<stdio.h>的时候一样,我们只能可以看到<stdio.h>有哪些函数可以给我们用,但是看不到这些函数的具体实现,如printf函数。

下面给个表格大家了解各个函数使用:

接口函数作用
_nop_();空操作指令:延时一个机器周期,相当于直接执行NOP指令
_testbit_(bit);_testbit_产生一个JBC 指令,该函数测试一个位,当置位时返回1,否则返回0。如果该位置为1,则将该位复位为0。8051 的JBC 指令即用作此目的。_testbit_只能用于可直接寻址的位;在表达式中使用是不允许的
ret = _cror_(var, n);无符号字符型循环右移函函数:var是需要位移的变量,n是循环右移的位数,ret是移动指定位数后的结果
ret = _iror_(var, n);无符号整数循环右移函函数:var是需要位移的变量,n是循环右移的位数,ret是移动指定位数后的结果
ret = _lror_ (var, n);无符号长整数循环右移函函数:var是需要位移的变量,n是循环右移的位数,ret是移动指定位数后的结果
ret = _crol_ (var, n);无符号字符型循环左移函函数:var是需要位移的变量,n是循环右移的位数,ret是移动指定位数后的结果
ret = _irol_(var, n);无符号整数循环左移函函数:var是需要位移的变量,n是循环右移的位数,ret是移动指定位数后的结果
ret = _lrol_ (var, n);无符号长整数循环左移函函数:var是需要位移的变量,n是循环右移的位数,ret是移动指定位数后的结果

一般我们一般用得比较多的是_nop__cror__crol_ 函数!下面我讲解一下_nop_函数。

2 _nop_函数

_nop_函数对应51单片机汇编语言中NOP指令,它是在51单片机中用的延时函数,表示执行一条没有什么意义的指令,延时一个指令周期,有的指令周期是两个或两个以上的机械周期,但是_nop_();指令需要的只是一个机械周期也就是12个时钟周期(震荡周期)。

这里有个小知识:

51单片机中,1个机械周期 = 12个时钟周期 = 12 * (1 / f)。(f 为晶振频率)。

如果只用的是12MHZ的晶振,那么 一个机械周期就是1us;也就是说:

_nop_(); 延迟时间为 1us。可以较为精确得控制延迟时间。

NOP指令的作用:

  • 通过NOP指令的填充(NOP指令一个字节),使指令按字对齐,从而减少取指令时的内存访问次数(一般用来内存地址偶数对齐,比如有一条指令,占3字节,这时候使用NOP指令,CPU就可以从第4个字节处读取指令)。
  • 通过NOP指令产生一定的延迟。
  • I/O传输时,也会用一下NOP指令,等待缓冲区清空,总线恢复。
  • 清除由上一个算术逻辑指令设置的标志位。

以上是关于STC89C52RC单片机额外篇 | 04 - 认识头文件<intrins.h>与_nop_函数的主要内容,如果未能解决你的问题,请参考以下文章

STC89C52RC单片机额外篇 | 02 - 认识串行通信波特率以及数据包

STC89C52RC单片机额外篇 | 06 - 认识高内聚低耦合的模块化编程

STC89C52RC单片机额外篇 | 05 - 把NOP指令封装成微秒级延时函数

STC89C52RC单片机额外篇 | 03 - 认识C51编译器支持的数据类型

STC89C52RC单片机额外篇 | 07 - 使用Keil搭建与管理项目式多文件工程

STC89C52RC单片机额外篇 | 08 - 认识I2C协议以及E2PROM存储器(AT24Cxx)