单片机测量周期法_stc单片机 测量 周期 - CSDN
  • 要求:测量脉冲的周期 思想:用定时器和外部中断(下降沿触发中断),当第一个下降沿时,触发外部中断,此时开始计时。当第二个下降沿时,此时停止计时,此时的时间就是脉冲的周期

    要求:测量脉冲的周期
    思想:用定时器和外部中断(下降沿触发中断),当第一个下降沿时,触发外部中断,此时开始计时。当第二个下降沿时,此时停止计时,此时的时间就是脉冲的周期。
    程序:

    #include <reg51.h>
    #include <intrins.h>
    
    #define uLint unsigned long int
    
    uLint cycle_t = 0 ;//脉冲周期时间
    sbit in = P3^2 ;
    bit start = 0 ;
    void Int0 (void) interrupt 0
    { 
    	if(start == 0)//第一次下降沿开始计时
    	{
    		cycle_t = 0 ;
    		TL0 = 0 ;	
    	}
    	if(start == 1)		 //第二次下降沿结束计时
    	{
    		 cycle_t += TL0 ;
    		 TL0 = 0 ;
    	}
    	start = ~start ;
    }
    
    void Time0(void) interrupt 1
    {
    	cycle_t += 256 ;
    }
    
    int main()
    {
    	//初始化
    	TMOD = 0x2 ; //定时器0,模式2
    	TH0 = 0 ;
    	TL0 = 0 ;
    	TR0 = 1 ;
    	ET0 = 1 ;
    	
    	IT0 = 1 ;
    	EX0 = 1 ;
    	EA = 1 ;
    	
    	while(1)
    	{
    			
    	}		
    }
    
    

    信号函数:

    
    signal void test() 
    {
    	int i ;
    	for(i = 0 ; i < 10 ; i++)
    	{
    		port3 &= ~(0x1<<2)  ;
    		swatch(0.5) ;
    		port3 |= (0x1<<2) ;	
    		swatch(0.7) ;
    		port3 &= ~(0x1<<2)  ;
    	}
    
    	_break_ = 1 ;
    	  
    }
    

    这里写图片描述
    这里写图片描述

    展开全文
  • 单片机测量PWM占空比的三种方法 PWM(Pulse Width Modulation),一般指脉冲宽度调节,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中,...

    单片机测量PWM占空比的三种方法

    PWM(Pulse Width Modulation),一般指脉冲宽度调节,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中,比如LED亮度调节、电机转速控制等。
    而在某些特殊应用中,我们也需要通过测量输入PWM的占空比,来实现不同的输出控制,这就需要使用到PWM占空比的测量方法。这里介绍三种不同的测量方法:阻塞方式、中断方式以及定时器捕获功能。

    1. 阻塞方式

    MCU阻塞方式测量PWM占空比的原理比较简单,也只需要使用到一个普通的IO端口(设置为输入模式,对于51而言那就是一个普通的双向口)。具体实现流程为:

    • 等待上升沿到来,然后开启定时器,开始计时;
    • 等待下降沿到来,记录下定时器的计数值,即得到PWM的高电平时间H
    • 同时,清零定时器,重新开始计数;
    • 等待上升沿到来,记录下定时器的计数值,即得到PWM的低电平时间L
    • 计算得出占空比:duty = H / (H + L);

    阻塞方式原理简单,而且只需要MCU有一个定时器的资源即可实现;但采集时阻塞CPU运行,阻塞的时间和输入PWM的周期相关,只适用于实时性较低的系统。

    另外,上述流程中存在着一个严重的BUG,即当输入的PWM占空比为0%或者100%时,程序会被一直阻塞,等待上升沿/下降沿的到来。所以解决方法是,在等待上升沿/下降沿的过程中,实时提取定时器的值,一旦定时时间超过1个周期的限定(一般可定义为2-3个周期时间),即退出等待,并根据端口电平判断此时占空比为0%(低电平)或100%(高电平)

    示例代码,仅供参考:

    //获取PWM输入脚的电平
    #define PWM_IN()   xxxxxx
    //定义超时时间(如2-3倍PWM周期)
    #define T1_TIMEOUT  xxxxxx
    
    uint8_t PWM_Analyse(void)
    {
        uint8_t duty = 0xFF;
        uint16_t pwm_H = 0;
        uint16_t pwm_L = 0;
    
        if (PWM_IN())   //初始为高电平,则开始等待低电平
        {
            TH1 = 0;
            while (PWM_IN()) //等待下降沿
            {
                if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
                {
                    duty = 100;
                    return duty;
                }
            }
    
            TH1 = 0;
            TL1 = 0;
            while (!PWM_IN()) //等待上升沿
            {
                if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
                {
                    duty = 0;
                    return duty;
                }
            }
            pwm_L = (TH1 << 8) | TL1;
    
            TH1 = 0;
            TL1 = 0;
            while (PWM_IN()) //等待下降沿
            {
                if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
                {
                    duty = 100;
                    return duty;
                }
            }
            pwm_H = (TH1 << 8) | TL1;
    
            duty = pwm_H * 100 / (pwm_H + pwm_L);
            return duty;
        }
        else    //当前为低电平,则开始等待高电平
        {
            TH1 = 0;
            while (!PWM_IN()) //等待上升沿
            {
                if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
                {
                    duty = 0;
                    return duty;
                }
            }
    
            TH1 = 0;
            TL1 = 0;
            while (PWM_IN()) //等待下降沿
            {
                if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
                {
                    duty = 100;
                    return duty;
                }
            }
            pwm_H = (TH1 << 8) | TL1;
    
            TH1 = 0;
            TL1 = 0;
            while (!PWM_IN()) //等待上升沿
            {
                if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
                {
                    duty = 0;
                    return duty;
                }
            }
            pwm_L = (TH1 << 8) | TL1;
    
            duty = pwm_H * 100 / (pwm_H + pwm_L);
            return duty;
        }
    
        return 0xFF;
    }
    

    2. 中断方式

    中断方式的PWM采集原理与阻塞方式相同,只是将判定移动至外部中断中。开启MCU端口的外部中断(上升沿和下降沿中断);如果MCU外部中断触发不支持上升和下降沿中断,则先开启上升沿中断,在中断处理中切换中断触发条件。

    处理方法:在中断处理函数中,根据当前电平状态,记录下定时器的值,并清零定时器的值,重新开始下一轮计时。

    0%和100%的处理:设定一个定时递增的变量,同时在外部中断中执行清零操作。若该变量超过一定值(说明外部中断有较长时间没有触发),则判定为0%或100%。

    uint16_t pwm_H = 0;
    uint16_t pwm_L = 0;
    uint16_t pwm_time_out = 0;
    void EXT1_ISR(void) interrupt EXTI1_VECTOR
    {
        if (PWM_IN())
        {
            pwm_L = (TH1 << 8) | TL1;    //记录低电平时间
            TH1 = 0;
            TL1 = 0;
        }
        else
        {
            pwm_H = (TH1 << 8) | TL1;    //记录高电平时间
            TH1 = 0;
            TL1 = 0;
        }
    
        //该变量定时递增(如1ms递增1),在外部中断中清零
        //在主程序中判断,超过一定值时认为PWM占空比为0%或100%
        pwm_time_out = 0;
    
        return;
    }
    

    注:使用中断方式,则占空比计算不建议放在中断中处理;同时,为了保证占空比的准确性,可以连续2-3次计算结果一致时,再确定当前占空比的结果。

    3. MCU捕获方式

    采用捕获方式的前提是MCU支持捕获功能。当前部分厂家推出的51内核单片机,会包含一个定时器2,其拥有捕获功能;或者采用32位单片机,一般都带有捕获功能。捕获的原理很简单,当上升沿或下降沿来临时,MCU硬件将定时器/计数器的值保存在一个影子寄存器中,并产生捕获中断。
    通过固定每次上升/下降沿的计数器值,相减即可分别得出高电平值和低电平值,从而计算出占空比。
    pwm占空比捕获原理
    下面以某颗51内核的MCU为例,提供示例代码:

    unsigned int pwm_fall = 0, pwm_rise = 0;
    
    volatile unsigned int pwm_H;
    volatile unsigned int pwm_L;
    
    volatile unsigned char pwm_time_out;
    //------------------------------------------------------------
    void T2_interrupt(void) interrupt 5          //定时器2中断;
    {
    
        if (CCCON & 0x02) //CC1中断标志位
        {
            CCCON  &= 0xFD; //清除中断标志
    
            if (PWM_IN())   //上升沿触发
            {
                pwm_rise = CC1;     //获取捕获寄存器中的值
                pwm_L = pwm_rise - pwm_fall;
            }
            else
            {
                pwm_fall = CC1;     //获取捕获寄存器中的值
                pwm_H = pwm_fall - pwm_rise;
            }
    
            //该变量定时递增(如1ms递增1),在外部中断中清零
            //在主程序中判断,超过一定值时认为PWM占空比为0%或100%
            pwm_time_out = 0;
        }
    }
    

    注: pwm_rise/pwm_fall/pwm_L/pwm_H都必须使用无符号数,否则相减时可能得到错误的值。

    总结

    方式一任何单片机都可以实现,但是阻塞方式会使系统的实时性变差;
    方式二在使用时,需要保证外部中断的最高优先级,不可以被其他中断打断,以保证其准确性;
    方式三的稳定性和准确性都较高,但是需要MCU硬件支持。

    展开全文
  • 现针对应广单片机,以乘法为例,现做了一个程序,用于测量乘法所消耗的时间.不多说,上代码. /****************系统时钟*********************/ //byte count; word usTmrCnt; //bit FLAG_NMS; ...

            在单片机应用过程中,特别是对实时性要求高的应用,需要知道函数,查表,算法等运算所消耗的时间.现针对应广单片机,以乘法为例,现做了一个程序,用于测量乘法所消耗的时间.不多说,上代码.


    /****************系统时钟*********************/
    //byte    count;
    word    usTmrCnt;
    //bit     FLAG_NMS;
    /**************T16*************************/

    WORD    usDat;

    BYTE    mul_y1, mul_x1;
    WORD    mul_t2;
    /*8bit 乘法*/
    void    Byte_Mul_Byte (void)
    {    //    mul_t2[W]    =    mul_x1[B] * mul_y1[B]
        mul_t2$1    =    0;
        BYTE    cnt;
        cnt    =    8;
        do
        {
            mul_x1    >>=    1;
            if (CF)
            {
                mul_t2    +=    (mul_y1 << 8);
            }
            mul_t2    >>>=    1;
        } while (--cnt);
    }

    void    TIME16_Init(void)
    {
        /* 使用IHRC,1分频,BIT15本例子中无意义*/
        $    T16M    IHRC,/1,BIT15;   
    }

    /*启动定时器*/
    void ResetTmr16(void)
    {
        usTmrCnt=0;
        /*设置初始值*/
        STT16 usTmrCnt;
    }

    /*取得定时器值*/
    void GetTmr16Dat(void)
    {
        /*取得计数值*/
        LDT16 usTmrCnt;
    }


    /*相应于main函数*/
    void    FPPA0 (void)
    {
        /*系统时钟为 IHRC默认为16M,因此,IHRC/2=8M*/
        .ADJUST_IC    SYSCLK=IHRC/2
        /*初始*/
        TIME16_Init();
        usTmrCnt=0;
        while (1)
        {
            /*启动定时器*/
            ResetTmr16();
            /*标准测试*/
            .delay 1000;
            GetTmr16Dat();
            /*设置断点,查看周期数,标准应该是2000 IHRC时钟周期*/
            .delay 1;

            /*启动定时器*/
            ResetTmr16();
            mul_y1=10;
            mul_x1=78;
            Byte_Mul_Byte();
            /*查看结果*/
            usDat=mul_t2;
            GetTmr16Dat();
            /*设置断点,查看周期数,大概190 IHRC时钟周期*/
            .delay 1;

        }
    }
     

    展开全文
  • ===============================================解答:这个0.001Hz的测量精度,在单片机领域是不能达到的。精度为0.001Hz,一般是指最大的绝对误差。当测量50KHz信号的时候,显示数值不应超过:49 999.999Hz ~ 50...

    问题:
    用C51系列单片机测TTL(f<50KHz)的信号,精度达到0.001Hz,用12MHz的单片机还是更高?
    怎么计算是否达到这个精度?
    ===============================================
    解答:
    这个0.001Hz的测量精度,在单片机领域是不能达到的。

    精度为0.001Hz,一般是指最大的绝对误差。
    当测量50KHz信号的时候,显示数值不应超过:49 999.999Hz ~ 50 000.001Hz。
    这才是精度达到了0.001Hz。
    12MHz的单片机,根本别想达到这个精度!!!

    测量频率,有“测量频率”和“测量周期”两种方法。

    如果采用“测量频率”的方法,也就是“定时计数”法。
    为了统计出来 49 999 999 ~ 50 000 001 的区别,就要用1000s的时间(16分钟多)。
    时间短了,就达不到0.001Hz的精度要求。

    “定时计数”法用时太长,不实用,那就再看看“测量周期”法。

    用单片机的确是可以测出50KHz信号的周期是20us,取倒数,确实能换算出50 000Hz。

    但是输入的频率,以0.001Hz 分档,再输入几个看看:
    频率是49 999.999Hz,它的周期是20.0000004us;
    频率是49 999.998Hz,它的周期是20.0000008us;
    ……
    ……
    呵呵,不用多说了,大家一眼就可以看出,这0.0000004us的差别,单片机是分辨不出来的。
    也就是说,单片机分辨不出来49 999.999Hz和49 999.998Hz的区别。

    所以,0.001Hz的精度,是不可能达到的。

    谁说能达到?请看:
    ===============================================
    原题网址:http://zhidao.baidu.com/question/164325076.html
    最佳答案:精确到50KHz到0.001Hz用12M晶振足够了。

    展开全文
  • 利用单片机测频率有两种方法:测周期法和脉冲计数法
  • 为了能够评估STC8G1K08单片机算法的效率,需要有一种能够直接测量单片机程序执行时间的物理方法。使用单片机的一个管脚的变化来表明软件流程的起始和结束,从外部通过示波器等手段测量脉冲的宽度,便可以有效衡量...

    为了能够评估STC8G1K08单片机算法的效率,需要有一种能够直接测量单片机程序执行时间的物理方法。使用单片机的一个管脚的变化来表明软件流程的起始和结束,从外部通过示波器等手段测量脉冲的宽度,便可以有效衡量单片机软件执行流程的时间。

    下面通过一些基本实验来衡量这种方法的有效性。

    实验平台

    实验电路板在博文“8G1K实验电路板”给出了描述。使用单片机P3.2管脚来只是程序的起始和结束。

    该管脚在初始化的时候输出模式设置为:PUSH-PULL。

    #define FLAG_PIN            3, 2           // For test time pulse
    
    PM_PP(FLAG_PIN);
    

    单片机的运行时钟频率为:
    fsys=35×106Hzf_{sys} = 35 \times 10^6 Hz

    典型时间测量

    1. 相邻ON,OFF指令

    ON,OFF是定义的宏指令,实际就是对sbit赋值指令。

    #define _ON(pt,pin)     P##pt##pin=1
    #define _OFF(pt,pin)    P##pt##pin=0
    #define _TOGGLE(pt,pin) P##pt##pin=~P##pt##pin
    
    #define ON(x)       _ON(x)
    #define OFF(x)      _OFF(x)
    #define TOGGLE(x)   _TOGGLE(x)
    

    这应该是改变MCU输出管脚电平最为简介的指令了。下面通过测量连续ON,OFF 指令,测量对应管脚信号的变化情况。

            ON(FLAG_PIN);
            OFF(FLAG_PIN);
    

    测量FLAG_PIN输出信号入下图所示,在波形的上升和下降起始位置之间的时间大约为:t1=30nst_1 = 30ns

    由于MCU系统频率为fsys=35nsf_{sys} = 35ns,所以t1t_1大约等于系统频率的倒数:t11fsys=135×106t_1 \approx {1 \over {f_{sys} }} = {1 \over {35 \times 10^6 }}
    ▲ P3.2输出波形

    ▲ P3.2输出波形

    使用ON,OFF命令测量实际执行时间的时候,需要将测量时间减去MCU工作的指令周期,也就是t1t_1

    2. 使用TOGGLE指令

    根据前面定义TOGGLE宏命令,该指令是8051中指令对sbit取反操作,使用连续两次取反,可以使得管脚输出举行脉冲。

    最终所测量得到的脉冲与前面连续ON,OFF脉冲相同。

    3. 测量_NOP_时间间隔

    在ON,OFF指令之间增加nop命令,则会反映出单个NOP命令的执行时间。

            ON(FLAG_PIN);
            _nop_();
            OFF(FLAG_PIN);
    

    测量结果如下图所示。相邻上升沿和下降沿之间的时间大约为60ns,相当于两个系统指令周期。

    ▲ 增加NOP指令之后的P3.2管脚信号

    ▲ 增加NOP指令之后的P3.2管脚信号

    变量操作运行时间

    1. unsigned char

    (1)赋值语句: unsigned char c1 = 1;
    执行时间为Tmcu=30ns。

    (2)加法指令: unsigned char c1,c2; c1=c1+c2;
    执行时间:3个Tmcu=90ns。

    (3)减法指令: c1=c1-c2 执行时间:4个Tmcu=120ns;

    (4)乘法指令: c1=c1*c2
    执行时间5个Tmcu=150ns。

    (5)除法指令: c1=c1/c2
    执行时间:300ns。

    2. unsigned int

    (1)赋值语句: unsigned int n1 = 1;

    执行时间:2Tmcu=60ns;

    (2)加法: n1=n1+n2;
    执行时间: 6Tmcu = 180ns。

    (3)减法: n1=n1-n2;
    执行时间: 7Tmcu=210ns。

    (4)乘法: n1=n1*n2;

    执行时间:25Tmcu=810ns

    (5)除法指令: n1=n1/n2
    执行时间:5us;

    3. unsigned long

    (1)赋值语句: unsigned int n1 = 1;

    执行时间:150ns;

    (2)加法: n1=n1+n2;
    执行时间: 12TMuc = 360ns;

    (3)减法: n1=n1-n2;
    执行时间: 410ns

    (4)乘法: n1=n1*n2;

    执行时间:2.65us

    (5)除法指令: n1=n1/n2
    执行时间:18.3us;

    对于32bit(long)ckzo ,乘法和除法都比较消耗时间,利用8G内部的MDU16(32位乘法/除法)单元,可以加快相应的计算结果。下面给出了数据手册中相关的运行速度说明。

    ▲ MDU16不同操作所需要的时钟数量

    ▲ MDU16不同操作所需要的时钟数量

    4. float

    (1)赋值语句: f1 = 34.340;

    执行时间:180ns;

    (2)加法: f1=f1+f2
    执行时间: 7.04us。

    (3)减法: f1=f1-f2;
    执行时间: 6.1us。

    (4)乘法: f1=f1*f2;

    执行时间:5.56us;

    从现实的波形上来看,在执行过程中出现了不同的执行时间。使用EA = 0,来关闭全局终点,依然会出现这种情况。这说明不是中断引起的执行时间的差异。
    ▲ 出现不同的执行时间

    ▲ 出现不同的执行时间

    (5)除法指令: f1=f1/f2;
    执行时间:1.84us;

    5. double

    (1)赋值语句: f1 = 34.340;

    执行时间: 180ns;

    (2)加法: f1=f1+f2
    执行时间: 6.18us。

    (3)减法: f1=f1-f2;
    执行时间: 1.94us。

    (4)乘法: f1=f1*f2;

    执行时间:2.14us;

    注意:这个执行时间比起float还要短?为什么呢?

    (5)除法指令: f1=f1/f2;
    执行时间:1.84us;

    展开全文
  • 单片机 数字电压表(ADC0809) 一、简述 采用模数转换的芯片ADC0809实现设计数字电压表。例子中设计的数字电压表可以测量0~5V范围内的输入电压值,并且通过4位LED数码管显示采集的电压值,例子测量三个模拟值:4....
  • 但是学到了一种很精确测量脉冲宽度的方法。 具体思想是: 利用定时器的内部资源(当GATE = 1时,计数器的停止和开始受TR和INT的电平共同控制),我们这里用定时器0 ,将外部脉冲接在INT0上,配置定时器0和外部...
  • 来源:单片机及嵌入式系统应用 作者:金海龙摘要:用MSP430P315单片机的A/D转换器,实现阻性温度传感器的电阻检测;...关键词:单片机 线性插值 补偿 温度检测引言长期以来,人们在测量温度时,大部分使用常...
  • 单片机的数据采集系统中,测量通道串入随机干扰是难免的,从而使A/D转换送入单片机的数据存在误差,这种因随机干扰产生的误差称为随机误差。随机误差虽然无法预测,但多次测量结果是符合统计规律的。为克服随机...
  • 整理:黄工素材来源:最后一个Bug程序的运行时间,对一个系统比较重要。有的地方要求精确延时Nus,有的地方要求程序运行时间不能超过Nus。所以,今天给大家分享一些常见测量程序(任务)运行...
  • 基于stm32f103单片机对信号频率、占空比的测量。 最近开始仪器仪表方面的学习了,计划后期做一个示波器。所以这周就在stm32f103上面做了一个测量频率、占空比的小设计。总体上精度还是比较高的,测量频率量程在35Hz...
  • 52单片机定时器2

    2015-01-22 19:26:39
    使用捕获功能可以非常准确的测量脉冲宽度或周期,他的工作原理是:单片机内部有两组寄存器,其中一组的内部数值是按照固定的机器周期递增或递减,通常这组寄存器就是定时器的计数器寄存器(TLX,THX),当与捕获功能...
  • 单片机原理及应用》复习提纲 单片机应用系统的典型结构图   单片机应用系统核心硬件技术包括: 1.时序 2.中断 3.地址译码   单片机应用系统核心软件技术包括: 1.寻址...
  • 单片机的基准电压一般为3.3V,如果外部信号超过了AD测量范围,可以采用电阻分压的方法,但是要注意阻抗匹配问题。比如,SMT32的模数输入阻抗约为10K,如果外接的分压电阻无法远小于该阻值,则会因为信号源输出阻抗较...
  • 点击上方「嵌入式大杂烩」,选择「置顶公众号」第一时间查看嵌入式笔记!前言 平时我们可能很少去关注程序运行的时间,但是在一些情况下可能需要对程序进行一个整体的复盘、优化。那么,程序运行的时...
  • 单片机c语言应用100例

    2020-07-30 23:32:14
    1.1单片机的结构与应用 1.1.1单片机的定义、分类与内部组成 1.1.2单片机应用系统的结构及其工作过程 1.1.3单片机的应用 1.2单片机基础知识 1.2.1数制与数制间的转换 1.2.2单片机中数的表示方法及常用数制的对应关系 ...
  • 单片机基础-第一个单片机系统 简单的单片机系统 构成单片机系统——单片机+外围器件 如果把单片机和外围器件组合起来,实现一定的功能,那我们就称单片机和外围器件组成了单片机系统。 如何控制一个发光...
  • 单片机常用滤波算法

    2018-03-21 14:54:14
    单片机常用滤波算法 说明:假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();1、限幅滤波(又称程序判断滤波)A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)...
  • 继上篇的《单片机(AT89C51)定时/计数器详解及其实验案例》由于各种原因里面没有实验案例现在在此补上。 单片机(AT89C51)定时/计数器详解见上篇:...
1 2 3 4 5 ... 20
收藏数 832
精华内容 332
关键字:

单片机测量周期法