令人头大的单片机延时----这里转一篇关于延时函数的文章看看

2023-05-16

标题:【转】关于nop()函数
2011-02-11 23:49:29

nop函数可以用来延时,请问1个NOP延时多少时间,怎么计算? 

附一段说明:
void _nop( void );
A NOP instruction is generated, before and behind the nop instruction the peephole is flushed. Code generation for _nop() is exactly the same as the
following inline assembly.
#pragma asm
nop ; inline nop instruction
#pragma endasm
Returns nothing.
value = P0; /* read from port P0 */
MOV R12,P0
_nop(); /* delay for one cycle */
NOP
P1 = value; /* write to port P1 */
MOV P1,R12

 

单片机c语言中nop函数的使用方法和延时计算默认分类 2010-08-28 15:39:40 阅读41 评论0   字号:大中小 订阅 .

标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。
这在汇编语言中很容易实现,写几个nop就行了。

在keil C51中,直接调用库函数:
#include<intrins.h>          // 声明了void _nop_(void);

_nop_();                               // 产生一条NOP指令

    作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。
     NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。


对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。 
在选择C51中循环语句时,要注意以下几个问题 
第一、定义的C51中循环变量,尽量采用无符号字符型变量。 
第二、在FOR循环语句中,尽量采用变量减减来做循环。 
第三、在do…while,while语句中,循环体内变量也采用减减方法。 
这因为在C51编译器中,对不同的循环方法,采用不同的指令来完成的。

下面举例说明: 
unsigned char I; 
for(i=0;i<255;i++); 
  
unsigned char I; 
for(i=255;i>0;i--); 
其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令: 
MOV 09H,#0FFH 
LOOP:            DJNZ 09H,LOOP 
指令相当简洁,也很好计算精确的延时时间。 
同样对do…while,while循环语句中,也是如此 
例: 
unsigned char n; 
n=255; 
do{n--} 
while(n); 
或 
n=255; 
while(n) 
{n--}; 
这两个循环语句经过C51编译之后,形成DJNZ来完成的方法,
故其精确时间的计算也很方便。


其三:对于要求精确延时时间更长,这时就要采用循环嵌套
的方法来实现,因此,循环嵌套的方法常用于达到ms级的延时。 
对于循环语句同样可以采用for,do…while,while结构来完
成,每个循环体内的变量仍然采用无符号字符变量。 
unsigned char i,j 
for(i=255;i>0;i--) 
for(j=255;j>0;j--); 
或 
unsigned char i,j 
i=255; 
do{j=255; 
    do{j--} 
    while(j); 
    i--; 
    } 
while(i); 
或 
unsigned char i,j 
i=255; 
while(i) 
{j=255; 
while(j) 
{j--}; 
i--; 

这三种方法都是用DJNZ指令嵌套实现循环的,由C51编
译器用下面的指令组合来完成的 
MOV R7,#0FFH 
LOOP2:        MOV R6,#0FFH 
LOOP1:        DJNZ R6,LOOP1 
DJNZ R7,LOOP2 
这些指令的组合在汇编语言中采用DJNZ指令来做延时用,
因此它的时间精确计算也是很简单,假上面变量i的初
值为m,变量j的初值为n,则总延时时间为:m×(n×T+T),
其中T为DJNZ指令执行时间(DJNZ指令为双周期指令)。
这里的+T为MOV这条指令所使用的时间。 
同样对于更长时间的延时,可以采用多重循环来完成。
只要在程序设计循环语句时注意以上几个问题。


下面给出有关在C51中延时子程序设计时要注意的问题 
1、在C51中进行精确的延时子程序设计时,尽量不要
或少在延时子程序中定义局部变量,所有的延时子程
序中变量通过有参函数传递。 
2、在延时子程序设计时,采用do…while,结构做循
环体要比for结构做循环体好。 
3、在延时子程序设计时,要进行循环体嵌套时,采用
先内循环,再减减比先减减,再内循环要好。 
unsigned char delay(unsigned char i,unsigned char j,unsigned char k) 
{unsigned char b,c; 
    b="j"; 
    c="k"; 
    do{ 
do{ 
    do{k--}; 
    while(k); 
    k="c"; 
    j--;}; 
while(j); 
j=b; 
i--;}; 
    while(i); 

这精确延时子程序就被C51编译为有下面的指令组合完成 
delay延时子程序如下: 
                MOV      R6,05H 
                MOV      R4,03H 
C0012:        DJNZ      R3, C0012 
                MOV      R3,04H 
                DJNZ      R5, C0012 
                MOV      R5,06H 
                DJNZ      R7, C0012 
                RET    
假设参数变量i的初值为m,参数变量j的初值为n,参数
变量k的初值为l,则总延时时间为:l×(n×(m×T+2T)+2T)+3T,
其中T为DJNZ和MOV指令执行的时间。当m=n=l时,精确延时为9T,最短;
当m=n=l=256时,精确延时到16908803T,最长。 
  
-----------------------------------------------------------------------------------------

采用软件定时的计算方法

利用指令执行周期设定,以下为一段延时程序:      
指令            周期  
MOV            1
DJNZ            2
NOP            1
采用循环方式定时,有程序:
            MOV      R5,#TIME2          ;周期1
LOOP1:      MOV      R6,#TIME1          ; 1
LOOP2:      NOP                        ; 1
      NOP                        ; 1
      DJNZ    R6,LOOP2              ; 2
            DJNZ      R5,LOOP1            ; 2
定时数=(TIME1*4+2+1)*TIM2*2+4

刚刚又学了一条,用_nop_();时记得加上#include  <intrins.h>  头文件

如:
//==================
#include  <intrins.h>  //包含库函数
        ......
        ......
//============
      ......
      ......
    _nop_();          //引用库函数

敬礼。
我一直都是借助仿真软件编。一点一点试时间。

C语言最大的缺点就是实时性差,我在网上到看了一些关于延时的讨论,其中有篇文章

   51单片机 Keil C 延时程序的简单研究,作者:InfiniteSpace Studio/isjfk

写得不错,他是用while(--i);产生DJNZ 来实现精确延时,后来有人说如果while里面不能放其它语句,否则也不行,用do-while就可以,具体怎样我没有去试.所有这些都没有给出具体的实例程序来.还看到一些延时的例子多多少少总有点延时差.为此我用for循环写了几个延时的子程序贴上来,希望能对初学者有所帮助.(晶振12MHz,一个机器周期1us.)

    一. 500ms延时子程序

程序:

    void delay500ms(void)

       {

       unsigned char i,j,k;

        for(i=15;i>0;i--)

        for(j=202;j>0;j--)

        for(k=81;k>0;k--);

       }

产生的汇编:

    C:0x0800    7F0F     MOV      R7,#0x0F

    C:0x0802    7ECA     MOV      R6,#0xCA

    C:0x0804    7D51     MOV      R5,#0x51

    C:0x0806    DDFE     DJNZ     R5,C:0806

    C:0x0808    DEFA     DJNZ     R6,C:0804

    C:0x080A    DFF6     DJNZ     R7,C:0802

    C:0x080C    22       RET     

计算分析:

    程序共有三层循环

    一层循环n:R5*2 = 81*2 = 162us                  DJNZ  2us

    二层循环m:R6*(n+3) = 202*165 = 33330us          DJNZ  2us + R5赋值 1us = 3us

    三层循环: R7*(m+3) = 15*33333 = 499995us        DJNZ  2us + R6赋值 1us = 3us

    循环外:   5us            子程序调用 2us + 子程序返回 2us + R7赋值 1us  = 5us

    延时总时间 = 三层循环 + 循环外 = 499995+5 = 500000us =500ms

计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5

    二. 200ms延时子程序

程序:

void delay200ms(void)

{

       unsigned char i,j,k;

        for(i=5;i>0;i--)

        for(j=132;j>0;j--)

        for(k=150;k>0;k--);

}

产生的汇编

C:0x0800    7F05     MOV      R7,#0x05

C:0x0802    7E84     MOV      R6,#0x84

C:0x0804    7D96     MOV      R5,#0x96

C:0x0806    DDFE     DJNZ     R5,C:0806

C:0x0808    DEFA     DJNZ     R6,C:0804

C:0x080A    DFF6     DJNZ     R7,C:0802

C:0x080C    22       RET

    三. 10ms延时子程序

程序:

void delay10ms(void)

{

       unsigned char i,j,k;

        for(i=5;i>0;i--)

        for(j=4;j>0;j--)

        for(k=248;k>0;k--);

}

产生的汇编

C:0x0800    7F05     MOV      R7,#0x05

C:0x0802    7E04     MOV      R6,#0x04

C:0x0804    7DF8     MOV      R5,#0xF8

C:0x0806    DDFE     DJNZ     R5,C:0806

C:0x0808    DEFA     DJNZ     R6,C:0804

C:0x080A    DFF6     DJNZ     R7,C:0802

C:0x080C    22       RET     

    四. 1s延时子程序

程序:

void delay1s(void)

{

       unsigned char h,i,j,k;

        for(h=5;h>0;h--)

        for(i=4;i>0;i--)

        for(j=116;j>0;j--)

        for(k=214;k>0;k--);

}

产生的汇编

C:0x0800    7F05     MOV      R7,#0x05

C:0x0802    7E04     MOV      R6,#0x04

C:0x0804    7D74     MOV      R5,#0x74

C:0x0806    7CD6     MOV      R4,#0xD6

C:0x0808    DCFE     DJNZ     R4,C:0808

C:0x080A    DDFA     DJNZ     R5,C:0806

C:0x080C    DEF6     DJNZ     R6,C:0804

C:0x080E    DFF2     DJNZ     R7,C:0802

C:0x0810    22       RET

在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

令人头大的单片机延时----这里转一篇关于延时函数的文章看看 的相关文章

  • 1-11 实验9 网络管理实验1 获取自身的和父节点网络地址、MAC地址

    p p p style color rgb 51 51 51 font family Arial font size 14px line height 26px 获取自身的和父节点网络地址 MAC地址 p p style color rgb
  • 1-14 实验11 获取网络拓扑

    获取网络拓扑 1 实验内容 xff1a PC端串口调试助手向协调器发送命名 topology 协调器接受到命令后 xff0c 将网络拓扑信息发送到PC机串口调试助手上 2 知识点 xff1a 在1 11 实验9 网络管理实验1 获取自身和父
  • S 串口编程 详解3 串口的初始化、打开/关闭

    串口编程 详解3 串口的初始化 程序打开串口 xff0c 采用两种方法 xff1a 1 程序启动 xff0c 调用OnInitDialog 函数 xff0c 打开串口 xff0c 缺省串口号为COM1 xff0c 如果COM1不存在或被占用
  • 求关键路径(包含邻接表的建立、拓扑排序)

    include lt stdio h gt include lt stdlib h gt typedef struct node int adjvex 邻接点域 int info 边上的信息 struct node next 指向下一个邻接
  • FPGA串口回环实验

    本文将从个人理解的角度 xff0c 解释FPGA串口通信的原理 xff0c 并进行实战演示 1 写在前面的话 串口通信是初学FPGA必过的一道坎 xff0c 如果能够在不参考任何资料的情况下自己手搓一套串口回环的代码 xff0c Verio
  • Debug Assertion Failed!解决方法详解

    1 野指针 2 内存泄露 解决方法 1 看一看你的程序里是不是有 ASSERT xff08 xff09 或 VERIFY xff08 xff09 语句 这两个宏是用来测试它的参数是否为真的 出现你说的 xff0c 这说明你的指针或表达试有问
  • 用tftp的方式在u_boot下 烧写uImage内核

    用 u boot 进行下载 uImage 一种 kernel 镜像文件 首先 把编译好的 uImage 文件放在 tftpboot 目录下 用网线把开发板和电脑连上 但PC上的网卡显示是没连接的 xff0c 这一点是没有关系的 xff0c
  • 利用NFS服务挂载NFS根文件系统

    嵌入式Linux根文件系统 xff0c 简单地说 xff0c 根文件系统就是一种目录结构 注意根文件系统和普通的文件系统的区别 常见的Linux根文件系统有 xff1a xff08 1 xff09 NFS xff08 网络根文件系统 xff
  • 数据校验之Checksum算法

    校验和 xff08 Checksum xff09 是网络协议使用的数据错误检测方法 xff0c 并且被认为比LRC xff08 纵向冗余校验 xff0c Longitudinal Redundancy Check xff0c LRC xff
  • 位序转字符串的一种高效方法

    include lt stdio h gt include lt stdlib h gt include lt malloc h gt include lt string h gt include lt arpa inet h gt def
  • OpenSIPS实战(一):OpenSIPS使用简介

    1 OpenSIPS是什么 OpenSIPS xff08 Open SIP Server xff09 是一个成熟的开源SIP服务器实现 可以作为SIP代理 路由器 但OpenSIPS不仅仅是一个SIP代理 路由器 xff0c 因为它包含了应
  • Floyd判圈算法(龟兔赛跑算法, Floyd's cycle detection)及其证明

    问题 xff1a 如何检测一个链表是否有环 xff08 循环节 xff09 xff0c 如果有 xff0c 那么如何确定环的起点以及环的长度 空间要求 xff1a 不能存储所经过的的每一个点 举例 xff1a x 0 61 1 x 0 61
  • Ubuntu配置GPU版本pytorch环境(含NVIDIA驱动+Cuda+Cudnn)

    本文更新于2018年8月底 概述 步骤如下 xff1a 1 安装Ubuntu 2 安装NVIDIA 显卡驱动 2 安装NVIDIA Cuda 3 安装NVIDIA CuDNN 4 安装GPU版本的PyTorch 安装Ubuntu 系统版本选
  • PyTorch中的Dataset、Dataloader和_DataloaderIter

    Dataset Pytorch中数据集被抽象为一个抽象类torch utils data Dataset xff0c 所有的数据集都应该继承这个类 xff0c 并override以下两项 xff1a len xff1a 代表样本数量 len
  • 彻底搞懂Lab 颜色空间

    本文参考wikipedia xff0c 并加入了自己的理解 xff0c 有不对的地方多多指教 名称 在开始之前 xff0c 先明确一下Lab颜色空间 xff08 Lab color space xff09 的名字 xff1a Lab的全称是
  • MiniFly微型四轴学习与开发日志(五)——遥控器任务详解

    文章目录 radiolinkTask无线连接任务usblinkTxTask usb发送任务usblinkRxTask usb接收任务commanderTask飞控指令发送任务keyTask按键扫描任务displayTask显示任务confi
  • .与::的使用区别

    今天尝试编写了一个小的Windows应用程序 xff0c 在编写的过程中用到MessageBox函数 但是一直不正确 我当时尝试MessageBox 34 NULL 34 34 Alert 34 34 ERROR 34 MB OK xff0
  • Pytorch中的contiguous理解

    最近遇到这个函数 xff0c 但查的中文博客里的解释貌似不是很到位 xff0c 这里翻译一下stackoverflow上的回答并加上自己的理解 在pytorch中 xff0c 只有很少几个操作是不改变tensor的内容本身 xff0c 而只
  • 一文读懂GAN, pix2pix, CycleGAN和pix2pixHD

    本文翻译 总结自朱俊彦的线上报告 xff0c 主要讲了如何用机器学习生成图片 来源 xff1a Games2018 Webinar 64期 xff1a Siggraph 2018优秀博士论文报告 人员信息 主讲嘉宾 姓名 xff1a 朱俊彦

随机推荐

  • Pytorch中的optimizer

    与优化函数相关的部分在torch optim模块中 xff0c 其中包含了大部分现在已有的流行的优化方法 如何使用Optimizer 要想使用optimizer xff0c 需要创建一个optimizer 对象 xff0c 这个对象会保存当
  • 图像质量评价之结构相似性SSIM(上)

    本文总结归纳自论文 image quality assessment from error visibility to structural similarity 概述 这篇文章主要介绍对图像质量进行打分评价的一个很经典的指数 结构相似性
  • 图像质量评价之结构相似性SSIM(中)

    在上一篇文章中 xff0c 我们介绍了对图像质量进行评价的必要性 主观评价和客观评价的两种标准 xff0c 以及设计符合人类直觉的评价标准的困难性和重要性 本来这篇文章想把我们的主角SSIM讲完 xff0c 但是发现前面需要写的铺垫有点长h
  • CS231n lecture 9:各大经典网络 AlexNet/VGG/GoogleNet/ResNet(上)

    本文翻译总结自CS231n Lecture 9 本篇将深入介绍当前的应用和研究工作中最火的几个CNN网络架构 AlexNet VGGNet GoogleNet和ResNet xff0c 它们都在ImageNet分类任务中有很好的表现 另外
  • STM32c8t6干扰GPS信号的解决方式

    项目目的 xff1a stm32解析GPS报文 xff0c 显示在oled上 项目遇到的问题 xff1a GPS模块接收信号不良 问题表现 xff1a 1 GPS可以搜星 xff0c 户外大约20颗 xff0c 但是锁定不了卫星 2 GPS
  • Rplidar A2 激光雷达使用hector_slam进行建图

    手头上有一个Rplidar A2 激光雷达 xff0c 通过其进行slam建图 xff0c 如下 环境 xff1a 1 Rplidar A2 激光雷达 xff1b 2 笔记本电脑 xff1b 3 Ubuntu 16 04 4 ROS Kin
  • Oracle之常用内置函数

    1 Oracle内置函数 wm concat wm concat 函数是oracle中独有的 mysql中有一个group concat 函数 实现行转列功能 xff0c 即将查询出的某一列值使用逗号进行隔开拼接 xff0c 成为一条数据
  • RRT算法三维避障的MATLAB实现

    RRT算法又称为快速随机扩展数算法 xff0c 是一种普适路径规划算法 xff0c 为什么说是普适算法 xff0c 因为它什么样的苛刻的条件都会极大的可能性找到一条路径 但是这样的算法也往往会伴随缺点 xff1a 1 每次迭代都是在随机找点
  • MiniFly微型四轴学习与开发日志(六)——遥控器任务与系统框架

    文章目录 遥控器任务框架遥控器系统框架 遥控器任务框架 参数配置任务主要功能是保存参数 按键扫描任务主要功能是扫描按键 显示任务主要功能是显示界面 飞控指令发送任务主要功能是将采集摇杆电位器的 AD 值转换为姿态控制命令 xff0c 并以
  • Arduino串口发送与接收16进制数据(HEX)(数据乱码)-JDY-10M组网

    最近使用JDY 10M蓝牙组网 xff0c 需要Arduino收发数据 xff0c 将遇到的一些问题与最终解决方法分享给大家 xff0c 如果内容有问题 xff0c 还请大家指点 1 JDY 10M组网 关于如何JDY 10M如何组网网上介
  • 串口通信协议介绍

    串口通信协议介绍 空闲时 xff1a TX RX为高电平 xff0c 通讯时 xff1a 低电平为起始位 43 送数据位 xff08 从低到高 xff09 43 校验位 43 停止位 常用8N1 0 1 0 1 0 0 0 0 0 0 TX
  • ROS-基础(kinetic---melodic---noetic)

    学习资料参考 xff1a ROS机器人开发实践 胡春旭 目录 工作空间和功能包的创建集成开发环境的搭建话题和服务的实现方法ROS中的命名空间及解析方法ROS分布式通信的方法 热身 常用命令 命令作用catkin create pkg创建功能
  • linux下用多线程实现socket服务器和客户端的异步通信

    前面介绍了用select函数来实现socket的异步收发数据 xff0c 但是select函数也有一些缺陷 xff0c 要使socket能持续地通信 xff0c select必须不停地检测 xff0c 这样进程就会一直阻塞在这里 xff0c
  • SDN之NETCONF Call Home

    本文主要内容都来自于今年二月发布的RFC8071 NETCONF Call Home and RESTCONF Call Home xff0c 该RFC从2015年4月提出到最终发布一共修改了17个版本 xff0c 其间修改内容可以点击查看
  • Command ‘roscore‘ not found, but can be installed with: sudo apt install python-roslaunch

    Command roscore not found but can be installed with sudo apt install python roslaunch roscore 报错 Command 39 roscore 39 n
  • 按键精灵通过抓抓工具来获取坐标位置

    1 按键精灵通过抓抓工具找图 这里我就随便拿一款游戏来测试了 这是一款手游打开之后的界面 xff0c 要求我们点击确定继续现在要求使用脚本在帮我们点击这个确定按钮 我们新建一个脚本 然后打开按键精灵的抓抓工具 然后返回到按键精灵 xff0c
  • 在云服务器上部署项目(上)

    1 购买腾讯云主机 首先我们先了解一下云服务器的概念 云服务器 xff1a 高性能高稳定的云虚拟机 xff0c 可在云中提供弹性可调节的计算容量 xff0c 不让计算能束缚您的想象 xff1b 您可以轻松购买自定义配置的机型 xff0c 在
  • 在云服务器上部署项目(下)

    云服务器上部署项目 xff08 上 xff09 xff1a http blog csdn net gfd54gd5f46 article details 54331207 5 从网上下载jpress开源项目 流程 xff1a 下载jpres
  • 利用String类制作简单的网络爬虫

    网络爬虫 网络爬虫 xff08 又被称为网页蜘蛛 xff0c 网络机器人 xff0c 在FOAF社区中间 xff0c 更经常的称为网页追逐者 xff09 xff0c 是一种按照一定的规则 xff0c 自动地抓取万维网信息的程序或者脚本 另外
  • 令人头大的单片机延时----这里转一篇关于延时函数的文章看看

    标题 xff1a 转 关于nop 函数 2011 02 11 23 49 29 nop函数可以用来延时 xff0c 请问1个NOP延时多少时间 xff0c 怎么计算 xff1f 附一段说明 xff1a void nop void A NOP