justaccount 发表于 2013-11-8 23:18:47

关于PWM与定时器之间的影响

学习PWM的过程中有个疑问:
如果用定时器来自己设计PWM输出,那这个时候系统本身的analogWrite()还能正确输出吗?
Arduino的analogWrite()是不是也是用到了系统的定时器?

谢谢。

春泥蛋炒饭 发表于 2013-11-9 03:39:56

ATMega328(比如UNO)有三个计时器timer 0-2, 一些延时语句比如delay(), millis() micros() 用的是timer0,
6个PWM输出脚当然也要用这些计时器,它们是这样分配的:
Pins 5 and 6: timer0
Pins 9 and 10: timer1
Pins 11 and 3: timer2

所以如果你避开引脚5和6的PWM就行

justaccount 发表于 2013-11-9 07:07:08

春泥蛋炒饭 发表于 2013-11-9 03:39
ATMega328(比如UNO)有三个计时器timer 0-2, 一些延时语句比如delay(), millis() micros() 用的是timer0,
...

谢谢,你这个说的很清楚。也就是说timer0承担的功能更多,要用也用其他定时器吧。
另外一个新的问题,既然其他函数调用会用到timer0,是不是调这些函数的时候,对应的管脚也是没有办法做pwm输出的?

justaccount 发表于 2013-11-9 07:33:16

春泥蛋炒饭 发表于 2013-11-9 03:39 static/image/common/back.gif
ATMega328(比如UNO)有三个计时器timer 0-2, 一些延时语句比如delay(), millis() micros() 用的是timer0,
...

我用示波器测量了一下,使用pin 5的时候,相同情况下PWM的周期会变小。pin5周期大概是1ms,而pin9的输出大概是2.04ms。使用delay()不会影响pin5的PWM输出,周期什么的都不会改变。
所以,这个问题还是很有疑问啊。
/*查找到的相关信息
当PWM输出与5,6号端口的时候,会产生比预期更高的占空比。原因是PWM输出所使用的内部时钟,millis()与delay()两函数也在使用。所以要注意使用5,6号端口时,空占比要设置的稍微低一些,或者会产生5,6号端口无法输出完全关闭的信号。*/
我看delay的源代码,明明是会设置timer0的,为什么对PWM的输出会没有影响呢?
我的analogWrite是写在setup里面的,只会运行一次,delay是写在loop里面。

春泥蛋炒饭 发表于 2013-11-9 07:53:50

本帖最后由 春泥蛋炒饭 于 2013-11-9 07:56 编辑

justaccount 发表于 2013-11-9 07:33 static/image/common/back.gif
我用示波器测量了一下,使用pin 5的时候,相同情况下PWM的周期会变小。pin5周期大概是1ms,而pin9的输出大 ...

赞一下动手派。PMW是通过定时器中断来实现的,所以用到这几个延时函数的时候,PWM还是可以输出的,但PWM的精度会受一些影响。你可以查看analogwrite函数的源码,里面用了直接的计时器寄存器操作

justaccount 发表于 2013-11-9 07:58:47

春泥蛋炒饭 发表于 2013-11-9 07:53 static/image/common/back.gif
赞一下动手派。PMW是通过定时器中断来实现的,所以用到这几个延时函数的时候,PWM还是可以输出的,但PWM的 ...

那是不是这个意思,其实analogWrite,delay,millis对于底层代码来说,是没有改变定时器的数据的,这些函数只是会去读取定时器相应的数据溢出,然后计数,然后累加对比?
否则不能解释,为什么delay(2000)这样的语句对于PWM的输出没有明显的影响啊

绿林网页 发表于 2013-11-9 08:35:16

春泥蛋炒饭 发表于 2013-11-9 03:39 static/image/common/back.gif
ATMega328(比如UNO)有三个计时器timer 0-2, 一些延时语句比如delay(), millis() micros() 用的是timer0,
...

问一下,舵机驱动库和pwm冲突,不能同时使用,也是这个原因吧

春泥蛋炒饭 发表于 2013-11-11 07:29:52

绿林网页 发表于 2013-11-9 08:35 static/image/common/back.gif
问一下,舵机驱动库和pwm冲突,不能同时使用,也是这个原因吧

正是。记得官方舵机库用的timer2,和pin3,11的pwm冲突

绿林网页 发表于 2013-11-11 08:07:29

春泥蛋炒饭 发表于 2013-11-11 07:29 static/image/common/back.gif
正是。记得官方舵机库用的timer2,和pin3,11的pwm冲突

pwm用的timer0吧,,是否可以修改舵机库的timer2,避免冲突呢?

春泥蛋炒饭 发表于 2013-11-12 06:06:42

绿林网页 发表于 2013-11-11 08:07 static/image/common/back.gif
pwm用的timer0吧,,是否可以修改舵机库的timer2,避免冲突呢?

我在上面沙发楼已经列出了,不同引脚的pwm用了不同的timer。无论你用哪一个timer,都会和其中两个pwm冲突。

绿林网页 发表于 2013-11-12 12:53:41

春泥蛋炒饭 发表于 2013-11-12 06:06 static/image/common/back.gif
我在上面沙发楼已经列出了,不同引脚的pwm用了不同的timer。无论你用哪一个timer,都会和其中两个pwm冲突 ...

那我用舵机库,并用 5,6,9,10来输出pwm 理论应该是可以的吧,
因为舵机库用的 timer2,但实际上,只要用舵机库,用哪个脚输出pwm好像都不正常

polo32081 发表于 2013-12-17 12:54:07

春泥蛋炒饭 发表于 2013-11-9 03:39 static/image/common/back.gif
ATMega328(比如UNO)有三个计时器timer 0-2, 一些延时语句比如delay(), millis() micros() 用的是timer0,
...

这个要顶!

chensg 发表于 2015-7-3 16:05:01

绿林网页 发表于 2013-11-12 12:53 static/image/common/back.gif
那我用舵机库,并用 5,6,9,10来输出pwm 理论应该是可以的吧,
因为舵机库用的 timer2,但实际上,只要用 ...

被这个冲突害惨了!使用了舵机库,PWM输出无法正常使用,找了很久,在这里找到了原因,谢谢各位的讨论!
页: [1]
查看完整版本: 关于PWM与定时器之间的影响