搜索
bottom↓
12
返回列表 发新帖
楼主: machao

关于定时器精确定时中断的讨论

[复制链接]

出0入0汤圆

发表于 2009-11-10 10:10:44 | 显示全部楼层
再来看一遍~~~

出0入0汤圆

发表于 2009-12-11 09:34:12 | 显示全部楼层
再看一遍~~~N+1遍

出0入0汤圆

 楼主| 发表于 2009-12-11 20:08:12 | 显示全部楼层
回100楼:

客套话就算了,你不会按我的“无私教诲”去认真学习的,只不过是想拿到一个参考代码。

下面的参考代码可以在M16的PORTD.5脚上上获得一个非常精准的5s周期的方波,不需要使用中断,只是使用T/C1,初始化后就不用程序管了。

注意:系统时钟为2.048M。

// Target : M16
// Crystal: 2.048Mhz

//TIMER1 initialize - prescale:1024
// WGM: 4) CTC, TOP=OCRnA
// desired value: 2.5Sec
// actual value:  2.500Sec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
OCR1AH = 0x13;
OCR1AL = 0x87;
TCCR1A = 0x40;
TCCR1B = 0x0D; //start Timer
}

出0入0汤圆

发表于 2009-12-11 21:56:24 | 显示全部楼层
好贴,今天才看到!花了一个多小时,mark下,以后再看!谢谢马老师

出0入0汤圆

发表于 2009-12-11 22:38:29 | 显示全部楼层
一定好好看看

出0入0汤圆

发表于 2009-12-13 20:36:54 | 显示全部楼层
学习!

出0入0汤圆

发表于 2009-12-16 19:53:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-29 14:20:33 | 显示全部楼层
以前用定时器也就这样用了。没有注意,今天看了一下!还有很多需要注意的呀!看了马老师的定时器讲解,真是如醍醐灌顶呀!

出0入0汤圆

发表于 2010-1-4 19:34:27 | 显示全部楼层
Mark!

出0入8汤圆

发表于 2010-1-6 12:12:33 | 显示全部楼层
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value:  1.000mSec (0.0%)
void Delay_ms(void)
{
   TCCR0 = 0x00; //stop
   TCNT0 = 0x83; //set count
   OCR0  = 0x7D;  //set compare
   TCCR0 = 0x03; //start timer
   while ((TIFR & 0x01) == 0);    // 为什么TIFR的D0位不会溢出????
  TIFR &= ~ (1<<TOV0);
  TCCR0 = 0x00; //stop   
}

出0入0汤圆

发表于 2010-1-7 09:38:24 | 显示全部楼层
Atmega8,使用3.6864MHz晶振,TC2使用CTC方式,溢出一次的时间为10ms,同时OC2(PB3)引脚输出50Hz方波,使用CTC中断。
OCR2=0x23,即35。

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 3.600 kHz
// Mode: CTC top=OCR2
// OC2 output: Clear on compare match
ASSR=0x00;
TCCR2=0x2F;
TCNT2=0x00;
OCR2=0x23;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

//PB3允许输出方波,50Hz,50%
PORTB=0x00;
DDRB=0x08;

出0入0汤圆

发表于 2010-2-22 11:45:04 | 显示全部楼层
受教

出0入0汤圆

发表于 2010-2-22 14:40:10 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-3-3 15:02:40 | 显示全部楼层
使用atmega16的定时器0定时0.1ms,(7.7328M晶振,8分频,TCNT0 = 0xa4),用于产生频率5k的方波。   

本身理论上就不是100us,而是99.826us。   


上面的晶振是7.3728M吧

出0入0汤圆

发表于 2010-3-3 15:46:41 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-3-7 19:08:46 | 显示全部楼层
好贴

出0入0汤圆

发表于 2010-3-23 14:40:45 | 显示全部楼层
看看

出0入0汤圆

发表于 2010-3-26 09:30:45 | 显示全部楼层
hao

出0入0汤圆

发表于 2010-4-29 13:42:47 | 显示全部楼层
记号

出0入0汤圆

发表于 2010-4-29 14:13:59 | 显示全部楼层
没想到这样的一个帖子,现在对于我学习STM32还是有帮助的。

出0入0汤圆

 楼主| 发表于 2010-4-29 20:47:56 | 显示全部楼层
8位是基础,8位的如果都玩不好,玩32位就属于“瞎掰”

出0入0汤圆

发表于 2010-5-25 12:49:21 | 显示全部楼层
精彩

出0入0汤圆

发表于 2010-6-13 21:34:19 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-18 14:51:49 | 显示全部楼层
学习要踏实,一点没错

出0入0汤圆

发表于 2010-8-25 12:13:05 | 显示全部楼层
受益匪浅……

出0入0汤圆

发表于 2010-10-8 13:30:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-8 13:43:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-28 15:33:46 | 显示全部楼层
mark 跟马老师受教啦 谢谢马老师!

出0入0汤圆

发表于 2010-11-4 14:35:32 | 显示全部楼层
好帖子!谢谢马老师!

出0入0汤圆

发表于 2010-12-4 00:21:44 | 显示全部楼层
学习要踏实,一点没错

出0入0汤圆

发表于 2011-2-5 14:00:52 | 显示全部楼层
看了这贴,心里又踏实点了。。

出0入0汤圆

发表于 2011-2-15 14:06:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-20 21:47:32 | 显示全部楼层
以后好好搞搞定时器

出0入0汤圆

发表于 2011-3-26 20:41:34 | 显示全部楼层
马超老师你好,我想问下在快速PWM模式下可以改变基频的大小吗?在用T2产生快速PWM时,基频是fOCnPWM=fclk/N*256,这样的话就是说基频只和分频系数有关,也就是说不能在中断里面改TCN2的值而得到其他多种基频吗?我试验过不行,可是芯片手册上说随时都可以访问TCN2寄存器的啊?有点混乱

出0入0汤圆

发表于 2011-4-24 23:32:46 | 显示全部楼层
好贴,在此感谢一下。

出0入0汤圆

发表于 2011-4-25 05:19:30 | 显示全部楼层
支持

出0入0汤圆

发表于 2011-4-25 09:23:00 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-4-25 10:13:42 | 显示全部楼层
好好地

出0入0汤圆

发表于 2011-5-2 14:42:03 | 显示全部楼层
machao老师,我用一个定时器模拟两个PWM,怎么误差大了5倍呢???定时器都不准了。。。

出0入0汤圆

发表于 2011-6-1 12:03:44 | 显示全部楼层
学习,学习,讲的真好!

出0入0汤圆

发表于 2011-6-1 13:27:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-9 23:46:49 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-7-10 12:20:57 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-21 16:26:09 | 显示全部楼层
获益匪浅哪~

出0入0汤圆

发表于 2011-11-3 22:03:03 | 显示全部楼层
受益匪浅, 受益匪浅!

出0入0汤圆

发表于 2011-11-16 14:26:09 | 显示全部楼层
定时还有很长的路啊

出0入0汤圆

发表于 2011-12-5 17:13:03 | 显示全部楼层
新手,学习了,收益匪浅

出0入0汤圆

发表于 2011-12-16 17:51:32 | 显示全部楼层
回复【楼主位】machao
-----------------------------------------------------------------------

我刚来这个论坛,今天刚申请了个账号。看了您的几个帖子,您的回答总是那么的精辟。您的回答中好像都会涉及您的讲义,不知道哪里有提供下载或者如何获得,想找来参考学习。

出0入0汤圆

发表于 2012-1-30 15:27:07 | 显示全部楼层
受益非浅

出0入0汤圆

发表于 2012-2-3 10:13:22 | 显示全部楼层
我的老师哪怕有马老师的1%,我也不至于沦落到今天的地步。一个好老师能稍稍指点一下,顶上我看书查资料一星期了。

出0入0汤圆

发表于 2012-2-23 10:41:51 | 显示全部楼层
学了不少知识,谢谢马老师!

出0入0汤圆

发表于 2012-2-24 17:19:06 | 显示全部楼层
马老师您好!看完您的讲述后我自己做了一下实验,单片机是ATmega16L,采用内部8M晶振,用定时器0的普通模式的溢出中断和CTC模式的比较匹配中断分别做了实验。我的目的是得到周期为2ms的方波,具体的就是通过PA0的取反,然后测单片机PA0口的波形
普通模式的溢出中断程序如下:
// Target : M16
// Crystal: 8.0000Mhz

#include <iom16v.h>
#include <macros.h>

void port_init(void)
{
PORTA = 0xFF;
DDRA  = 0xFF;
}

//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 1KHz
// actual value:  1.000KHz (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
MCUCR = 0x00;
GICR  = 0x00;
TIMSK = 0x01; //定时器0溢出中断
TCCR0 = 0x03; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0x83;
PORTA^=0x01;
}

void main(void)
{
OSCCAL=0xA7;//时钟校准
CLI();
port_init();
timer0_init();
SEI();
while(1);
}
用示波器测得的结果周期是1.989ms

CTC模式的比较匹配中断程序如下:
// Target : M16
// Crystal: 8.0000Mhz

#include <iom16v.h>
#include <macros.h>

void port_init(void)
{
PORTA = 0xff;
DDRA  = 0xff;
PORTB = 0xff;
DDRB  = 0xff;
}

//TIMER0 initialize - prescale:64
// WGM: CTC
void timer0_init(void)
{
TCCR0 = 0x00; //stop
MCUCR = 0x00;
GICR  = 0x00;
TIMSK = 0x02; //比较匹配中断
TCNT0 = 0x00; //set count
OCR0  = 0x7C;  //set compare这个值是根据手册上给的公式算得的
TCCR0 = 0x1B; //start timer CTC模式比较匹配时OC0取反
}

#pragma interrupt_handler timer0_crc_isr:20
void timer0_crc_isr(void)
{
//TCNT0 = 0x00; //reload counter value
PORTA^=0x01;
}

void main(void)
{
OSCCAL =  0xA7;//时钟校准
CLI();
port_init();
timer0_init();
SEI(); //re-enable interrupts
while(1);
}
用示波器测得的结果周期是1.985ms,而且这个测OC0也是这个结果
请问马老师这是什么原因造成的?谢谢!

出0入0汤圆

 楼主| 发表于 2012-2-24 22:11:33 | 显示全部楼层
回复【154楼】djingm1234
-----------------------------------------------------------------------
我粗看了ctc的方式,基本计算和设置没有问题。

你使用内部的RC时钟8M,你的OSCCAL调整是依据什么?考虑一下,如果要产生非常精确的2ms方波,如果你的系统时钟8M本身有误差,其它就免谈。也就是说,你是如何保证系统时钟8M是非常准确的?

出0入0汤圆

发表于 2012-2-25 16:41:25 | 显示全部楼层
回复【155楼】machao
-----------------------------------------------------------------------

(原文件名:定时器1.png)
图一

(原文件名:定时器.png)
图二
OSCCAL是根据上图这个软件设置的,在右上角,图一是未标定的,图二是标定后的。内部8M是根据界面左边的熔丝位设置,CKSEL3..0是0100时标称频率为8M。我感觉经过标定的片内RC振荡器应该是准确的,而且手册上说可以对8M进行标定

出0入0汤圆

 楼主| 发表于 2012-2-26 00:03:38 | 显示全部楼层
建议你使用一个外部8M晶体先做个测试,而后再考虑对内部RC的标定

出0入0汤圆

发表于 2012-2-26 08:28:09 | 显示全部楼层
回复【17楼】I_use_AVR_too  
我觉得这个问题的出现在于很多人在用到定时中断时都将:中断产生后到重新赋值这个时间内计数器仍在计数这一事实给忽略了引起的。
事实上严谨的定时程序是这样的:
一是如果该定时中断为最优先中断,则赋值时应减去:中断响应到重新辅值时计数器已计数值。
二是如果该定时中断不为最优先中断,则应在赋值前关闭中断,然后用理论的初值减去当前已计数值。
-----------------------------------------------------------------------

三:如计数器有使用预分频, 则应从理论的初值减去中断响应到重新辅值时计数器已计数之值 +1 或 +2, 然後不断读出计数器现值, 发现跳变时才立刻重新辅值。

出0入0汤圆

 楼主| 发表于 2012-2-26 18:01:32 | 显示全部楼层
楼上的概念已经OUT了, 是老51的概念。

新的MCU所配备的T/C,都有比较匹配的功能。使用AVR的CTC模式,比较匹配输出,不用中断能产生精确的方波,此时的精度仅依赖于在于系统时钟(在我的教材中有例子)。

出0入0汤圆

发表于 2012-2-27 09:14:16 | 显示全部楼层
回复【157楼】machao 马潮
-------------------------------------------------------------------
好的,谢谢马老师!

出0入0汤圆

发表于 2012-3-10 22:00:57 | 显示全部楼层
谢谢马潮老师讲解:)

出0入0汤圆

发表于 2012-3-11 11:23:06 | 显示全部楼层
受益匪浅……

出0入0汤圆

发表于 2012-3-28 09:22:33 | 显示全部楼层
初学者呀,很多还是从基础做起,不然很难理解的,马潮老师不错!

出0入0汤圆

发表于 2012-5-8 13:38:50 | 显示全部楼层
为什么我连定时1毫秒都不准呢?
我的程序如下:void timer2_init(void)
{
TCCR2 = 0x00;
TCNT2 = 0x00 ;//8M/64KHz=125KHz
OCR2  = 0x7C ;//(124+1)/125=1MS
TCCR2 = 0x0B; //64分频   CTC模式
}

#pragma interrupt_handler timer2_comp_isr:iv_TIM2_COMP
void timer2_comp_isr(void)
{
clock++;
if(clock>=1000)
{
  clock=0;
  s++;
  if(s>=59)
  {
   mintue++;
   s=0;
   if(mintue>=59)mintue=0;
  }
}  
}
但是用数码管显示出来,就好像在飞

出0入0汤圆

发表于 2012-5-8 13:52:03 | 显示全部楼层
void timer2_init(void)
{
TCCR2 = 0x00;
TCNT2 = 0x00 ;//8M/64KHz=125KHz
OCR2  = 0x7C ;//(124+1)/125=1MS
TCCR2 = 0x0B; //64分频   CTC模式
}

#pragma interrupt_handler timer2_comp_isr:iv_TIM2_COMP
void timer2_comp_isr(void)
{
clock++;
if(clock>=1000)
{
  clock=0;
  s++;
  if(s>=59)
  {
   mintue++;
   s=0;
   if(mintue>=59)mintue=0;
  }
}  
}
但是用数码管显示出来,就好像在飞
大家看一下我的程序

出0入0汤圆

发表于 2012-5-8 13:52:27 | 显示全部楼层
用的是8M的晶振

出0入0汤圆

发表于 2012-5-8 20:37:40 | 显示全部楼层
为什么我不能发帖呢?在这里

出0入0汤圆

发表于 2012-6-14 15:12:09 | 显示全部楼层
做个记号,等能彻底理解的时候就来看看!

出0入0汤圆

发表于 2012-6-25 14:46:28 | 显示全部楼层
       mark

出0入0汤圆

发表于 2013-8-3 00:21:01 | 显示全部楼层
先马一个,最近也在产生方波,频率精确度达不到要求,捉急阿,,

出0入0汤圆

发表于 2014-5-22 20:29:24 | 显示全部楼层
听大家这么说,我想要用一个M0核的单片机(新唐M051)的单片机通过定时器0和外部中断1计算来自外部中断1引脚的PWM波形有点行不通吧??PWM的周期是固定的。但是是us级的。而且占空比是不断变化的。我之前有用PWM捕捉试过,但是发现捕捉的周期不够快,中间有漏掉一些周期没有测试到。

出0入0汤圆

 楼主| 发表于 2014-5-23 02:34:38 | 显示全部楼层
NanceMichael 发表于 2014-5-22 20:29
听大家这么说,我想要用一个M0核的单片机(新唐M051)的单片机通过定时器0和外部中断1计算来自外部中断1引 ...

用M051测量PWM,最正确、最简单、最好的就是用它的 PWM捕捉功能,用定时器0和外部中断不是正确的方法(就是用AVR或STC51也不能采用)。

下面是M051的一段说明,由于你的PWM波频率太高,所以用M051是不能实现的。

The maximum captured frequency that PWM can capture is confined by the capture interrupt latency. When capture interrupt occurred, software will do at  least three steps, they are: Read PIIRx to get interrupt source and Read PWM_CRLx/PWM_CFLx(x=0 and 3) to get capture value and finally write 1 to clear PIIRx. If interrupt latency will take time T0 to finish, the capture signal mustn’t transition during this interval (T0). In this case, the maximum capture frequency will be 1/T0. For example:
HCLK = 50 MHz, PWM_CLK = 25 MHz, Interrupt latency is 900 ns
So the maximum capture frequency will is 1/900ns ≈ 1000 kHz

也就是说,M051测量PWM波的极限频率是1M, (1us) ,主要是执行中断服务的时间的限制。这种应用是考验工程师真正水平的,要考虑中断的最优化,执行时间最短,还要考虑系统作其它事情(计算、转换、显示等等)。一般的工程师就是采用PWM捕捉功能能实现精确测量100K的PWM波算不错的了。很多的童鞋从根本上还是基础知识不扎实,没有真正了解和掌握定时器的正确应用方法,就是有PWM捕捉功能也用不了,用不好。


非常好的一个题目,与我的“频率测量”的题目是同工异曲,是“频率测量”的扩展题目。建议有兴趣的讨论如何用MCU来测量PWM波。

出0入0汤圆

发表于 2014-5-23 08:21:10 | 显示全部楼层
恩,非常感谢老师的回复,我现在测试PWM捕捉是没问题的,如果是固定占空比的话能够准确测量出PWM值。但是还有一个问题,M051的核不带硬件的除法计算器,我算PWM值的时候用的公式是:(占空比时间/PWM周期)*256,但是我发现我PWM周期是800us,如果占空比一直在变化,采样回来的PWM值不是每一个周期都能够采样得到。我的PWM捕捉中断函数算出PWM高,低电平的时间,PWM值计算公式放在主循环while(1)里面,我发现测量出来的结果会在变化的过程中,每测量一个周期就会漏掉10个周期左右的PWM值。请问这是怎么回事。

出0入0汤圆

发表于 2014-5-23 08:23:21 | 显示全部楼层
machao 发表于 2014-5-23 02:34
用M051测量PWM,最正确、最简单、最好的就是用它的 PWM捕捉功能,用定时器0和外部中断不是正确的方法(就 ...

老师,刚才想在这回复的,结果发错地方弄成直接发帖了,请见谅。我回贴在上面链接上。

出0入0汤圆

 楼主| 发表于 2014-5-24 08:24:45 | 显示全部楼层
NanceMichael 发表于 2014-5-23 08:21
恩,非常感谢老师的回复,我现在测试PWM捕捉是没问题的,如果是固定占空比的话能够准确测量出PWM值。但是还 ...

我说的没错哈--在上贴中我回复说过:
“这种应用是考验工程师真正水平的,要考虑中断的最优化,执行时间最短,还要考虑系统作其它事情(计算、转换、显示等等)。一般的工程师就是采用PWM捕捉功能能实现精确测量100K的PWM波算不错的了。很多的童鞋从根本上还是基础知识不扎实,没有真正了解和掌握定时器的正确应用方法,就是有PWM捕捉功能也用不了,用不好。”
=========================================================
根据你的帖子:

1/ 你的PWM周期是固定的,800us,也就是1.25K, 你的目的是只要测量占空比。
2/ 如果你采用连续测量,也就是每个PWM周期都测量一次,那么你在800us时间内必须完成一次中断读取,计算占空比,显示结果等其它的所有工作。
   --PWM中断,读取一次2个测量值(高电平数字、周期数字),作为下一次计算用的数字。这个中断要最断的时间,必须估计的比较准确(假定50us)
   --计算占空比(除法),此次计算是使用前一次中断中读取测量值,然后显示以及其它工作。这个部分必须在700us完成!

如果达不到上面的指标,也就不可能实现连续PWM波的测量,只能是间断的测量了

==========================================================
实际工程中不可能做出一个万能的PWM波测试设备,只要满足具体应用需求就可以。你提供些具体的数据,我们分析看能不能提供一个思路,满足要求。

首先是被测PWM波是数字方式产生还是模拟方式产生,如果是数字方式的话,那么是几位的。比如8位精度,或10\12\16位精度

1/ 你测量的PWM周期是否固定为800us,每次中断中读到的周期数字是多少?变化多少?(这个与你PWM捕捉使用的频率有关)
2/ 被测PWM占空比的变化范围,是0%-100%吗?
3/ 要求得到测量的PWM占空比精度是多少位(8位,1/256 还是16位 1/65536)?或者描述为十进制的小数点保留几位(比如25%还是25.1%,假定8位,那么精度是(25.x +-0.4)%)?你的计算公式×256的用意是什么?

提示:
1/越高的精度需要计算的时间越多,而且高的精度还可能是虚假的。比如被测PWM波的精度是8位的,你的结果显示25.01%的话,这个精度就是虚假的。
2/要实现PWM波的测量,不仅仅是考虑如何准确得到PWM的周期数据,其它工作所使用的思路方法同样重要。MCU的应用技术是综合全面的。   

出0入0汤圆

发表于 2014-5-24 16:45:07 | 显示全部楼层
machao 发表于 2014-5-24 08:24
我说的没错哈--在上贴中我回复说过:
“这种应用是考验工程师真正水平的,要考虑中断的最优化,执行时 ...

老师,你好,首先谢谢你这么长的回复并提到愿意为我分析提供思路!也希望通过此贴能够延伸下这贴的主题,并通过和老师的交流能够加深跟我一样还在学习的朋友对精确定时及PWM捕捉的理解。下面是我通过串口打印出来的测试数据,PWM周期依然是800us,PWM变化过程大概是在2秒内PWM的值从0到255再从255到0连续变化。
PWM3 = 66
PWM3 = 76
PWM3 = 86
PWM3 = 96
PWM3 = 106
PWM3 = 117
PWM3 = 127
PWM3 = 138
PWM3 = 149
PWM3 = 159
PWM3 = 170
PWM3 = 180
PWM3 = 191
PWM3 = 202
PWM3 = 212
PWM3 = 223
PWM3 = 233
PWM3 = 244
PWM3 = 254
PWM3 = 253
PWM3 = 242
PWM3 = 232
PWM3 = 221
PWM3 = 211
PWM3 = 200
PWM3 = 190
PWM3 = 179
PWM3 = 169
PWM3 = 158
PWM3 = 148
PWM3 = 137
PWM3 = 127
PWM3 = 116
PWM3 = 106
从数据看,我发现漏测的PWM值很接近10个。这是否能判断是捕捉频率不够快呢?我这里说到的800us只是举例一个被测量的PWM信号,因为我要采集的PWM信号源有可能来自不同的设备,PWM产生方式有可能是由定时器模拟输出,也有可能是由单片机自带的PWM输出,精度有可能是8位的,也有可能是16位的,占空比范围是从0%-100%。我在程序里计算PWM值的公式是:PWM3        = ((float)H_Leve/(H_Leve+L_Leve))*255;
我查了M051的DATASHEET。发现M051这款IC没有硬件的除法计算器,这里计算有可能也是影响以上数据结果的原因。 上面是我的一些情况,下面再根据老师上面提到的问题作1对1的回帖:
1/我的PWM周期在测量的时候是固定的,但不一定是800us(因为PWM信号源有可能来自不同的设备,不同的设备PWM周期就不固定了),上面提到的是我以测试800us周期的PWM信号为例。
2/提供的PWM信号同一台设备占空比是固定的,但每一台设备不一定是同个周期,即不同设备周期不同。我上面的例子是以800us为例。
3/问题同上,不同设备提供的PWM信号不一样,这些信号有可能像老师第三问题提到的所有可能一样。有可能是模拟,有可能是单片机自身带的PWM。
本来打算把测试数据以及把示波器测试结果拿上来的,但是现在手头没有工作,等我两天我有时间再把结果拿出来,这里先回复了些我能回答的。

出0入0汤圆

 楼主| 发表于 2014-5-24 19:45:09 | 显示全部楼层
本帖最后由 machao 于 2014-5-24 20:51 编辑

首先是基本概念和理论知识非常的不扎实,所以你无法正确评估以及设计去实现你的系统。

单单仅靠一片MCU本身的功能,是不可能做到一个完善的PWM测量设备的。假如是你买一台商业的示波器,或者频率计,它也有一个指标的,比如能测到的最高频率试多少。例如通常一般示波器有 20M \50M\100等指标,如果你要测25M的波形,20M示波器就不行,就要使用100M的示波器。

你要设计PWM测量,要非常清楚PWM测量的真正思想方法,以及测量精度应该如何评估(这个在大部分的书中都不会涉及到的)。

学习MCU不是单纯的会硬件、会软件编程,没有真正的理论基础的话,你作的东西就不可靠,因为数据是假的。

==========================================
我们要首先看被测的PWM波,假定周期是800us
如果是8位数字产生的,那么最小占空比的变化为 800us / 256 = 3.125us。而如果是16位数字产生的,那么最小占空比的变化为 800us/65536 = 0.022us!

那么用M051测量,能得到什么精度?后面一种1个占空比的变化能测到吗?

以上提示一下,建议看看我写的教程。尽管教程是用AVR硬件平台,但思想方法是通用的,也是最新的。教程中有如何使用定时器捕捉功能测周期的例子,希望能认真参考。,

==========================================
就目前情况提几个建议:

1/ 建立变量 pwm_ok;

2/ M051的PWM捕捉方式,只允许上升沿中断(或下降沿),在上升沿中断服务中:

      第n次中断服务:
      {
             读取PWM_CRLx(n) 和 PWM_CFLx(n);
             pwm_ok = 1;
       }
            
        ..........
        ..........
       主循环中:

        while(1)
        {
                ......
                if(pwm_ok)
                {
                        pwm_ok = 0;
                        RES = (PWM_CRLx(n-1) - PWM_CFLx(n)) * 100 / (PWM_CRLx(n-1) - PWM_CRLx(n)) ; =====>注1
                        DISPLAY();                                                                                                        ====》注2
                 }
         }              //==注3

注3:  主循环必须在700us能完成!!为保证这点:
注2:  显示代码要最快完成,如果通过串口打印,绝对不能使用系统的PRINT函数(因为内部的函数是用轮询方式送出的,大大消耗MCU效率!有几个人能说明白和理解?)!!必须自己写串口的中断+缓冲发送代码(我教程中有,不过一般人也看不明白的),波特率使用最高的标准频率,中断优先级比PWM捕捉低。
注3:  使用整数的乘除法,比浮点运算快多了。M051的PWM发生器是16位的数据,所以用32位长度变量,乘上100(整数乘法)不会溢出,再做整除触发,得到以百分比的占空比值,精度正负1(比如 25  误差1 );
        如果乘上1000的话,结果精确到小数点1位(比如 250 误差1),只要显示时,小数点向左移动1位。
        32位的变量,最多可以乘到10000,结果精确到小数点2位(比如 2500 误差1),只要显示时,小数点向左移动2位。但这个精度可能是虚的,还要看你PWM_CFLx和PWM_CRLx的位数。

==============================================
真正理解我在本站的“频率计设计题目”的思想,做这样的PWM测量就不会有大的问题,会自己分析了。正确的使用MCU的定时器来精准的测量频率或周期是基础!这个就是所谓“特种兵”的训练题!         






        

出0入0汤圆

发表于 2014-5-24 19:59:49 | 显示全部楼层
再学习              

出0入0汤圆

发表于 2014-9-25 13:51:40 | 显示全部楼层
好好学习  天天

出0入0汤圆

发表于 2014-12-4 10:14:49 | 显示全部楼层
帮助很大,谢谢!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 19:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表