单片机5s延时 - CSDN
  • 【51单片机】代码实例

    千次阅读 2019-12-17 11:54:53
    LED灯 —依次点亮 #include<reg51.h> #include<math.h> void delay(unsigned int n) { int i; for(i=0;i<n;i++); } void LED_left_to_right()//从左到右依次点亮 ... unsign...

    LED灯

    —LED灯闪烁

    #include<reg51.h>
    #include<math.h>
    sbit LED=P2^0;
    
    void delay(unsigned int n)
    {
    	unsigned int i;
    	for(i=0;i<n;i++);
    }
    
    void main()
    {	LED=0;
    	while(1)
    	{
    		LED=~LED;
    		delay(20000);
    	}
    }
    

    —流水灯

    #include<reg51.h>
    #include<math.h>
    
    void delay(unsigned int n)
    {
    	int i;
    	for(i=0;i<n;i++);
    }
    
    void LED_flow_ltor()
    {
    	unsigned char cnt=0;
    	unsigned char i=0;
    	unsigned int ADDR;
    	while(1)
    	{
    		ADDR=~(0x01<<cnt);
    		P2=ADDR;
    		delay(20000);
    		cnt++;
    		if(cnt==8)
    		while(1)
    		{
    			P2=ADDR/pow(2,i);
    			delay(20000);
    			i++;
    			if(i==8)
    			{
    			i=0;
    			cnt=0;
    			break;
    			}
    		}
         }
    }
    
    void main()
    {
    	 LED_flow_ltor();  	
    }
    

    —依次点亮

    #include<reg51.h>
    #include<math.h>
    void delay(unsigned int n)
    {
    	int i;
    	for(i=0;i<n;i++);
    }
    
    void LED_left_to_right()//从左到右依次点亮
    {
    	unsigned int ADDR;
    	unsigned char i =1;
    	ADDR=0x01;
    	delay(30000);
    	while(1)
    	{
    		P2=~ADDR;
    		if(i==8)break;
    		delay(30000);
    		ADDR+=pow(2,i);
    		i++;
    	}
    }
    
    void LED_right_to_left()//从右到左依次点亮
    {
    	unsigned int ADDR;
    	unsigned char i =6;
    	ADDR=0x80;
    	delay(20000);
    	while(1)
    	{
    		P2=~ADDR;
    		if(i==-1)break;
    		delay(30000);
    		ADDR+=pow(2,i);
    		i--;
    	}
    }
    
    void main()
    {	   while(1){
      LED_left_to_right();
      LED_right_to_left();
       }
    }
    

    数码管

    —灯管选位

    灯管选位   LSA LSB LSC
    ---------------------1        0   0   02        1   0   03        0   1   04        1   1   05        0   0   16        1   0   17        0   1   18        1   1   1
    

    —从左至右显示0-7

    #include <reg51.h>			 //此文件中定义了单片机的一些特殊功能寄存器
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    
    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    
    u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
    
    void delay(u16 i)
    {
    	while(i--);	
    }
    
    void DigDisplay()
    {
    	u8 i;
    	for(i=0;i<8;i++)
    	{
    		switch(i)	 //位选,选择点亮的数码管,
    		{
    		   case(0):
    				LSA=1;LSB=1;LSC=1; break;//显示第0位
    			case(1):
    				LSA=0;LSB=1;LSC=1; break;//显示第1位
    			case(2):
    				LSA=1;LSB=0;LSC=1; break;//显示第2位
    			case(3):	
    				LSA=0;LSB=0;LSC=1; break;//显示第3位
    			case(4):
    				LSA=1;LSB=1;LSC=0; break;//显示第4位
    			case(5):
    				LSA=0;LSB=1;LSC=0; break;//显示第5位
    			case(6):
    				LSA=1;LSB=0;LSC=0; break;//显示第6位
    			case(7):
    				LSA=0;LSB=0;LSC=0; break;//显示第7位	
    		}
    		P0=smgduan[i];
    		delay(100); //间隔一段时间扫描	
    		P0=0x00;//消隐
    	}
    }
    
    void main()
    {	
    	while(1)
    	{	
    		DigDisplay();  //数码管显示函数	
    	}		
    }
    

    —流水显示相同数字

    #include<reg51.h>
    
    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    unsigned char led[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    void main()
    {
    	unsigned char cnt=0;
    	unsigned char i=0;
    	TMOD=0x01;
    	TH0=0xBB;
    	TL0=0xB8;
    	TR0=1;
    	while(1)
    	{
    		if(TF0==1)
    		{	
    			TF0=0;
    			TH0=0xB8;
    			TL0=0x00;
    			cnt++;
    			if(cnt>=25)
    			{
    			cnt=0;
    			switch(i)
    			{
    			case 1:LSA=0;LSB=0;LSC=0;break;
    			case 2:LSA=1;LSB=0;LSC=0;break;
    			case 3:LSA=0;LSB=1;LSC=0;break;
    			case 4:LSA=1;LSB=1;LSC=0;break;
    			case 5:LSA=0;LSB=0;LSC=1;break;
    			case 6:LSA=1;LSB=0;LSC=1;break;
    			case 7:LSA=0;LSB=1;LSC=1;break;
    			case 8:LSA=1;LSB=1;LSC=1;break;	
    			}
    			P0=led[9];
    			i++;
    			if(i==9)i=1;
    			}
    		}
    	}
    }
    

    —流水显示不同数字

    #include<reg51.h>
    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    unsigned char led[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    void main()
    {
    unsigned char cnt=0;
    
    unsigned char i=0;
    unsigned char sum=0;
    TMOD=0x01;
    TH0=0xBB;
    TL0=0xB8;
    TR0=1;
    while(1)
    {
    	if(TF0==1)
    	{
    		TF0=0;
    		TH0=0xB8;
    		TL0=0x00;
    		cnt++;
    		if(cnt>=50)
    		{
    			cnt=0;
    			switch(i)
    			{
    			case 1:LSA=0;LSB=0;LSC=0;break;
    			case 2:LSA=1;LSB=0;LSC=0;break;
    			case 3:LSA=0;LSB=1;LSC=0;break;
    			case 4:LSA=1;LSB=1;LSC=0;break;
    			case 5:LSA=0;LSB=0;LSC=1;break;
    			case 6:LSA=1;LSB=0;LSC=1;break;
    			case 7:LSA=0;LSB=1;LSC=1;break;
    			case 8:LSA=1;LSB=1;LSC=1;break;
    			}
    			P0=led[sum];
    			i++;
    			if(i==9)i=1,sum++;
    			if(sum==16)sum=0;
    		}
    	 }
     }
    }
    

    —99999999~0秒计时

    #include<reg51.h>
    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    unsigned char led[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    unsigned char ledbuff[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    void main()
    {
    unsigned char i=0;
    unsigned int cnt=0;
    unsigned long sec=99999999;
    
    TMOD=0x01;
    TH0=0xFC;
    TL0=0x67;
    TR0=1;
    while(1)
    {
    	if(TF0==1)
    	{
    		TF0=0;
    		TH0=0xFC;
    		TL0=0x67;
    		cnt++;
    		if(cnt>=1000){
    			cnt=0;
    			sec--;
    			ledbuff[0]=led[sec%10];
    			ledbuff[1]=led[sec/10%10];
    			ledbuff[2]=led[sec/100%10];
    			ledbuff[3]=led[sec/1000%10];
    			ledbuff[4]=led[sec/10000%10];
    			ledbuff[5]=led[sec/100000%10];
    			ledbuff[6]=led[sec/1000000%10];
    			ledbuff[7]=led[sec/10000000%10];}
    		P2=0xFF;//消隐
    		switch(i)
    		   {
    				case 0:LSA=0;LSB=0;LSC=0;i++;P0=ledbuff[0];break;
    				case 1:LSA=1;LSB=0;LSC=0;i++;P0=ledbuff[1];break;
    				case 2:LSA=0;LSB=1;LSC=0;i++;P0=ledbuff[2];break;
    				case 3:LSA=1;LSB=1;LSC=0;i++;P0=ledbuff[3];break;
    				case 4:LSA=0;LSB=0;LSC=1;i++;P0=ledbuff[4];break;
    				case 5:LSA=1;LSB=0;LSC=1;i++;P0=ledbuff[5];break;
    				case 6:LSA=0;LSB=1;LSC=1;i++;P0=ledbuff[6];break;
    				case 7:LSA=1;LSB=1;LSC=1;i=0;P0=ledbuff[7];break;
    				default:break;	
    		   }
         }
       }
    }
    
    

    —0~9999秒计时

    #include<reg51.h>
    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    unsigned char led[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    unsigned char ledbuff[4]={0xFF,0xFF,0xFF,0xFF};
    void main()
    {
    	unsigned char i=0;
    	unsigned int cnt=0;
    	unsigned long sec=0;
    
    	TMOD=0x01;
    	TH0=0xFC;
    	TL0=0x67;
    	TR0=1;
    	while(1)
    	{
    		if(TF0==1)
    		{
    		TF0=0;
    		TH0=0xFC;
    		TL0=0x67;
    		cnt++;
    		if(cnt>=1000){
    			cnt=0;
    			sec++;
    			ledbuff[0]=led[sec%10];
    			ledbuff[1]=led[sec/10%10];
    			ledbuff[2]=led[sec/100%10];
    			ledbuff[3]=led[sec/1000%10];}
    			
    			P2=0xFF;//消隐
    			switch(i)
    			   {
    					case 0:LSA=0;LSB=0;LSC=0;i++;P0=ledbuff[0];break;
    					case 1:LSA=1;LSB=0;LSC=0;i++;P0=ledbuff[1];break;
    					case 2:LSA=0;LSB=1;LSC=0;i++;P0=ledbuff[2];break;
    					case 3:LSA=1;LSB=1;LSC=0;i=0;P0=ledbuff[3];break;
    					default:break;	
    			   }
    	     }
        }
    }
    

    蜂鸣器

    —启动蜂鸣器

    #include <reg51.h>
    sbit beep=P1^5;	
    
    void delay(unsigned char i)
    {
    	while(i--);	
    }
    
    void main()
    {	
    	while(1){
    		beep=~beep;
    		delay(100);//调节蜂鸣器音色
    		}
    }
    

    独立按键

    —控制LED灯的开关

    #include <reg51.h>			 //此文件中定义了单片机的一些特殊功能寄存器
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    # K1=P3^1;
    # K2=P3^0;
    # K3=P3^2;
    # K4=P3^3
    sbit k1=P3^1;	 //定义P31口是k1
    sbit led=P2^0;	 //定义P20口是led
    
    void delay(u16 i)
    {
    	while(i--);	
    }
    
    void keypros()
    {
    	if(k1==0)		  //检测按键K1是否按下
    	{	
    		delay(1000);   //消除抖动 一般大约10ms
    		if(k1==0)	 //再次判断按键是否按下
    		{
    			led=~led;	  //led状态取反
    		}
    		while(!k1);	 //检测按键是否松开
    	}		
    }
    
    void main()
    {	
    	led=1;
    	while(1)
    	{	
    		keypros();  //按键处理函数	
    	}		
    }
    

    步进电机

    —启动步进电机

    #include <reg51.h>
    sbit moto=P1^0;	  	 
    
    void delay(unsigned int i)
    {
    	while(i--);	
    }
    
    void main()
    {	
    	unsigned char  i;
    	moto=0;			       //关闭电机
    	for(i=0;i<100;i++)	   //循环100次,也就是大约5S
    	{
    		moto=1;			  //开启电机
    		delay(5000);	  //大约延时50ms
    	}
    	moto=0;			      //关闭电机
    }
    
    							  /**************************************************************************************
    实验现象:下载程序后,D1小灯循环点亮1秒,熄灭1秒。使用单片机内部定时器可以实现准确延时
    		  
    接线说明: (具体接线图可见开发攻略对应实验的“实验现象”章节)
    		   1,单片机-->LED&交通灯模块
    		   		P20-->D1
    		   	
    	
    注意事项:																				
    
      
    ***************************************************************************************/
    
    #include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
    
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    
    
    
    /*******************************************************************************
    * 函 数 名         : Timer0Init
    * 函数功能		   : 定时器0初始化
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void Timer0Init()
    {
    	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
    
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;	
    	ET0=1;//打开定时器0中断允许
    	EA=1;//打开总中断
    	TR0=1;//打开定时器			
    }
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    	Timer0Init();  //定时器0初始化
    	P2=0xAA;
    	while(1);		
    }
    
    /*******************************************************************************
    * 函 数 名         : void Timer0() interrupt 1
    * 函数功能		   : 定时器0中断函数
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void Timer0() interrupt 1
    {
    	static u16 i;
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;
    	i++;
    	if(i==1000)
    	{
    		i=0;
    		P2=~P2;
    		
    	
    	}	
    }
    
    
    展开全文
  • 51单片机延时子程序详解
  • 精确地延时1s需要准确地计算,粗略地延迟1s可以自定义一个delay函数,下面我们让第一个LED灯延迟1s闪烁: //本题的delay函数参数为1时延迟的是1ms,1000是1s #include<reg52.h> #define uchar unsigned char ...

    精确地延时1s需要准确地计算,粗略地延迟1s可以自定义一个delay函数,下面我们让第一个LED灯延迟1s闪烁:

    //本题的delay函数参数为1时延迟的是1ms,1000是1s
    #include<reg52.h>    
    #define uchar unsigned char
    #define uint unsigned int
    void delay(uint z);
    sbit LED=P1^0;   //定义管脚
    void main()
    {
        while(1)   //让体系一直循环下去
    	    {
    		LED=0;    //我的单片机默认接的是高电平,给个低电平就可以亮啦
    		delay(1000); //延迟1s
    		LED=1;      //LED灯熄灭
    		delay(1000);  //这个延迟不要忘了,不然的话灯会一直亮着
    		}             //灯亮1s,熄灭1s,所以周期是2s
    }
    void delay(uint z)
    {
     	uint x,y;
     	for(x=z;x>0;x--)
     	for(y=110;y>0;y--);  //y的数值是模拟推算出来的
    }
    

    解释都在注释里啦,烧录到你的单片机里就可以闪烁喽~~

    展开全文
  • 单片机中常用的延时控制方式有两种。一种是采用编程的方式达到延时的目的,另一种方法则是通过单片机中的两个定时器T0和T1进行计时达到延时的目的。 本例通过具体实例说明单片机的两种延时控制方式在实际中的应用。 ...

    单片机中常用的延时控制方式有两种。一种是采用编程的方式达到延时的目的,另一种方法则是通过单片机中的两个定时器T0和T1进行计时达到延时的目的。

    本例通过具体实例说明单片机的两种延时控制方式在实际中的应用。

    采用编程方式延时控制
    1.问题的提出

    通过编程使单片机分别产生约10ms和约0.5s的延时。单片机的晶振频率为12MHz。因为单片机的晶振频率为12MHz,所以单片机1个机器周期的时间为1μs。

    2.控制程序

    (1)10ms延时程序。

    实例讲解,51单片机常用延时控制子程序
    此程序的实际延时时间为:1+(1+2×250+2)×20=10.061ms

    (2)0.5s延时程序。

    实例讲解,51单片机常用延时控制子程序
    此程序实际延时时间为:251×66×5×6+66×5×2+5×2+1×2+5×6+66×5×6=499662μs=0.49662s。

    采用定时器延时控制
    1.问题的提出

    利用单片机定时器使之产生10h的延时控制。

    2.控制程序

    实例讲解,51单片机常用延时控制子程序
    说明:程序中用“;程序开始******”符号表示程序开始,用“;程序结束******”符号表示程序结束,用“;-------------”表示将程序中各阶段程序分隔开,以便程序的条理性和直观性,这些符号均可以同时输入到Keil μVision3软件中进行编译。以下各例程序均同。

    展开全文
  • 51单片机延时子程序

    千次阅读 2012-06-25 23:48:20
    延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器 周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指 令周期的区别和...

    延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器

    周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指

    令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者

       我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如

    在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何

    实现的呢?下面让我们先来了解一些相关的概念。

    一、机器周期和指令周期

    1.机器周期是指单片机完成一个基本操作所花费的时间,一般使用微秒来计量单片机的运行速度,

    51 单片机的一个机器周期包括12 个时钟振荡周期,也就是说如果51 单片机采用12MHz 晶振,那么执行

    一个机器周期就只需要1μs;如果采用的是6MHz 的晶振,那么执行一个机器周期就需要2 μs。

       2 .指令周期是指单片机执行一条指令所需要的时间,一般利用单片机的机器周期来计量指令周期。

    在51 单片机里有单周期指令(执行这条指令只需一个机器周期),双周期指令(执行这条指令只需要两个

    机器周期),四周期指令(执行这条指令需要四个机器周期)。除了乘、除两条指令是四周期指令,其余均

    为单周期或双周期指令。也就是说,如果51 单片机采用的是12MHz 晶振,那么它执行一条指令一般只需

    1~2 微秒的时间;如果采用的是6MH 晶振,执行一条指令一般就需2~4 微秒的时间。

       现在的单片机有很多种型号,但在每个型号的单片机器件手册中都会详细说明执行各种指令所需的机

    器周期,了解以上概念后,那么可以依据单片机器件手册中的指令执行周期和单片机所用晶振频率来完成

    需要精确延时时间的延时程序。

    二、延时指令

       在单片机编程里面并没有真正的延时指令,从上面的概念中我们知道单片机每执行一条指令都需要一

    定的时间,所以要达到延时的效果,只须让单片机不断地执行没有具体实际意义的指令,从而达到了延时

    的效果。

    1.数据传送指令 MOV

       数据传送指令功能是将数据从一个地方复制、拷贝到另一个地方。

       如:MOV R7,#80H   ;将数据80H 送到寄存器R7,这时寄存器R7 里面存放着80H,就单这条

    指令而言并没有任何实际意义,而执行该指令则需要一个机器周期。

    2.空操作指令 NOP

       空操作指令功能只是让单片机执行没有意义的操作,消耗一个机器周期。

    3.循环转移指令 DJNZ

       循环转移指令功能是将第一个数进行减1 并判断是否为0,不为0 则转移到指定地点;为0 则往下执行。

       如:DJNZ R7,KK ;将寄存器R7 的内容减1 并判断寄存器R7 里的内容减完1 后是否为0,如果

       不为0 则转移到地址标号为KK 的地方;如果为0 则执行下一条指令。这条指令需要2 个机器周期。

       利用以上三条指令的组合就可以比较精确地编写出所需要的延时程序。

    三、1 秒延时子程序、流程图及时间计算 (以单片机晶振为12MHz 为例,1 个机器周期需要1μs)

    了解了以上的内容,现在让我们来看看

    程序总共所需时间:1+10+2560+330240+660480+5120+20+2=998433 μs≈1S

       在这里运行这段程序共需998433 μs,还差1567μs 才达到1S 的,所以想要达到完美的1S 延时,需

    要在返回指令RET 前再添加一些指令让它把1567μs 的延时完成。有兴趣的读者可以自己试着添加完成。

    最后补充一点,编写程序时一般将延时程序编写成独立的子程序,而所谓子程序也就是一个实现某个功能

    的小模块。这样在主程序中就可以方便地反复调用编写好的延时子程序。

       小提示:循环转移指令(DJNZ )除了可以给定地址标号让其跳转外,还可以将地址标号改成$,这样

    程序就跳回本指令执行。例如:

       DJNZ R7,$ ;R7 内容减1 不为0,则再次执行本指令;为0 则往下执行,当R7 的值改为10

    时,则执行完该条程序所需的时间为2*10=20 μs。

    51单片机汇编延时程序算法详解

    将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。   

    指令周期、机器周期与时钟周期

      指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。

      时钟周期:也称为振荡周期,一个时钟周期 =晶振的倒数。

      MCS-51单片机的一个机器周期=6个状态周期=12个时钟周期。

      MCS-51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1μs。

      程序分析

      例1 50ms 延时子程序:

      DEL:MOV R7,#200 ①

      DEL1:MOV R6,#125 ②

      DEL2:DJNZ R6,DEL2 ③

      DJNZ R7,DEL1 ④

      RET ⑤

      精确延时时间为:1+(1*200)+(2*125*200)+(2*200)+2

      =(2*125+3)*200+3 ⑥

      =50603μs

      ≈50ms

      由⑥整理出公式(只限上述写法)延时时间=(2*内循环+3)*外循环+3 ⑦

    详解:DEL这个子程序共有五条指令,现在分别就 每一条指令 被执行的次数和所耗时间进行分析。

      第一句:MOV R7,#200 在整个子程序中只被执行一次,且为单周期指令,所以耗时1μs

      第二句:MOV R6,#125 从②看到④只要R7-1不为0,就会返回到这句,共执行了R7次,共耗时200μs

      第三句:DJNZ R6,DEL2 只要R6-1不为0,就反复执行此句(内循环R6次),又受外循环R7控制,所以共执行R6*R7次,因是双周期指令,所以耗时2*R6*R7μs。

      例2 1秒延时子程序:

      DEL:MOV R7,#10 ①

      DEL1:MOV R6,#200 ②

      DEL2:MOV R5,#248 ③

      DJNZ R5,$ ④

      DJNZ R6,DEL2 ⑤

      DJNZ R7,DEL1 ⑥

      RET ⑦

      对每条指令进行计算得出精确延时时间为:

       1+(1*10)+(1*200*10)+(2*248*200*10)+(2*200*10)+(2*10)+2

      =[(2*248+3)*200+3]*10+3 ⑧

      =998033μs≈1s

      由⑧整理得:延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑨

      此式适用三层循环以内的程序,也验证了例1中式⑦(第三层循环相当于1)的成立。

      注意,要实现较长时间的延时,一般采用多重循环,有时会在程式序里加入NOP指令,这时公式⑨不再适用,下面举例分析。

      例3仍以1秒延时为例

      DEL:MOV R7,#10 1指令周期1

      DEL1:MOV R6,#0FFH 1指令周期10

      DEL2:MOV R5,#80H 1指令周期255*10=2550

      KONG:NOP 1指令周期128*255*10=326400

      DJNZ R5,$ 2指令周期2*128*255*10=652800

      DJNZ R6,DEL2 2指令周期2*255*10=5110

      DJNZ R7,DEL1 2指令周期2*10=20

      RET 2

      延时时间=1+10+2550+326400+652800+5110+20+2 =986893μs约为1s

      整理得:延时时间=[(3*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑩

      结论:针对初学者的困惑,对汇编程序的延时算法进行了分步讲解,并就几种不同写法分别总结出相应的计算公式,只要仔细阅读例1中的详解,并用例2、例3来加深理解,一定会掌握各种类型程序的算法并加以运用。

    单片机延时子程序

    1)延时为:20ms 晶振12M

    1+(1+2*248+2)*4+1+1+1=20000US=20MS

    用汇编..优点就是精确...

    缺点就是算有点复杂.

    DELAY20MS:

    MOV R7,#4

    D1:

    MOV R6,#248

    DJNZ R6,$

    DJNZ R7,D1

    NOP

    NOP

    RET

    2)一些通过计算51汇编指令得出的软延时子程序

    ;*****************************************************************   

    ;延时10uS   

    ;*****************************************************************   

      

    time10us:               mov     r5,#05h                 ;11us   

                            djnz    r5,$   

                            ret  

      

    ;*****************************************************************   

    ;延时50uS   

    ;*****************************************************************   

      

    time50us:               mov     r5,#19h                 ;51us   

                            djnz    r5,$   

                            ret  

      

    ;*****************************************************************   

    ;延时100uS   

    ;*****************************************************************   

      

    time100us:              mov     r5,#31h                 ;99.6us   

                            djnz    r5,$   

                            ret  

      

    ;*****************************************************************   

    ;延时200uS   

    ;*****************************************************************   

      

    time200us:              mov     r5,#64h                 ;201us   

                            djnz    r5,$   

                            ret  

      

    ;*****************************************************************   

    ;延时250uS   

    ;*****************************************************************   

      

    time250us:              mov     r5,#7ch                 ;249.6us   

                            djnz    r5,$   

                            ret  

      

    ;*****************************************************************   

    ;延时350uS   

    ;*****************************************************************   

      

    time350us:              mov     r5,#0afh                 ;351us   

    time350us_1:            djnz    r5,time350us_1   

                            ret  

      

    ;*****************************************************************   

    ;延时500uS   

    ;*****************************************************************   

      

    time500us:              mov     r5,#0fah                 ;501us   

    time500us_1:            djnz    r5,time500us_1   

                            ret  

      

    ;*****************************************************************   

    ;延时1mS   

    ;*****************************************************************   

      

    time1ms:                mov     r5,#0fah                ;1001us   

    time1ms_1:              nop  

                            nop  

                            djnz    r5,time1ms_1   

                            ret  

      

    ;*****************************************************************   

    ;延时2.5mS   

    ;*****************************************************************   

      

    time2_5ms:              mov     r5,#05h          ;2.496ms   

    time2_5ms_1:            mov     r6,#0f8h         ;497us   

                            djnz    r6,$   

                            djnz    r5,time2_5ms_1   

                            ret  

      

    ;*****************************************************************   

    ;延时10mS   

    ;*****************************************************************   

      

    time10ms:               mov    r5,#14h         ;10.262ms   

    time10ms_1:             mov    r6,#0ffh        ;511us   

                            djnz   r6,$   

                            djnz   r5,time10ms_1   

                            ret  

      

    ;*****************************************************************   

    ;延时50mS   

    ;*****************************************************************   

      

    time50ms:               mov    r5,#63h         ;49.996ms   

    time50ms_1:             mov    r6,#0fbh        ;503us   

                            djnz   r6,$   

                            djnz   r5,time50ms_1   

                            ret  

      

    ;*****************************************************************   

    ;延时100mS   

    ;*****************************************************************   

      

    time100ms:              mov     r5,#0c3h        ;100.036ms   

    time100ms_1:            mov     r6,#0ffh        ;511us   

                            djnz    r6,$   

                            djnz    r5,time100ms_1   

                            ret  

      

    ;*****************************************************************   

    ;延时200mS   

    ;*****************************************************************   

      

    time200ms:              mov     r5,#02h         ;250.351ms   

    time200ms_1:            mov     r6,#0f4h        ;125.173ms   

    time200ms_2:            mov     r7,#0ffh        ;511us   

                            djnz    r7,$   

                            djnz    r6,time200ms_2   

                            djnz    r5,time200ms_1   

                            ret  

      

    ;*****************************************************************   

    ;延时500mS   

    ;*****************************************************************   

      

    time500ms:              mov    r5,#04h         ;500.701ms   

    time500ms_1:            mov    r6,#0f4h        ;125.173ms   

    time500ms_2:            mov    r7,#0ffh        ;511us   

                            djnz   r7,$   

                            djnz   r6,time500ms_2   

                            djnz   r5,time500ms_1   

                            ret  

      

    ;*****************************************************************   

    ;延时1S   

    ;*****************************************************************   

      

    time1s:                 mov    r5,#08h         ;1001.401ms   

    time1s_1:               mov    r6,#0f4h        ;125.173ms   

    time1s_2:               mov    r7,#0ffh        ;511us   

                            djnz   r7,$   

                            djnz   r6,time1s_2   

                            djnz   r5,time1s_1   

                            ret

    12M晶振 机器周期为1US  NOP为单周期指令 DJNZ为双周期指令.

    3)

    ;;晶振12MHZ,延时1秒  

       

       

       

    DELAY:MOV   72H,#100  

    LOOP3:MOV   71H,#100  

    LOOP1:MOV   70H,#47  

    LOOP0:DJNZ   70H,LOOP0  

                  NOP    

                  DJNZ   71H,LOOP1  

                  MOV   70H,#46  

    LOOP2:DJNZ   70H,LOOP2  

                  NOP  

                  DJNZ   72H,LOOP3  

                  MOV   70H,#48  

    LOOP4:DJNZ   70H,LOOP4

    4);延时1分钟子程序,F=6MHz

    ;程序已测过,延时时间60,000,000.0uS

    delay60s:mov r3,#228

             mov r2,#253

             mov r1,#219

    loop1:   djnz r1,$

             djnz r2,loop1

             djnz r3,loop1

             nop

             ret

    5)计算机反复执行一段程序以达到延时的目的称为软件延时,单片机程序中经常需要短时间的延时,但是相当一部分人对延时程序很模糊,对延时程序的算法不够了解,在这里我以12MHz晶振和两个经典延时子程序为例,详细分析单片机汇编延时程序。

    何为时钟周期、机器周期、和指令周期?

    时钟周期:也就是振荡周期,以12MHz的时钟脉冲为例,那时钟周期就为(1/12000000)s=(1/12)us;

    机器周期:1个机器周期=6个状态周期=12个时钟周期=1us;

    指令周期:CPU执行一条指令所需要的时间称为指令周期,指令周期是以机器周期为单位的,不同的指令所需的机器周期不一定相同,可参考51单片机指令速查表。

            由上可得:CPU执行一条单周期指令,需要1us;执行一条双周期指令需要2us。

            下面是具体的延时子程序分析:

    0.1s延时子程序(12MHz晶振):

               MOV R7,#200   ;单周期指令(1us)

    D1:     MOV R6,#250   ;单周期指令(1us)

               DJNZ R6,$      ;双周期指令(2us)//该指令自身执行R6次

               DJNZ R7,D1     ;双周期指令(2us)//D1执行R7次

               RET            ;双周期指令(2us)

    T=1+(1+2*R6+2)*R7+2

       =100603us

       ≈0.1s

    0.5s延时子程序(12MHz晶振):

               MOV R7,#5     ;单周期指令(1us)

    D1:     MOV R6,#200   ;单周期指令(1us)

    D2:     MOV R5,#250   ;单周期指令(1us

               DJNZ R5,$      ;双周期指令(2us)//该指令自身执行R5次

               DJNZ R6,D2     ;双周期指令(2us)//D2执行R6次

               DJNZ R7,D1     ;双周期指令(2us)//D1执行R7次

               RET            ;双周期指令(2us)

    T=1+[1+(1+2*R5+2)*R6+2]*R7+2

       =503018us

       ≈0.5s

    6) 51单片机经典流水灯程序,在51单片机的P2口接上8个发光二极管,产生流水灯的移动效果。

                        ORG        0                   ;程序从0地址开始

    START:      MOV      A,#0FEH     ;让ACC的内容为11111110

    LOOP:         MOV      P2,A            ;让P2口输出ACC的内容

                         RR          A                  ;让ACC的内容左移

                         CALL     DELAY       ;调用延时子程序

                         LJMP     LOOP          ;跳到LOOP处执行

    ;0.1秒延时子程序(12MHz晶振)===================

    DELAY:      MOV      R7,#200      ;R7寄存器加载200次数

    D1:               MOV      R6,#250      ;R6寄存器加载250次数

                         DJNZ     R6,$             ;本行执行R6次

                         DJNZ     R7,D1          ;D1循环执行R7次

                         RET                            ;返回主程序

                         END                           ;结束程序


    展开全文
  • 单片机延时C语言程序

    千次阅读 2015-07-31 22:15:41
    (晶振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 
  • 谈谈51单片机延时子程序

    千次阅读 2010-07-23 11:48:00
    延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器 周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指 令...
  • //单片机每秒执行的指令数:频率*1 (例:cc2530频率为)32MHz //8051效率是PC的12分之一 //循环需要执行5条指令 //公式为 32*1024*1024/5/12 = 559240.533 所以写一个for循环 循环次数为559240次
  • 关于C语言延时时间的问题

    千次阅读 2016-01-25 11:27:10
    回答了一个关于C语言延时时间的问题,题目给出延时函数如下:delay(unsigned int x) {while(x--);}delay(unsigned int x) {for (i =0, i 单片机的晶振为12M。要求说出他们所延迟的时间分别是X的多少倍?怎么计算的。...
  • stm32延时函数的三种写法

    千次阅读 2019-08-04 12:38:54
    我常用的延时函数有3种,一种是空循环,一种是使用systick中断,还有一种是正点原子的延时。 第一种就不做举例,因为平时不常用。但是一些模块给的参考代码的延时函数都会采用这样的方法,直接用就好了,不做赘述。 ...
  • 单片机的编程中,时常会出现延时需求,例如,点亮一盏LED灯,然后延时1s,延时过后再让LED灯灭掉并再次亮起。单片机入门学习者一般习惯在超级循环里通过调用delay的方式来实现该功能。【超级循环:程序按顺序执行...
  • 二、应广单片机点亮一个灯

    千次阅读 2018-06-18 00:48:09
    这一节开始从一个个实际例子,向大家展示应广单片机的各项功能。由于看本文的读者层次不相同,这里全部按照初学者视之。废话少说,上例程://======================================================== #include &...
  • 51单片机交通灯(十字路口演示),包括紧急情况 本项目中采用单片机 AT89C52为中心器件来设计交通信号灯控制器, 系统实用性强、操作简单、扩展性强。本设计系统就是由单片机最小系统、交通灯状态显示系统、 LED...
  • 51定时器控制灯亮灭

    2020-02-01 23:55:15
    任务:定时器控制灯亮灭...第一种操作://单片机一次最大计数为65.536ms,想要设计单次计时5ms,每一次i++,直到(i%1000==1),理论上灯5s灭,5s亮。 #include<reg52.h> #define unit8 unsigned char #def...
  • 单片机 数字电压表(ADC0809)

    万次阅读 多人点赞 2020-04-04 15:59:49
    单片机 数字电压表(ADC0809) 一、简述 采用模数转换的芯片ADC0809实现设计数字电压表。例子中设计的数字电压表可以测量0~5V范围内的输入电压值,并且通过4位LED数码管显示采集的电压值,例子测量三个模拟值:4....
  • 基于51单片机的抢答器

    千次阅读 多人点赞 2019-06-18 20:51:31
    这是一个用单片机开发板做的抢答器,用独立按键进行抢答,用数码管显示。 二、使用说明 使用说明烧录完毕按,(这里四个独立从左到右依次为s1,s2,s3,s4),按下s3开始抢答数码管开始倒计时,在倒计时内按下s1或s2...
  • 怎么让LED灯延时1秒

    千次阅读 2017-11-21 00:07:06
    LED灯定时闪烁
  • 对于51定时器,却是有点少,有时候不经意间就被用完了,而实现定时又TM神坑了!...所以来分享一个神好用的方法,C语言的while和nop结合使用实现精确延时上调试代码:#include <reg52.h> #include <intrins.h>//声
  • 本程序使用单片机的定时器0和中断实现9到0的倒计时功能,并用数码管显示 */ #include #define uchar unsigned char //宏定义 #define uint unsigned int uchar num1=9,shu; uchar num; sbit ...
  • 单片机模拟十字路口的交通灯,采用自动红绿黄交通灯控制,具有固定的红灯、绿灯转换时间间隔,自动切换,每个方向具有倒计时功能。 功能要求: 1)要求南北方向车道和东西方向车道2条交叉道路上的车辆自动交替运行...
1 2 3 4 5 ... 10
收藏数 200
精华内容 80
热门标签
关键字:

单片机5s延时