单片机定时问题_stm32单片机通用定时器高级定时器基本定时器区别 - CSDN
  • 本人最近学习51单片机,以下是教程网址,在7-37课中,讲到定时器时第一遍不是太明白,看到下面的评论中也有不少人一头雾水,本人现将自己的理解概述如下: 教程网址:http://www.51zxw.net/show.aspx?id=37655&...

    本人最近学习51单片机,以下是教程网址,在7-37课中,讲到定时器时第一遍不是太明白,看到下面的评论中也有不少人一头雾水,本人现将自己的理解概述如下:

    教程网址:http://www.51zxw.net/show.aspx?id=37655&cid=473

    先贴代码:

    #include <reg52.h>
    typedef unsigned char u8;
    typedef unsigned int u16;
    sbit led = P1^0;
    u8 timer;
    void main (void)
    {    
        TMOD = 0x01;
        TH0 = (65535-50000)/256;
        TL0 = (65535-50000)%256;
        EA = 1;
        ET0 = 1;
        TR0 = 1;
        while (1)
        {
            ;
        }  
     
    }
    void timer0_service(void) interrupt 1
    {
        TH0 = (65535-50000)/256;
        TL0 = (65535-50000)%256;
        timer ++;
        if(timer==20)
        {
            timer=0;
            led=~led;
        }
    }

    橙黄色的while循环语句很多人不明白为什么加上去之后就能实现定时呢?下面是个人理解:

    首先要确认的是:main函数是扫描执行的,如果不加while语句,那么在TR0=1这条语句执行完后,程序会有两个分支同时进行,第一个分支是:重新执行main函数,给定时器赋初值;第二个分支是:定时器开始计时,记到50ms就会跳到中断函数 timer0_service,但是第一个分支的时间要比第二个分支的时间短,也就是说,第二个分支中,定时器还没能计时50ms,程序就已经跳到主函数的赋值语句中了,这就导致定时器还没计时50ms就被重新赋予初值,从而无法跳到中断函数 timer0_service,而加上while语句后,程序就会在此一直等待,而不执行第一个分支,使得定时器计时50ms后再跳到中断函数。

     

    展开全文
  • 问题 今天,在用12的时候,定时器无意之间debug竟然发现,定时不准? 查查查,,,一直没有头绪,还好没有放弃一直在苦苦挣扎。 过程再现#include #include <intrins.h>unsigned char T0RH; unsigned char T0RL;...

    自己不断的折腾确实挺浪费时间的,但是真的收获颇丰。

    问题

    今天,在用12的时候,定时器无意之间debug竟然发现,定时不准?
    查查查,,,一直没有头绪,还好没有放弃一直在苦苦挣扎。

    过程再现

    #include <stc12.h>
    #include <intrins.h>
    
    unsigned char T0RH;
    unsigned char T0RL;
    
    /* 配置并启动T0,ms-T0定时时间 */
    void ConfigTimer0(unsigned int ms)
    {
        unsigned long tmp;  //临时变量
    
        AUXR &= 0x7F;       //定时器时钟12T模式 
        tmp = 12000000 / 12;      //定时器计数频率
        tmp = (tmp * ms) / 1000;  //计算所需的计数值
        tmp = 65536 - tmp;        //计算定时器重载值
        //tmp = tmp + 12;            //补偿中断响应延时造成的误差
        T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
        T0RL = (unsigned char)tmp;
        TMOD &= 0xF0;   //清零T0的控制位
        TMOD |= 0x01;   //配置T0为模式1
        TH0 = T0RH;     //加载T0重载值
        TL0 = T0RL;
        ET0 = 1;        //使能T0中断
        TR0 = 1;        //启动T0
    }
    
    void main()
    {
    
        ConfigTimer0(1);
    
        EA = 1;
        while(1);
    }
    
    void InterruptTimer0() interrupt 1
    {
        TH0 = T0RH;
        TL0 = T0RL;
    }

    设置型号以及晶振值
    设置型号以及晶振值
    计算两次中断的时间间隔
    这里写图片描述
    第一次sec = 0.000453

    这里写图片描述
    第二次sec = 0.000704
    相差251us非1ms。

    不科学对不对?

    专门还查了手册,手册上写12就是IT单片机。T0上电部分默认为12T模式,用户也可通过AUXR寄存器来更改是IT还是12T!

    这里先来了解一个东西,什么叫IT单片机,所谓的IT单片机就是一个机器周期就是一个时钟周期
    也就是一个nop()就是一个机器周期,也就是晶振频率分之1。
    实测如下:
    这里写图片描述
    sec = 0.00045375
    这里写图片描述
    sec = 0.00045383
    12M下一个机器周期为 1/12000000 = 8.3333333*10^8
    两者相差刚好就是一个机器周期,说明一个nop就是一个机器周期就是一个时钟周期,就是IT。
    但是,前面到底错在了哪里呢?
    keil跑的内核为intel公司制造的,所以选择intel旗下的80/87C52来代替即可!
    一切over,演示如下:

    这里写图片描述
    sec = 0.00234300
    这里写图片描述
    sec = 0.00334900
    1ms多几个机器周期,补偿回来即可!

    over~~~~

    展开全文
  • 单片机定时问题:亮100ms、灭300ms

    千次阅读 2016-01-25 11:27:10
    6MHz晶振,用定时计数器1,采用中断方式,通过P1.0让一个发光二极管亮100ms、灭300ms,周而复始。汇编编程实现。悬赏分:20 - 解决时间:2010-1-10 13:14 ;----------------------------------最佳答案:;下列程序,...

    6MHz晶振,用定时计数器1,采用中断方式,通过P1.0让一个发光二极管亮100ms、灭300ms,周而复始。
    汇编编程实现。

    悬赏分:20 - 解决时间:2010-1-10 13:14
    ;----------------------------------
    最佳答案:

    ;下列程序,经过编译、仿真,符合要求:

        ORG  0000H
        SJMP START
        ORG  000BH
        SJMP T0_INT
    START:
        MOV  TMOD, #01H
        MOV  TH0, #03CH
        MOV  TL0, #0B0H   ;100ms@6MHz
        SETB TR0
        SETB ET0
        SETB EA
        MOV  R2, #4
        CLR  P1.0
        SJMP $            ;设置结束,原地转移,等待中断
    T0_INT:
        MOV  TH0, #03CH
        MOV  TL0, #0B0H   ;100ms@6MHz
        SETB P1.0         ;100ms就上升为高电平
        DJNZ R2, T0_END   ;不够四次,退出中断
        MOV  R2, #4
        CLR  P1.0         ;每中断四次,输出一次低电平
    T0_END:
        RETI

    END
    ;----------------------------------
    回答者:   做而论道 - 十二级   2010-1-10 10:37
    提问者对于答案的评价:非常感谢!!
    原文网址:http://zhidao.baidu.com/question/132749703.html
    ;----------------------------------

    展开全文
  • 51单片机定时中断(三)

    千次阅读 2018-12-02 09:49:32
    振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期) 状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。 机器周期:1个机器周期含6个状态周期,12个振荡周期。 ...

    前言:单片机的中断系统(一)

    图片和内容来自普中科技的ppt。


    相关知识:

    周期:

    振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)

    状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。

    机器周期:1个机器周期含6个状态周期,12个振荡周期。

    指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。

    (1M=1000000,所以在晶振频率为12MHZ时,一个机器周期=1/12M=1us)

      (指令周期的长短不一,如果不知道一些指令周期的长度,即使定时中断,也不能理论上绝对准确的中断。因为函数的调用等也需    要时间)(这目前我还不会,但是感觉应该可以更精确延时,因为可以在计时中剪掉相应的操作时间)

    IT0/IT1:

    51单片机有两组定时器/计数器IT0/IT1,因为既可以定时又可以计数,故称之为定时器/计数器。

    定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。

    51单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加1。

    有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加1的工作可以交给定时器/计数器处理。CPU转而处理一些复杂的事情。同时可以实现精确定时作用。

     

    定时/计数器的工作原理

    定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。

     

    51单片机定时/计数器结构

    定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器THx和TLx组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。

    图一:定时计数器结构

     

    定时/计数器的控制

    51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。

    工作方式寄存器TMOD

    图二:TMOD

    1、高四位用来控制T1,低四位用来控制T0

    2、GATE是门控位。GATE=0时,用于控制定时器的启动不受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。

    3、C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。(T上有个非)

    4、M1M0:工作方式设置位。定时/计数器有四种工作方式。(8位自动重装,指的是将初始化值装在高位,然后赋值给低位。低位进行计数或计溢出后,高位的数重新赋值给低位,重复)

    图三

     

    控制寄存器TCON

    制定时/计数器的启动和中断申请。其格式如下:

    图四

    TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。

    TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。

    TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。

    TR0(TCON.4):T0运行控制位,其功能与TR1类同。

     

    定时/计数器的工作方式

    这里仅仅提及方式一(我目前只用过这两种)

    方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器 。

            计数个数与计数初值的关系为:X=216-N

    图五

     

     

     

    定时器的使用

    对TMOD赋值,以确定T0和T1的工作方式。

    计算初值,并将其写入TH0、TL0或TH1、TL1。

    中断方式时,则对EA,ET0/1赋值,开放定时器中断。

    使TR0或TR1置位,启动定时/计数器定时或计数。(这个最后设置,因为一旦设置,计时或计数就开始)

     

    代码:

    定时器0

    #include<reg52.h>
    
    sbit led=P2^0;//LED接在P2^0引脚上
    
    int i=0;
    
    void Timer0Init()
    {
    	TMOD|=0X01;//这样写是非常好的,仅仅设置定时器0,不影响定时器1的工作状态。在多文件编程中,这一点能更好的体现
    	TH0=(65536-1000)/256;
       	TL0=(65536-1000)%256;
    	//TH0=0xFC;//晶振频率为12M
    	//TL0=0X18;
    	TH0=0xFC;//我板子上晶振频率为11.05926M
    	TL0=0X66;//这差别很小的
    	ET0=1;//定时器0的中断允许
    	EA=1;//打开总终端
    	TR0=1;
    }
    
    void main(void)
    {
    	Timer0Init();
    	while(1);			
    }
    
    void Timer0() interrupt 1//尽量减少中断中的操作,提高精度
    {
       i++;
       TH0=0xFC;//重新赋初值
       TL0=0X66;
       if(i==1000)
       {
       		led=~led;
    		i=0;
       }
    }
    
    
    

    1、TMOD|=0X01;//这样写是非常好的,仅仅设置定时器0,不影响定时器1的工作状态。在多文件编程中,这一点能更好的体现

    2、尽量减少定时中断中的操作,提高精度。

    3、这个定时中断是1ms,中断中的操作应该是不到1000的1/10,所以这个中断在ms级别中,可能还是相对准确的。可以用于以后的实验。但是在s级别误差逐渐变大,下面是我简单测量的方法和结果。

    测量:

    在灯灭下的瞬间,手机开始计时。如果要测10s,在第五次灯灭的时候结束计时。(因为点亮和熄灭各一秒)

    下面用上述方法测量了10s,30s,50,70s,各三次。结果如下

    1ms延时的测量
      10s 30s 50s 70s
    第一次测量(s) 09.77 28.08 46.48 65.98
    第二次测量(s) 09.38 28.15 46.44 65.88
    第三次测量(s) 09.46 28.08 47.18 65.53
    实际平均时间(s) 09.536 28.103 46.700 65.797

     上表可见,误差越来越大。当然也可能我的晶振不是11.0592MHz,上面没标注,问的淘宝客服。

    好奇万年历是怎么做出来的,回头好好查查。

     

    定时器1(普中科技的代码)

    /**************************************************************************************
    *		              定时器1实验												  *
    实现现象:下载程序后数码管最后一位间隔一秒循环显示0-F。使用单片机内部定时器可以实现准确延时。
    注意事项:如果不想让点阵模块显示,可以将74HC595模块上的JP595短接片拔掉。																				  
    ***************************************************************************************/
    
    #include "reg52.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的值
    u8 n=0;
    /*******************************************************************************
    * 函 数 名         : Timer1Init
    * 函数功能		   : 定时器1初始化
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void Timer1Init()
    {
    	TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。
    
    	TH1=0XFC;	//给定时器赋初值,定时1ms
    	TL1=0X18;	
    	ET1=1;//打开定时器1中断允许
    	EA=1;//打开总中断
    	TR1=1;//打开定时器			
    }
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    	LSA=0;
    	LSB=0;
    	LSC=0;
    	Timer1Init();  //定时器1初始化
    	while(1);		
    }
    
    /*******************************************************************************
    * 函 数 名         : void Timer1() interrupt 3
    * 函数功能		   : 定时器0中断函数
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void Timer1() interrupt 3
    {
    	static u16 i;
    	TH1=0XFC;	//给定时器赋初值,定时1ms
    	TL1=0X18;
    	i++;
    	if(i==1000)
    	{
    		i=0;
    		P0=smgduan[n++];
    		if(n==16)n=0;	
    	}	
    }

    在定时中断函数中,为了不断定时,进行了重装载(重新赋值)。当溢出的时候ET0置一,中断标志。

    TR0=1,为打开计时器;ET0=1是打开定时器1中断允许。我咋感觉这两个有点重复呢?

     

    补充:

    来自百度百科:晶体振荡器

            石英晶体振荡器是高精度和高稳定度的振荡器,被广泛应用于彩电、计算机、遥控器等各类振荡电路中,以及通信系统中用于频率发生器、为数据处理设备产生时钟信号和为特定系统提供基准信号。

            石英晶体振荡器是利用石英晶体(二氧化硅的结晶体)的压电效应制成的一种谐振器件,它的基本构成大致是:从一块石英晶体上按一定方位角切下薄片(简称为晶片,它可以是正方形、矩形或圆形等),在它的两个对应面上涂敷银层作为电极,在每个电极上各焊一根引线接到管脚上,再加上封装外壳就构成了石英晶体谐振器,简称为石英晶体或晶体、晶振。其产品一般用金属外壳封装,也有用玻璃壳、陶瓷或塑料封装的

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 51单片机定时计数器

    2020-07-30 23:31:54
    51单片机定时计数器 该项目包括原理图电路图 程序源码 演示视频讲解文档全套资料 三分拿去 超值了
  • 众所周知 单片机定时计数器是难点 来来回回 学习了三遍 算是看懂了 吧吧吧吧吧 定时计数器本质上 就是一个加一计数器 计时完成 定时模式即时间到达 计数模式即计数完成 晶振提供震荡周期 为单片机定时计数器提供震荡...
  • 单片机定时/控制器的控制接口 定时/计数器编程的 5 个步骤 1.根据需求选择工作方式,确定方式控制字,写入TMOD寄存器 2.计算定时/计数器的计数值,求计数初值,写入初值寄存器 3.根据需要,开放定时/计数器的中断...
  • 51单片机定时/计数器

    千次阅读 2018-09-18 22:54:08
    51单片机定时/计数器 实现LED灯闪烁,代码如下: #include &lt;reg51.h&gt; //51单片机头文件 sbit LED = P0^0; //定义特殊寄存器p0.0;注意:sbit 必须小写、P 大写! void main() { unsigned int i; //...
  • 51单片机定时时间的计算

    千次阅读 2020-05-06 11:55:03
    单片机根据计时/计数模式的不同,来进行计算 M1 M0 工作模式 说明 0 0 0 13位计时计数器 (8192) 0 1 ...
  • 51单片机定时/计数器的功能实现

    千次阅读 2017-05-08 16:12:21
    8051单片机内部有两个16位的定时/计数器:T0和T1 定时器用途:延时和脉宽测量 读取方式:软件读取和中断 公式: T(初值)=2^N-定时时间/机器周期时间 机器周期时间=12/fosc N:代表几位定时器,有13 16...
  • 单片机定时/计数器

    千次阅读 2012-02-01 11:26:28
    上一篇,我们给大家讲述了单片机的一些简单入门知识,不知道对您是否有用呢,今天我将继续为大家献上单片机定时/计数器知识,欢迎和我一起讨论学习,嘻嘻。   在测量控制系统中,常常要求有一些实时时钟,以实现...
  • 单片机精确定时1s

    2020-07-30 23:33:33
    基于8位单片机12MHZ晶振,应用定时器和内部中断所编写的能够精确定时1s
  • /*****************************...定时炸弹 9秒倒计时,至0时蜂鸣器响演示炸弹 Author:Vivien *******************************************************/ #include &lt;reg51.h&gt; #define DataPort P0 /...
  • 单片机定时功能的实现

    千次阅读 2020-04-05 23:23:55
    单片机定时功能 先上代码,然后再解释: //定時器功能 void timer_0(void) { TMOD=0x01; //採用定時器T0,工作方式為1(16位定时器) IE=0x82; //二進制1000|0010,七位為1表示全局中斷打開,即EA=1,一位...
  • 基于51单片机的电器定时开关C程序,程序通过外部中断和计时器,实现了电器定时开关的功能,程序很简单,可以用于初学者学习51单片机
  • 单片机定时初始值的设定

    千次阅读 2017-09-26 22:20:13
    其实很简单,不管你使用多大的晶振,使用51单片机,一般都是12分频出来,也就可以得出一个机器周期 机器周期=12/n(n指晶振频率),假设你要定时的时间为M 那么定时的初值为: M/机器周期=初值; TH0=(65536-初值...
  • #include &amp;amp;lt;reg52.h&amp;amp;gt; #define uchar unsigned char #define uint unsigned int uchar code table[] = {0x01, 0x02, 0x04, 0x08};...uchar code ledCode[]= {0xc0,0xf9,0xa4, ...
  • 定时器(计数器) ...  51系列单片机中有两个16位可编程定时/计数器:T0和T1,52子系列还有一个T2 定时/计数器T0、T1的结构 如图,T0、T1各有两个计数变量TH、TL 计数变量有计数范围,当计数变量达到计数上...
  • 单片机定时计数器产生高电平为50ms,低电平为100ms的方波信号。 实现方式: 使用定时计数器0产生中断,单片机的晶振频率为12MHZ,方波信号在P2.0口输出。 C语言程序代码: #include<reg51.h> sbit led = ...
  • 单片机定时/计数器的四种工作方式

    千次阅读 2010-01-09 17:34:00
    我们用这个图来讨论几个问题: M1M0:定时/计数器一共有四种工作方式,就是用M1M0来控制的,2位正好是四1 工作方式0 定时器/计数器的工作方式0称之为13位定时/计数方式。它由TL(1/0)的低5位和TH(0/1)
1 2 3 4 5 ... 20
收藏数 11,503
精华内容 4,601
关键字:

单片机定时问题